jquery-rails 3.1.5 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of jquery-rails might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 1cc4ee935197027be03834032460f10b605fa29e5f370e956323827ff6459bb0
4
- data.tar.gz: 01e0552ffb9ac7484592c6a600297361b3238295c162a0374669112893ea9c66
2
+ SHA1:
3
+ metadata.gz: 980af19d5077a9cbd177a653fd33964f5c68df2f
4
+ data.tar.gz: 2becaf966d6b6a7774a77d93254cd719b367c12e
5
5
  SHA512:
6
- metadata.gz: e294510d1e0b4e3ced3ec09e16a8fc6882469e663ed4a5437f69664e4902ef40397fc5b56200c6e8f32747b83540f3e517837539dc8eb090cd779aa94d7c56b3
7
- data.tar.gz: 335edf0e53ccfd6545b0e83a42ecbb49060505816fca7aff2b49477f9cc87923094aea8487580c24cd3c4502cdb3f582d62807d10f48e3325de3dc6d96bfb458
6
+ metadata.gz: 2a43212bb1c63b6776ff6d179112bfd2220a2db779c1f276eac06ad0ff975b879febaa1e56e3088b6bdec9e1f11516e711fc23bf49f23d45f7ee40c500acbdc3
7
+ data.tar.gz: 86d4029e21e50608ffd4b1c77da3168d07a7f14ae9b28a99d4edf3b707d53b278a9bf9b9ab3821d78a161689086ee15e127641b2a8ab9f5ee9923b3e30a596c1
@@ -1,10 +1,6 @@
1
- ## 3.1.5 (18 Apr 2018)
1
+ ## 4.0.0
2
2
 
3
- - Updated jQuery 1.12.4
4
-
5
- ## 3.1.3 (16 June 2015)
6
-
7
- - Fix CSP bypass vulnerability. CVE-2015-1840
3
+ - Minimum dependency set to Rails 4.2
8
4
 
9
5
  ## 3.1.2 (1 September 2014)
10
6
 
data/README.md CHANGED
@@ -4,19 +4,19 @@ jQuery! For Rails! So great.
4
4
 
5
5
  This gem provides:
6
6
 
7
- * jQuery 1.11.1
7
+ * jQuery 1.11.1 and jQuery 2.1.1
8
8
  * the jQuery UJS adapter
9
9
  * assert_select_jquery to test jQuery responses in Ruby tests
10
10
 
11
11
  ## Versions
12
12
 
13
13
  Starting with v2.1, the jquery-rails gem follows these version guidelines
14
- to provide more control over your app's jquery version from your Gemfile:
14
+ to provide more control over your app's jQuery version from your Gemfile:
15
15
 
16
16
  ```
17
- patch version bump = updates to jquery-ujs, jquery-rails, and patch-level updates to jquery
18
- minor version bump = minor-level updates to jquery
19
- major version bump = major-level updates to jquery and updates to rails which may be backwards-incompatible
17
+ patch version bump = updates to jquery-ujs, jquery-rails, and patch-level updates to jQuery
18
+ minor version bump = minor-level updates to jQuery
19
+ major version bump = major-level updates to jQuery and updates to Rails which may be backwards-incompatible
20
20
  ```
21
21
 
22
22
  See [VERSIONS.md](VERSIONS.md) to see which versions of jquery-rails bundle which
@@ -24,28 +24,17 @@ versions of jQuery.
24
24
 
25
25
  ## Installation
26
26
 
27
- Apps generated with Rails 3.1 or later include jquery-rails in the Gemfile by default. So just make a new app:
28
-
29
- ```sh
30
- rails new myapp
31
- ```
32
-
33
- If upgrading from an older version of rails, or for rails 3.0 apps,
34
- add the jquery-rails gem to your Gemfile.
27
+ The jquery and jquery-ujs files will be added to the asset pipeline and available for you to use. If they're not already in `app/assets/javascripts/application.js` by default, add these lines:
35
28
 
36
- ```ruby
37
- gem "jquery-rails"
29
+ ```js
30
+ //= require jquery
31
+ //= require jquery_ujs
38
32
  ```
39
33
 
40
- And run `bundle install`. The rest of the installation depends on
41
- whether the asset pipeline is being used.
42
-
43
- ### Rails 3.1 or greater (with asset pipeline *enabled*)
44
-
45
- The jquery and jquery-ujs files will be added to the asset pipeline and available for you to use. If they're not already in `app/assets/javascripts/application.js` by default, add these lines:
34
+ If you want to use jQuery 2, you can require `jquery2` instead:
46
35
 
47
36
  ```js
48
- //= require jquery
37
+ //= require jquery2
49
38
  //= require jquery_ujs
50
39
  ```
51
40
 
@@ -54,30 +43,13 @@ For jQuery UI, we recommend the [jquery-ui-rails](https://github.com/joliss/jque
54
43
  *As of v3.0, jquery-rails no longer includes jQuery UI. Use the
55
44
  jquery-ui-rails gem above.*
56
45
 
57
- ### Rails 3.0 (or greater with asset pipeline *disabled*)
58
-
59
- This gem adds a single generator: `jquery:install`. Running the generator will remove any Prototype JS files you may happen to have, and copy jQuery and the jQuery-ujs driver for Rails to the `public/javascripts` directory.
60
-
61
- This gem will also hook into the Rails configuration process, removing Prototype and adding jQuery to the javascript files included by the `javascript_include_tag(:defaults)` call. While this gem contains the minified and un-minified versions of jQuery, only the minified versions will be included in the `:defaults` when Rails is run in `production` or `test` mode (un-minified versions will be included when Rails is run in `development` mode).
62
-
63
- To invoke the generator, run:
64
-
65
- ```sh
66
- rails generate jquery:install
67
- ```
68
-
69
- You're done!
70
-
71
- *As of v3.0, jquery-rails no longer includes jQuery UI, you will need to
72
- install it by yourself as needed.*
73
-
74
46
  ## Contributing
75
47
 
76
48
  Feel free to open an issue ticket if you find something that could be improved. A couple notes:
77
49
 
78
50
  * If it's an issue pertaining to the jquery-ujs javascript, please report it to the [jquery-ujs project](https://github.com/rails/jquery-ujs).
79
51
 
80
- * If the jquery scripts are outdated (i.e. maybe a new version of jquery was released yesterday), feel free to open an issue and prod us to get that thing updated. However, for security reasons, we won't be accepting pull requests with updated jquery scripts.
52
+ * If the jQuery scripts are outdated (i.e. maybe a new version of jquery was released yesterday), feel free to open an issue and prod us to get that thing updated. However, for security reasons, we won't be accepting pull requests with updated jQuery scripts.
81
53
 
82
54
  ## Acknowledgements
83
55
 
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ task :guard_version do
9
9
  def check_version(file, pattern, constant)
10
10
  body = File.read("vendor/assets/javascripts/#{file}")
11
11
  match = body.match(pattern) or abort "Version check failed: no pattern matched in #{file}"
12
- file_version = match[1]
12
+ file_version = body.match(pattern)[1]
13
13
  constant_version = Jquery::Rails.const_get(constant)
14
14
 
15
15
  unless constant_version == file_version
@@ -18,21 +18,22 @@ task :guard_version do
18
18
  end
19
19
 
20
20
  check_version('jquery.js', /jQuery JavaScript Library v([\S]+)/, 'JQUERY_VERSION')
21
+ check_version('jquery2.js', /jQuery JavaScript Library v([\S]+)/, 'JQUERY_2_VERSION')
21
22
  end
22
23
 
23
- desc "Update jQuery versions"
24
24
  task :update_jquery do
25
25
  def download_jquery(filename, version)
26
26
  suffix = "-#{version}"
27
27
 
28
28
  puts "Downloading #{filename}.js"
29
- puts `curl -o vendor/assets/javascripts/#{filename}.js https://code.jquery.com/jquery#{suffix}.js`
29
+ puts `curl -o vendor/assets/javascripts/#{filename}.js http://code.jquery.com/jquery#{suffix}.js`
30
30
  puts "Downloading #{filename}.min.js"
31
- puts `curl -o vendor/assets/javascripts/#{filename}.min.js https://code.jquery.com/jquery#{suffix}.min.js`
31
+ puts `curl -o vendor/assets/javascripts/#{filename}.min.js http://code.jquery.com/jquery#{suffix}.min.js`
32
32
  puts "Downloading #{filename}.min.map"
33
- puts `curl -o vendor/assets/javascripts/#{filename}.min.map https://code.jquery.com/jquery#{suffix}.min.map`
33
+ puts `curl -o vendor/assets/javascripts/#{filename}.min.map http://code.jquery.com/jquery#{suffix}.min.map`
34
34
  end
35
35
 
36
36
  download_jquery('jquery', Jquery::Rails::JQUERY_VERSION)
37
+ download_jquery('jquery2', Jquery::Rails::JQUERY_2_VERSION)
37
38
  puts "\e[32mDone!\e[0m"
38
39
  end
@@ -2,9 +2,7 @@
2
2
 
3
3
  | Gem | jQuery | jQuery UJS | jQuery UI |
4
4
  |--------|--------|------------| ----------|
5
- | 3.1.5 | 1.12.4 | 1.0.4 | - |
6
- | 3.1.4 | 1.11.1 | 1.0.4 | - |
7
- | 3.1.3 | 1.11.1 | 1.0.4 | - |
5
+ | 4.0.0 | 1.1.1 & 2.1.1 | ↾ | - |
8
6
  | 3.1.2 | 1.11.1 | 1.0.1 | - |
9
7
  | 3.1.1 | 1.11.1 | 1.0.0 | - |
10
8
  | 3.1.0 | 1.11.0 | - | - |
@@ -8,16 +8,18 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["André Arko"]
9
9
  s.email = ["andre@arko.net"]
10
10
  s.homepage = "http://rubygems.org/gems/jquery-rails"
11
- s.summary = "Use jQuery with Rails 3+"
12
- s.description = "This gem provides jQuery and the jQuery-ujs driver for your Rails 3+ application."
11
+ s.summary = "Use jQuery with Rails 4+"
12
+ s.description = "This gem provides jQuery and the jQuery-ujs driver for your Rails 4+ application."
13
13
  s.license = "MIT"
14
14
 
15
15
  s.required_rubygems_version = ">= 1.3.6"
16
16
  s.rubyforge_project = "jquery-rails"
17
17
 
18
- s.add_dependency "railties", ">= 3.0", "< 5.0"
18
+ s.add_dependency "railties", ">= 4.2.0.beta", "< 5.0"
19
19
  s.add_dependency "thor", ">= 0.14", "< 2.0"
20
20
 
21
+ s.add_dependency "rails-dom-testing", "~> 1.0"
22
+
21
23
  s.files = `git ls-files`.split("\n")
22
24
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
23
25
  s.require_path = 'lib'
@@ -1,5 +1,7 @@
1
- module ActionDispatch
2
- module Assertions
1
+ require 'rails/dom/testing/assertions/selector_assertions'
2
+
3
+ module Jquery
4
+ module Rails
3
5
  module SelectorAssertions
4
6
  # Selects content from a JQuery response. Patterned loosely on
5
7
  # assert_select_rjs.
@@ -50,20 +52,20 @@ module ActionDispatch
50
52
  jquery_opt = args.first.is_a?(Symbol) ? args.shift : nil
51
53
  id = args.first.is_a?(String) ? args.shift : nil
52
54
 
53
- pattern = "\\.#{jquery_method || '\\w+'}\\("
55
+ pattern = "\\s*\\.#{jquery_method || '\\w+'}\\("
54
56
  pattern = "#{pattern}['\"]#{jquery_opt}['\"],?\\s*" if jquery_opt
55
57
  pattern = "#{pattern}#{PATTERN_HTML}"
56
58
  pattern = "(?:jQuery|\\$)\\(['\"]#{id}['\"]\\)#{pattern}" if id
57
59
 
58
- fragments = []
60
+ fragments = Nokogiri::HTML::Document.new
59
61
  response.body.scan(Regexp.new(pattern)).each do |match|
60
- doc = HTML::Document.new(unescape_js(match.first))
62
+ doc = Nokogiri::HTML::Document.parse(unescape_js(match.first))
61
63
  doc.root.children.each do |child|
62
- fragments.push child if child.tag?
64
+ fragments << child if child.element?
63
65
  end
64
66
  end
65
67
 
66
- if fragments.empty?
68
+ unless fragments.children.any? { |child| child.element? }
67
69
  opts = [jquery_method, jquery_opt, id].compact
68
70
  flunk "No JQuery call matches #{opts.inspect}"
69
71
  end
@@ -93,7 +95,10 @@ module ActionDispatch
93
95
  unescaped.gsub!(PATTERN_UNICODE_ESCAPED_CHAR) {|u| [$1.hex].pack('U*')}
94
96
  unescaped
95
97
  end
96
-
97
98
  end
98
99
  end
99
100
  end
101
+
102
+ module Rails::Dom::Testing::Assertions::SelectorAssertions
103
+ include Jquery::Rails::SelectorAssertions
104
+ end
@@ -1,10 +1,8 @@
1
1
  require 'jquery/assert_select' if ::Rails.env.test?
2
- require 'jquery/rails/engine' if ::Rails.version >= '3.1'
3
- require 'jquery/rails/railtie'
2
+ require 'jquery/rails/engine'
4
3
  require 'jquery/rails/version'
5
4
 
6
5
  module Jquery
7
6
  module Rails
8
- PROTOTYPE_JS = %w{prototype effects dragdrop controls}
9
7
  end
10
8
  end
@@ -1,7 +1,8 @@
1
1
  module Jquery
2
2
  module Rails
3
- VERSION = "3.1.5"
4
- JQUERY_VERSION = "1.12.4"
5
- JQUERY_UJS_VERSION = "1.0.4"
3
+ VERSION = "4.0.0.beta1"
4
+ JQUERY_VERSION = "1.11.1"
5
+ JQUERY_2_VERSION = "2.1.1"
6
+ JQUERY_UJS_VERSION = "1.0.1"
6
7
  end
7
8
  end
@@ -1,27 +1,27 @@
1
1
  /*!
2
- * jQuery JavaScript Library v1.12.4
2
+ * jQuery JavaScript Library v1.11.1
3
3
  * http://jquery.com/
4
4
  *
5
5
  * Includes Sizzle.js
6
6
  * http://sizzlejs.com/
7
7
  *
8
- * Copyright jQuery Foundation and other contributors
8
+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9
9
  * Released under the MIT license
10
10
  * http://jquery.org/license
11
11
  *
12
- * Date: 2016-05-20T17:17Z
12
+ * Date: 2014-05-01T17:42Z
13
13
  */
14
14
 
15
15
  (function( global, factory ) {
16
16
 
17
17
  if ( typeof module === "object" && typeof module.exports === "object" ) {
18
- // For CommonJS and CommonJS-like environments where a proper `window`
19
- // is present, execute the factory and get jQuery.
20
- // For environments that do not have a `window` with a `document`
21
- // (such as Node.js), expose a factory as module.exports.
22
- // This accentuates the need for the creation of a real `window`.
18
+ // For CommonJS and CommonJS-like environments where a proper window is present,
19
+ // execute the factory and get jQuery
20
+ // For environments that do not inherently posses a window with a document
21
+ // (such as Node.js), expose a jQuery-making factory as module.exports
22
+ // This accentuates the need for the creation of a real window
23
23
  // e.g. var jQuery = require("jquery")(window);
24
- // See ticket #14549 for more info.
24
+ // See ticket #14549 for more info
25
25
  module.exports = global.document ?
26
26
  factory( global, true ) :
27
27
  function( w ) {
@@ -37,14 +37,13 @@
37
37
  // Pass this if window is not defined yet
38
38
  }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
39
 
40
- // Support: Firefox 18+
41
- // Can't be in strict mode, several libs including ASP.NET trace
40
+ // Can't do this because several apps including ASP.NET trace
42
41
  // the stack via arguments.caller.callee and Firefox dies if
43
42
  // you try to trace through "use strict" call chains. (#13335)
44
- //"use strict";
45
- var deletedIds = [];
43
+ // Support: Firefox 18+
44
+ //
46
45
 
47
- var document = window.document;
46
+ var deletedIds = [];
48
47
 
49
48
  var slice = deletedIds.slice;
50
49
 
@@ -65,11 +64,10 @@ var support = {};
65
64
 
66
65
 
67
66
  var
68
- version = "1.12.4",
67
+ version = "1.11.1",
69
68
 
70
69
  // Define a local copy of jQuery
71
70
  jQuery = function( selector, context ) {
72
-
73
71
  // The jQuery object is actually just the init constructor 'enhanced'
74
72
  // Need init if jQuery is called (just allow error to be thrown if not included)
75
73
  return new jQuery.fn.init( selector, context );
@@ -89,7 +87,6 @@ var
89
87
  };
90
88
 
91
89
  jQuery.fn = jQuery.prototype = {
92
-
93
90
  // The current version of jQuery being used
94
91
  jquery: version,
95
92
 
@@ -133,14 +130,16 @@ jQuery.fn = jQuery.prototype = {
133
130
  },
134
131
 
135
132
  // Execute a callback for every element in the matched set.
136
- each: function( callback ) {
137
- return jQuery.each( this, callback );
133
+ // (You can seed the arguments with an array of args, but this is
134
+ // only used internally.)
135
+ each: function( callback, args ) {
136
+ return jQuery.each( this, callback, args );
138
137
  },
139
138
 
140
139
  map: function( callback ) {
141
- return this.pushStack( jQuery.map( this, function( elem, i ) {
140
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
142
141
  return callback.call( elem, i, elem );
143
- } ) );
142
+ }));
144
143
  },
145
144
 
146
145
  slice: function() {
@@ -158,11 +157,11 @@ jQuery.fn = jQuery.prototype = {
158
157
  eq: function( i ) {
159
158
  var len = this.length,
160
159
  j = +i + ( i < 0 ? len : 0 );
161
- return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
160
+ return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
162
161
  },
163
162
 
164
163
  end: function() {
165
- return this.prevObject || this.constructor();
164
+ return this.prevObject || this.constructor(null);
166
165
  },
167
166
 
168
167
  // For internal use only.
@@ -174,7 +173,7 @@ jQuery.fn = jQuery.prototype = {
174
173
 
175
174
  jQuery.extend = jQuery.fn.extend = function() {
176
175
  var src, copyIsArray, copy, name, options, clone,
177
- target = arguments[ 0 ] || {},
176
+ target = arguments[0] || {},
178
177
  i = 1,
179
178
  length = arguments.length,
180
179
  deep = false;
@@ -189,7 +188,7 @@ jQuery.extend = jQuery.fn.extend = function() {
189
188
  }
190
189
 
191
190
  // Handle case when target is a string or something (possible in deep copy)
192
- if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
191
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
193
192
  target = {};
194
193
  }
195
194
 
@@ -200,10 +199,8 @@ jQuery.extend = jQuery.fn.extend = function() {
200
199
  }
201
200
 
202
201
  for ( ; i < length; i++ ) {
203
-
204
202
  // Only deal with non-null/undefined values
205
- if ( ( options = arguments[ i ] ) != null ) {
206
-
203
+ if ( (options = arguments[ i ]) != null ) {
207
204
  // Extend the base object
208
205
  for ( name in options ) {
209
206
  src = target[ name ];
@@ -215,15 +212,13 @@ jQuery.extend = jQuery.fn.extend = function() {
215
212
  }
216
213
 
217
214
  // Recurse if we're merging plain objects or arrays
218
- if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
219
- ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
220
-
215
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
221
216
  if ( copyIsArray ) {
222
217
  copyIsArray = false;
223
- clone = src && jQuery.isArray( src ) ? src : [];
218
+ clone = src && jQuery.isArray(src) ? src : [];
224
219
 
225
220
  } else {
226
- clone = src && jQuery.isPlainObject( src ) ? src : {};
221
+ clone = src && jQuery.isPlainObject(src) ? src : {};
227
222
  }
228
223
 
229
224
  // Never move original objects, clone them
@@ -241,8 +236,7 @@ jQuery.extend = jQuery.fn.extend = function() {
241
236
  return target;
242
237
  };
243
238
 
244
- jQuery.extend( {
245
-
239
+ jQuery.extend({
246
240
  // Unique for each copy of jQuery on the page
247
241
  expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
248
242
 
@@ -259,11 +253,11 @@ jQuery.extend( {
259
253
  // Since version 1.3, DOM methods and functions like alert
260
254
  // aren't supported. They return false on IE (#2968).
261
255
  isFunction: function( obj ) {
262
- return jQuery.type( obj ) === "function";
256
+ return jQuery.type(obj) === "function";
263
257
  },
264
258
 
265
259
  isArray: Array.isArray || function( obj ) {
266
- return jQuery.type( obj ) === "array";
260
+ return jQuery.type(obj) === "array";
267
261
  },
268
262
 
269
263
  isWindow: function( obj ) {
@@ -272,13 +266,10 @@ jQuery.extend( {
272
266
  },
273
267
 
274
268
  isNumeric: function( obj ) {
275
-
276
269
  // parseFloat NaNs numeric-cast false positives (null|true|false|"")
277
270
  // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
278
271
  // subtraction forces infinities to NaN
279
- // adding 1 corrects loss of precision from parseFloat (#15100)
280
- var realStringObj = obj && obj.toString();
281
- return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
272
+ return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
282
273
  },
283
274
 
284
275
  isEmptyObject: function( obj ) {
@@ -295,27 +286,25 @@ jQuery.extend( {
295
286
  // Must be an Object.
296
287
  // Because of IE, we also have to check the presence of the constructor property.
297
288
  // Make sure that DOM nodes and window objects don't pass through, as well
298
- if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
289
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
299
290
  return false;
300
291
  }
301
292
 
302
293
  try {
303
-
304
294
  // Not own constructor property must be Object
305
295
  if ( obj.constructor &&
306
- !hasOwn.call( obj, "constructor" ) &&
307
- !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
296
+ !hasOwn.call(obj, "constructor") &&
297
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
308
298
  return false;
309
299
  }
310
300
  } catch ( e ) {
311
-
312
301
  // IE8,9 Will throw exceptions on certain host objects #9897
313
302
  return false;
314
303
  }
315
304
 
316
305
  // Support: IE<9
317
306
  // Handle iteration over inherited properties before own properties.
318
- if ( !support.ownFirst ) {
307
+ if ( support.ownLast ) {
319
308
  for ( key in obj ) {
320
309
  return hasOwn.call( obj, key );
321
310
  }
@@ -333,20 +322,20 @@ jQuery.extend( {
333
322
  return obj + "";
334
323
  }
335
324
  return typeof obj === "object" || typeof obj === "function" ?
336
- class2type[ toString.call( obj ) ] || "object" :
325
+ class2type[ toString.call(obj) ] || "object" :
337
326
  typeof obj;
338
327
  },
339
328
 
329
+ // Evaluates a script in a global context
340
330
  // Workarounds based on findings by Jim Driscoll
341
331
  // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
342
332
  globalEval: function( data ) {
343
333
  if ( data && jQuery.trim( data ) ) {
344
-
345
334
  // We use execScript on Internet Explorer
346
335
  // We use an anonymous function so that context is window
347
336
  // rather than jQuery in Firefox
348
337
  ( window.execScript || function( data ) {
349
- window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
338
+ window[ "eval" ].call( window, data );
350
339
  } )( data );
351
340
  }
352
341
  },
@@ -361,20 +350,49 @@ jQuery.extend( {
361
350
  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
362
351
  },
363
352
 
364
- each: function( obj, callback ) {
365
- var length, i = 0;
353
+ // args is for internal usage only
354
+ each: function( obj, callback, args ) {
355
+ var value,
356
+ i = 0,
357
+ length = obj.length,
358
+ isArray = isArraylike( obj );
359
+
360
+ if ( args ) {
361
+ if ( isArray ) {
362
+ for ( ; i < length; i++ ) {
363
+ value = callback.apply( obj[ i ], args );
366
364
 
367
- if ( isArrayLike( obj ) ) {
368
- length = obj.length;
369
- for ( ; i < length; i++ ) {
370
- if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371
- break;
365
+ if ( value === false ) {
366
+ break;
367
+ }
368
+ }
369
+ } else {
370
+ for ( i in obj ) {
371
+ value = callback.apply( obj[ i ], args );
372
+
373
+ if ( value === false ) {
374
+ break;
375
+ }
372
376
  }
373
377
  }
378
+
379
+ // A special, fast, case for the most common use of each
374
380
  } else {
375
- for ( i in obj ) {
376
- if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
377
- break;
381
+ if ( isArray ) {
382
+ for ( ; i < length; i++ ) {
383
+ value = callback.call( obj[ i ], i, obj[ i ] );
384
+
385
+ if ( value === false ) {
386
+ break;
387
+ }
388
+ }
389
+ } else {
390
+ for ( i in obj ) {
391
+ value = callback.call( obj[ i ], i, obj[ i ] );
392
+
393
+ if ( value === false ) {
394
+ break;
395
+ }
378
396
  }
379
397
  }
380
398
  }
@@ -394,7 +412,7 @@ jQuery.extend( {
394
412
  var ret = results || [];
395
413
 
396
414
  if ( arr != null ) {
397
- if ( isArrayLike( Object( arr ) ) ) {
415
+ if ( isArraylike( Object(arr) ) ) {
398
416
  jQuery.merge( ret,
399
417
  typeof arr === "string" ?
400
418
  [ arr ] : arr
@@ -419,7 +437,6 @@ jQuery.extend( {
419
437
  i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
420
438
 
421
439
  for ( ; i < len; i++ ) {
422
-
423
440
  // Skip accessing in sparse arrays
424
441
  if ( i in arr && arr[ i ] === elem ) {
425
442
  return i;
@@ -442,7 +459,7 @@ jQuery.extend( {
442
459
  // Support: IE<9
443
460
  // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
444
461
  if ( len !== len ) {
445
- while ( second[ j ] !== undefined ) {
462
+ while ( second[j] !== undefined ) {
446
463
  first[ i++ ] = second[ j++ ];
447
464
  }
448
465
  }
@@ -473,13 +490,14 @@ jQuery.extend( {
473
490
 
474
491
  // arg is for internal usage only
475
492
  map: function( elems, callback, arg ) {
476
- var length, value,
493
+ var value,
477
494
  i = 0,
495
+ length = elems.length,
496
+ isArray = isArraylike( elems ),
478
497
  ret = [];
479
498
 
480
499
  // Go through the array, translating each of the items to their new values
481
- if ( isArrayLike( elems ) ) {
482
- length = elems.length;
500
+ if ( isArray ) {
483
501
  for ( ; i < length; i++ ) {
484
502
  value = callback( elems[ i ], i, arg );
485
503
 
@@ -542,50 +560,38 @@ jQuery.extend( {
542
560
  // jQuery.support is not used in Core but other projects attach their
543
561
  // properties to it so it needs to exist.
544
562
  support: support
545
- } );
546
-
547
- // JSHint would error on this code due to the Symbol not being defined in ES5.
548
- // Defining this global in .jshintrc would create a danger of using the global
549
- // unguarded in another place, it seems safer to just disable JSHint for these
550
- // three lines.
551
- /* jshint ignore: start */
552
- if ( typeof Symbol === "function" ) {
553
- jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
554
- }
555
- /* jshint ignore: end */
563
+ });
556
564
 
557
565
  // Populate the class2type map
558
- jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
559
- function( i, name ) {
566
+ jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
560
567
  class2type[ "[object " + name + "]" ] = name.toLowerCase();
561
- } );
562
-
563
- function isArrayLike( obj ) {
568
+ });
564
569
 
565
- // Support: iOS 8.2 (not reproducible in simulator)
566
- // `in` check used to prevent JIT error (gh-2145)
567
- // hasOwn isn't used here due to false negatives
568
- // regarding Nodelist length in IE
569
- var length = !!obj && "length" in obj && obj.length,
570
+ function isArraylike( obj ) {
571
+ var length = obj.length,
570
572
  type = jQuery.type( obj );
571
573
 
572
574
  if ( type === "function" || jQuery.isWindow( obj ) ) {
573
575
  return false;
574
576
  }
575
577
 
578
+ if ( obj.nodeType === 1 && length ) {
579
+ return true;
580
+ }
581
+
576
582
  return type === "array" || length === 0 ||
577
583
  typeof length === "number" && length > 0 && ( length - 1 ) in obj;
578
584
  }
579
585
  var Sizzle =
580
586
  /*!
581
- * Sizzle CSS Selector Engine v2.2.1
587
+ * Sizzle CSS Selector Engine v1.10.19
582
588
  * http://sizzlejs.com/
583
589
  *
584
- * Copyright jQuery Foundation and other contributors
590
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
585
591
  * Released under the MIT license
586
592
  * http://jquery.org/license
587
593
  *
588
- * Date: 2015-10-17
594
+ * Date: 2014-04-18
589
595
  */
590
596
  (function( window ) {
591
597
 
@@ -612,7 +618,7 @@ var i,
612
618
  contains,
613
619
 
614
620
  // Instance-specific data
615
- expando = "sizzle" + 1 * new Date(),
621
+ expando = "sizzle" + -(new Date()),
616
622
  preferredDoc = window.document,
617
623
  dirruns = 0,
618
624
  done = 0,
@@ -627,6 +633,7 @@ var i,
627
633
  },
628
634
 
629
635
  // General-purpose constants
636
+ strundefined = typeof undefined,
630
637
  MAX_NEGATIVE = 1 << 31,
631
638
 
632
639
  // Instance methods
@@ -636,13 +643,12 @@ var i,
636
643
  push_native = arr.push,
637
644
  push = arr.push,
638
645
  slice = arr.slice,
639
- // Use a stripped-down indexOf as it's faster than native
640
- // http://jsperf.com/thor-indexof-vs-for/5
641
- indexOf = function( list, elem ) {
646
+ // Use a stripped-down indexOf if we can't use a native one
647
+ indexOf = arr.indexOf || function( elem ) {
642
648
  var i = 0,
643
- len = list.length;
649
+ len = this.length;
644
650
  for ( ; i < len; i++ ) {
645
- if ( list[i] === elem ) {
651
+ if ( this[i] === elem ) {
646
652
  return i;
647
653
  }
648
654
  }
@@ -653,21 +659,25 @@ var i,
653
659
 
654
660
  // Regular expressions
655
661
 
656
- // http://www.w3.org/TR/css3-selectors/#whitespace
662
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
657
663
  whitespace = "[\\x20\\t\\r\\n\\f]",
664
+ // http://www.w3.org/TR/css3-syntax/#characters
665
+ characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
658
666
 
659
- // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
660
- identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
667
+ // Loosely modeled on CSS identifier characters
668
+ // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
669
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
670
+ identifier = characterEncoding.replace( "w", "w#" ),
661
671
 
662
672
  // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
663
- attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
673
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
664
674
  // Operator (capture 2)
665
675
  "*([*^$|!~]?=)" + whitespace +
666
676
  // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
667
677
  "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
668
678
  "*\\]",
669
679
 
670
- pseudos = ":(" + identifier + ")(?:\\((" +
680
+ pseudos = ":(" + characterEncoding + ")(?:\\((" +
671
681
  // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
672
682
  // 1. quoted (capture 3; capture 4 or capture 5)
673
683
  "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
@@ -678,7 +688,6 @@ var i,
678
688
  ")\\)|)",
679
689
 
680
690
  // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
681
- rwhitespace = new RegExp( whitespace + "+", "g" ),
682
691
  rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
683
692
 
684
693
  rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
@@ -690,9 +699,9 @@ var i,
690
699
  ridentifier = new RegExp( "^" + identifier + "$" ),
691
700
 
692
701
  matchExpr = {
693
- "ID": new RegExp( "^#(" + identifier + ")" ),
694
- "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
695
- "TAG": new RegExp( "^(" + identifier + "|[*])" ),
702
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
703
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
704
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
696
705
  "ATTR": new RegExp( "^" + attributes ),
697
706
  "PSEUDO": new RegExp( "^" + pseudos ),
698
707
  "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
@@ -730,14 +739,6 @@ var i,
730
739
  String.fromCharCode( high + 0x10000 ) :
731
740
  // Supplemental Plane codepoint (surrogate pair)
732
741
  String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
733
- },
734
-
735
- // Used for iframes
736
- // See setDocument()
737
- // Removing the function wrapper causes a "Permission Denied"
738
- // error in IE
739
- unloadHandler = function() {
740
- setDocument();
741
742
  };
742
743
 
743
744
  // Optimize for push.apply( _, NodeList )
@@ -770,129 +771,104 @@ try {
770
771
  }
771
772
 
772
773
  function Sizzle( selector, context, results, seed ) {
773
- var m, i, elem, nid, nidselect, match, groups, newSelector,
774
- newContext = context && context.ownerDocument,
774
+ var match, elem, m, nodeType,
775
+ // QSA vars
776
+ i, groups, old, nid, newContext, newSelector;
775
777
 
776
- // nodeType defaults to 9, since context defaults to document
777
- nodeType = context ? context.nodeType : 9;
778
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
779
+ setDocument( context );
780
+ }
778
781
 
782
+ context = context || document;
779
783
  results = results || [];
780
784
 
781
- // Return early from calls with invalid selector or context
782
- if ( typeof selector !== "string" || !selector ||
783
- nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
784
-
785
+ if ( !selector || typeof selector !== "string" ) {
785
786
  return results;
786
787
  }
787
788
 
788
- // Try to shortcut find operations (as opposed to filters) in HTML documents
789
- if ( !seed ) {
790
-
791
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
792
- setDocument( context );
793
- }
794
- context = context || document;
795
-
796
- if ( documentIsHTML ) {
797
-
798
- // If the selector is sufficiently simple, try using a "get*By*" DOM method
799
- // (excepting DocumentFragment context, where the methods don't exist)
800
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
801
-
802
- // ID selector
803
- if ( (m = match[1]) ) {
804
-
805
- // Document context
806
- if ( nodeType === 9 ) {
807
- if ( (elem = context.getElementById( m )) ) {
808
-
809
- // Support: IE, Opera, Webkit
810
- // TODO: identify versions
811
- // getElementById can match elements by name instead of ID
812
- if ( elem.id === m ) {
813
- results.push( elem );
814
- return results;
815
- }
816
- } else {
817
- return results;
818
- }
819
-
820
- // Element context
821
- } else {
789
+ if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
790
+ return [];
791
+ }
822
792
 
823
- // Support: IE, Opera, Webkit
824
- // TODO: identify versions
825
- // getElementById can match elements by name instead of ID
826
- if ( newContext && (elem = newContext.getElementById( m )) &&
827
- contains( context, elem ) &&
828
- elem.id === m ) {
793
+ if ( documentIsHTML && !seed ) {
829
794
 
795
+ // Shortcuts
796
+ if ( (match = rquickExpr.exec( selector )) ) {
797
+ // Speed-up: Sizzle("#ID")
798
+ if ( (m = match[1]) ) {
799
+ if ( nodeType === 9 ) {
800
+ elem = context.getElementById( m );
801
+ // Check parentNode to catch when Blackberry 4.6 returns
802
+ // nodes that are no longer in the document (jQuery #6963)
803
+ if ( elem && elem.parentNode ) {
804
+ // Handle the case where IE, Opera, and Webkit return items
805
+ // by name instead of ID
806
+ if ( elem.id === m ) {
830
807
  results.push( elem );
831
808
  return results;
832
809
  }
810
+ } else {
811
+ return results;
812
+ }
813
+ } else {
814
+ // Context is not a document
815
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
816
+ contains( context, elem ) && elem.id === m ) {
817
+ results.push( elem );
818
+ return results;
833
819
  }
834
-
835
- // Type selector
836
- } else if ( match[2] ) {
837
- push.apply( results, context.getElementsByTagName( selector ) );
838
- return results;
839
-
840
- // Class selector
841
- } else if ( (m = match[3]) && support.getElementsByClassName &&
842
- context.getElementsByClassName ) {
843
-
844
- push.apply( results, context.getElementsByClassName( m ) );
845
- return results;
846
820
  }
847
- }
848
821
 
849
- // Take advantage of querySelectorAll
850
- if ( support.qsa &&
851
- !compilerCache[ selector + " " ] &&
852
- (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
822
+ // Speed-up: Sizzle("TAG")
823
+ } else if ( match[2] ) {
824
+ push.apply( results, context.getElementsByTagName( selector ) );
825
+ return results;
853
826
 
854
- if ( nodeType !== 1 ) {
855
- newContext = context;
856
- newSelector = selector;
827
+ // Speed-up: Sizzle(".CLASS")
828
+ } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
829
+ push.apply( results, context.getElementsByClassName( m ) );
830
+ return results;
831
+ }
832
+ }
857
833
 
858
- // qSA looks outside Element context, which is not what we want
859
- // Thanks to Andrew Dupont for this workaround technique
860
- // Support: IE <=8
861
- // Exclude object elements
862
- } else if ( context.nodeName.toLowerCase() !== "object" ) {
834
+ // QSA path
835
+ if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
836
+ nid = old = expando;
837
+ newContext = context;
838
+ newSelector = nodeType === 9 && selector;
863
839
 
864
- // Capture the context ID, setting it first if necessary
865
- if ( (nid = context.getAttribute( "id" )) ) {
866
- nid = nid.replace( rescape, "\\$&" );
867
- } else {
868
- context.setAttribute( "id", (nid = expando) );
869
- }
840
+ // qSA works strangely on Element-rooted queries
841
+ // We can work around this by specifying an extra ID on the root
842
+ // and working up from there (Thanks to Andrew Dupont for the technique)
843
+ // IE 8 doesn't work on object elements
844
+ if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
845
+ groups = tokenize( selector );
870
846
 
871
- // Prefix every selector in the list
872
- groups = tokenize( selector );
873
- i = groups.length;
874
- nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
875
- while ( i-- ) {
876
- groups[i] = nidselect + " " + toSelector( groups[i] );
877
- }
878
- newSelector = groups.join( "," );
847
+ if ( (old = context.getAttribute("id")) ) {
848
+ nid = old.replace( rescape, "\\$&" );
849
+ } else {
850
+ context.setAttribute( "id", nid );
851
+ }
852
+ nid = "[id='" + nid + "'] ";
879
853
 
880
- // Expand context for sibling selectors
881
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
882
- context;
854
+ i = groups.length;
855
+ while ( i-- ) {
856
+ groups[i] = nid + toSelector( groups[i] );
883
857
  }
858
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
859
+ newSelector = groups.join(",");
860
+ }
884
861
 
885
- if ( newSelector ) {
886
- try {
887
- push.apply( results,
888
- newContext.querySelectorAll( newSelector )
889
- );
890
- return results;
891
- } catch ( qsaError ) {
892
- } finally {
893
- if ( nid === expando ) {
894
- context.removeAttribute( "id" );
895
- }
862
+ if ( newSelector ) {
863
+ try {
864
+ push.apply( results,
865
+ newContext.querySelectorAll( newSelector )
866
+ );
867
+ return results;
868
+ } catch(qsaError) {
869
+ } finally {
870
+ if ( !old ) {
871
+ context.removeAttribute("id");
896
872
  }
897
873
  }
898
874
  }
@@ -905,7 +881,7 @@ function Sizzle( selector, context, results, seed ) {
905
881
 
906
882
  /**
907
883
  * Create key-value caches of limited size
908
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
884
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
909
885
  * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
910
886
  * deleting the oldest entry
911
887
  */
@@ -960,7 +936,7 @@ function assert( fn ) {
960
936
  */
961
937
  function addHandle( attrs, handler ) {
962
938
  var arr = attrs.split("|"),
963
- i = arr.length;
939
+ i = attrs.length;
964
940
 
965
941
  while ( i-- ) {
966
942
  Expr.attrHandle[ arr[i] ] = handler;
@@ -1046,7 +1022,7 @@ function createPositionalPseudo( fn ) {
1046
1022
  * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1047
1023
  */
1048
1024
  function testContext( context ) {
1049
- return context && typeof context.getElementsByTagName !== "undefined" && context;
1025
+ return context && typeof context.getElementsByTagName !== strundefined && context;
1050
1026
  }
1051
1027
 
1052
1028
  // Expose support vars for convenience
@@ -1070,29 +1046,36 @@ isXML = Sizzle.isXML = function( elem ) {
1070
1046
  * @returns {Object} Returns the current document
1071
1047
  */
1072
1048
  setDocument = Sizzle.setDocument = function( node ) {
1073
- var hasCompare, parent,
1074
- doc = node ? node.ownerDocument || node : preferredDoc;
1049
+ var hasCompare,
1050
+ doc = node ? node.ownerDocument || node : preferredDoc,
1051
+ parent = doc.defaultView;
1075
1052
 
1076
- // Return early if doc is invalid or already selected
1053
+ // If no document and documentElement is available, return
1077
1054
  if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1078
1055
  return document;
1079
1056
  }
1080
1057
 
1081
- // Update global variables
1058
+ // Set our document
1082
1059
  document = doc;
1083
- docElem = document.documentElement;
1084
- documentIsHTML = !isXML( document );
1060
+ docElem = doc.documentElement;
1085
1061
 
1086
- // Support: IE 9-11, Edge
1087
- // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1088
- if ( (parent = document.defaultView) && parent.top !== parent ) {
1089
- // Support: IE 11
1090
- if ( parent.addEventListener ) {
1091
- parent.addEventListener( "unload", unloadHandler, false );
1062
+ // Support tests
1063
+ documentIsHTML = !isXML( doc );
1092
1064
 
1093
- // Support: IE 9 - 10 only
1065
+ // Support: IE>8
1066
+ // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1067
+ // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1068
+ // IE6-8 do not support the defaultView property so parent will be undefined
1069
+ if ( parent && parent !== parent.top ) {
1070
+ // IE11 does not have attachEvent, so all must suffer
1071
+ if ( parent.addEventListener ) {
1072
+ parent.addEventListener( "unload", function() {
1073
+ setDocument();
1074
+ }, false );
1094
1075
  } else if ( parent.attachEvent ) {
1095
- parent.attachEvent( "onunload", unloadHandler );
1076
+ parent.attachEvent( "onunload", function() {
1077
+ setDocument();
1078
+ });
1096
1079
  }
1097
1080
  }
1098
1081
 
@@ -1100,8 +1083,7 @@ setDocument = Sizzle.setDocument = function( node ) {
1100
1083
  ---------------------------------------------------------------------- */
1101
1084
 
1102
1085
  // Support: IE<8
1103
- // Verify that getAttribute really returns attributes and not properties
1104
- // (excepting IE8 booleans)
1086
+ // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1105
1087
  support.attributes = assert(function( div ) {
1106
1088
  div.className = "i";
1107
1089
  return !div.getAttribute("className");
@@ -1112,12 +1094,21 @@ setDocument = Sizzle.setDocument = function( node ) {
1112
1094
 
1113
1095
  // Check if getElementsByTagName("*") returns only elements
1114
1096
  support.getElementsByTagName = assert(function( div ) {
1115
- div.appendChild( document.createComment("") );
1097
+ div.appendChild( doc.createComment("") );
1116
1098
  return !div.getElementsByTagName("*").length;
1117
1099
  });
1118
1100
 
1119
- // Support: IE<9
1120
- support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1101
+ // Check if getElementsByClassName can be trusted
1102
+ support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1103
+ div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1104
+
1105
+ // Support: Safari<4
1106
+ // Catch class over-caching
1107
+ div.firstChild.className = "i";
1108
+ // Support: Opera<10
1109
+ // Catch gEBCN failure to find non-leading classes
1110
+ return div.getElementsByClassName("i").length === 2;
1111
+ });
1121
1112
 
1122
1113
  // Support: IE<10
1123
1114
  // Check if getElementById returns elements by name
@@ -1125,15 +1116,17 @@ setDocument = Sizzle.setDocument = function( node ) {
1125
1116
  // so use a roundabout getElementsByName test
1126
1117
  support.getById = assert(function( div ) {
1127
1118
  docElem.appendChild( div ).id = expando;
1128
- return !document.getElementsByName || !document.getElementsByName( expando ).length;
1119
+ return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1129
1120
  });
1130
1121
 
1131
1122
  // ID find and filter
1132
1123
  if ( support.getById ) {
1133
1124
  Expr.find["ID"] = function( id, context ) {
1134
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1125
+ if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1135
1126
  var m = context.getElementById( id );
1136
- return m ? [ m ] : [];
1127
+ // Check parentNode to catch when Blackberry 4.6 returns
1128
+ // nodes that are no longer in the document #6963
1129
+ return m && m.parentNode ? [ m ] : [];
1137
1130
  }
1138
1131
  };
1139
1132
  Expr.filter["ID"] = function( id ) {
@@ -1150,8 +1143,7 @@ setDocument = Sizzle.setDocument = function( node ) {
1150
1143
  Expr.filter["ID"] = function( id ) {
1151
1144
  var attrId = id.replace( runescape, funescape );
1152
1145
  return function( elem ) {
1153
- var node = typeof elem.getAttributeNode !== "undefined" &&
1154
- elem.getAttributeNode("id");
1146
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1155
1147
  return node && node.value === attrId;
1156
1148
  };
1157
1149
  };
@@ -1160,20 +1152,14 @@ setDocument = Sizzle.setDocument = function( node ) {
1160
1152
  // Tag
1161
1153
  Expr.find["TAG"] = support.getElementsByTagName ?
1162
1154
  function( tag, context ) {
1163
- if ( typeof context.getElementsByTagName !== "undefined" ) {
1155
+ if ( typeof context.getElementsByTagName !== strundefined ) {
1164
1156
  return context.getElementsByTagName( tag );
1165
-
1166
- // DocumentFragment nodes don't have gEBTN
1167
- } else if ( support.qsa ) {
1168
- return context.querySelectorAll( tag );
1169
1157
  }
1170
1158
  } :
1171
-
1172
1159
  function( tag, context ) {
1173
1160
  var elem,
1174
1161
  tmp = [],
1175
1162
  i = 0,
1176
- // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1177
1163
  results = context.getElementsByTagName( tag );
1178
1164
 
1179
1165
  // Filter out possible comments
@@ -1191,7 +1177,7 @@ setDocument = Sizzle.setDocument = function( node ) {
1191
1177
 
1192
1178
  // Class
1193
1179
  Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1194
- if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1180
+ if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1195
1181
  return context.getElementsByClassName( className );
1196
1182
  }
1197
1183
  };
@@ -1211,7 +1197,7 @@ setDocument = Sizzle.setDocument = function( node ) {
1211
1197
  // See http://bugs.jquery.com/ticket/13378
1212
1198
  rbuggyQSA = [];
1213
1199
 
1214
- if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1200
+ if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1215
1201
  // Build QSA regex
1216
1202
  // Regex strategy adopted from Diego Perini
1217
1203
  assert(function( div ) {
@@ -1220,15 +1206,13 @@ setDocument = Sizzle.setDocument = function( node ) {
1220
1206
  // setting a boolean content attribute,
1221
1207
  // since its presence should be enough
1222
1208
  // http://bugs.jquery.com/ticket/12359
1223
- docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1224
- "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1225
- "<option selected=''></option></select>";
1209
+ div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
1226
1210
 
1227
1211
  // Support: IE8, Opera 11-12.16
1228
1212
  // Nothing should be selected when empty strings follow ^= or $= or *=
1229
1213
  // The test attribute must be unknown in Opera but "safe" for WinRT
1230
1214
  // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1231
- if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1215
+ if ( div.querySelectorAll("[msallowclip^='']").length ) {
1232
1216
  rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1233
1217
  }
1234
1218
 
@@ -1238,30 +1222,18 @@ setDocument = Sizzle.setDocument = function( node ) {
1238
1222
  rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1239
1223
  }
1240
1224
 
1241
- // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1242
- if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1243
- rbuggyQSA.push("~=");
1244
- }
1245
-
1246
1225
  // Webkit/Opera - :checked should return selected option elements
1247
1226
  // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1248
1227
  // IE8 throws error here and will not see later tests
1249
1228
  if ( !div.querySelectorAll(":checked").length ) {
1250
1229
  rbuggyQSA.push(":checked");
1251
1230
  }
1252
-
1253
- // Support: Safari 8+, iOS 8+
1254
- // https://bugs.webkit.org/show_bug.cgi?id=136851
1255
- // In-page `selector#id sibing-combinator selector` fails
1256
- if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1257
- rbuggyQSA.push(".#.+[+~]");
1258
- }
1259
1231
  });
1260
1232
 
1261
1233
  assert(function( div ) {
1262
1234
  // Support: Windows 8 Native Apps
1263
1235
  // The type and name attributes are restricted during .innerHTML assignment
1264
- var input = document.createElement("input");
1236
+ var input = doc.createElement("input");
1265
1237
  input.setAttribute( "type", "hidden" );
1266
1238
  div.appendChild( input ).setAttribute( "name", "D" );
1267
1239
 
@@ -1309,7 +1281,7 @@ setDocument = Sizzle.setDocument = function( node ) {
1309
1281
  hasCompare = rnative.test( docElem.compareDocumentPosition );
1310
1282
 
1311
1283
  // Element contains another
1312
- // Purposefully self-exclusive
1284
+ // Purposefully does not implement inclusive descendent
1313
1285
  // As in, an element does not contain itself
1314
1286
  contains = hasCompare || rnative.test( docElem.contains ) ?
1315
1287
  function( a, b ) {
@@ -1363,16 +1335,16 @@ setDocument = Sizzle.setDocument = function( node ) {
1363
1335
  (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1364
1336
 
1365
1337
  // Choose the first element that is related to our preferred document
1366
- if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1338
+ if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1367
1339
  return -1;
1368
1340
  }
1369
- if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1341
+ if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1370
1342
  return 1;
1371
1343
  }
1372
1344
 
1373
1345
  // Maintain original order
1374
1346
  return sortInput ?
1375
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1347
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1376
1348
  0;
1377
1349
  }
1378
1350
 
@@ -1394,12 +1366,12 @@ setDocument = Sizzle.setDocument = function( node ) {
1394
1366
 
1395
1367
  // Parentless nodes are either documents or disconnected
1396
1368
  if ( !aup || !bup ) {
1397
- return a === document ? -1 :
1398
- b === document ? 1 :
1369
+ return a === doc ? -1 :
1370
+ b === doc ? 1 :
1399
1371
  aup ? -1 :
1400
1372
  bup ? 1 :
1401
1373
  sortInput ?
1402
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1374
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1403
1375
  0;
1404
1376
 
1405
1377
  // If the nodes are siblings, we can do a quick check
@@ -1432,7 +1404,7 @@ setDocument = Sizzle.setDocument = function( node ) {
1432
1404
  0;
1433
1405
  };
1434
1406
 
1435
- return document;
1407
+ return doc;
1436
1408
  };
1437
1409
 
1438
1410
  Sizzle.matches = function( expr, elements ) {
@@ -1449,7 +1421,6 @@ Sizzle.matchesSelector = function( elem, expr ) {
1449
1421
  expr = expr.replace( rattributeQuotes, "='$1']" );
1450
1422
 
1451
1423
  if ( support.matchesSelector && documentIsHTML &&
1452
- !compilerCache[ expr + " " ] &&
1453
1424
  ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1454
1425
  ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1455
1426
 
@@ -1463,7 +1434,7 @@ Sizzle.matchesSelector = function( elem, expr ) {
1463
1434
  elem.document && elem.document.nodeType !== 11 ) {
1464
1435
  return ret;
1465
1436
  }
1466
- } catch (e) {}
1437
+ } catch(e) {}
1467
1438
  }
1468
1439
 
1469
1440
  return Sizzle( expr, document, null, [ elem ] ).length > 0;
@@ -1682,7 +1653,7 @@ Expr = Sizzle.selectors = {
1682
1653
  return pattern ||
1683
1654
  (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1684
1655
  classCache( className, function( elem ) {
1685
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1656
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1686
1657
  });
1687
1658
  },
1688
1659
 
@@ -1704,7 +1675,7 @@ Expr = Sizzle.selectors = {
1704
1675
  operator === "^=" ? check && result.indexOf( check ) === 0 :
1705
1676
  operator === "*=" ? check && result.indexOf( check ) > -1 :
1706
1677
  operator === "$=" ? check && result.slice( -check.length ) === check :
1707
- operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1678
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1708
1679
  operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1709
1680
  false;
1710
1681
  };
@@ -1723,12 +1694,11 @@ Expr = Sizzle.selectors = {
1723
1694
  } :
1724
1695
 
1725
1696
  function( elem, context, xml ) {
1726
- var cache, uniqueCache, outerCache, node, nodeIndex, start,
1697
+ var cache, outerCache, node, diff, nodeIndex, start,
1727
1698
  dir = simple !== forward ? "nextSibling" : "previousSibling",
1728
1699
  parent = elem.parentNode,
1729
1700
  name = ofType && elem.nodeName.toLowerCase(),
1730
- useCache = !xml && !ofType,
1731
- diff = false;
1701
+ useCache = !xml && !ofType;
1732
1702
 
1733
1703
  if ( parent ) {
1734
1704
 
@@ -1737,10 +1707,7 @@ Expr = Sizzle.selectors = {
1737
1707
  while ( dir ) {
1738
1708
  node = elem;
1739
1709
  while ( (node = node[ dir ]) ) {
1740
- if ( ofType ?
1741
- node.nodeName.toLowerCase() === name :
1742
- node.nodeType === 1 ) {
1743
-
1710
+ if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1744
1711
  return false;
1745
1712
  }
1746
1713
  }
@@ -1754,21 +1721,11 @@ Expr = Sizzle.selectors = {
1754
1721
 
1755
1722
  // non-xml :nth-child(...) stores cache data on `parent`
1756
1723
  if ( forward && useCache ) {
1757
-
1758
1724
  // Seek `elem` from a previously-cached index
1759
-
1760
- // ...in a gzip-friendly way
1761
- node = parent;
1762
- outerCache = node[ expando ] || (node[ expando ] = {});
1763
-
1764
- // Support: IE <9 only
1765
- // Defend against cloned attroperties (jQuery gh-1709)
1766
- uniqueCache = outerCache[ node.uniqueID ] ||
1767
- (outerCache[ node.uniqueID ] = {});
1768
-
1769
- cache = uniqueCache[ type ] || [];
1770
- nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1771
- diff = nodeIndex && cache[ 2 ];
1725
+ outerCache = parent[ expando ] || (parent[ expando ] = {});
1726
+ cache = outerCache[ type ] || [];
1727
+ nodeIndex = cache[0] === dirruns && cache[1];
1728
+ diff = cache[0] === dirruns && cache[2];
1772
1729
  node = nodeIndex && parent.childNodes[ nodeIndex ];
1773
1730
 
1774
1731
  while ( (node = ++nodeIndex && node && node[ dir ] ||
@@ -1778,55 +1735,29 @@ Expr = Sizzle.selectors = {
1778
1735
 
1779
1736
  // When found, cache indexes on `parent` and break
1780
1737
  if ( node.nodeType === 1 && ++diff && node === elem ) {
1781
- uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1738
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1782
1739
  break;
1783
1740
  }
1784
1741
  }
1785
1742
 
1786
- } else {
1787
- // Use previously-cached element index if available
1788
- if ( useCache ) {
1789
- // ...in a gzip-friendly way
1790
- node = elem;
1791
- outerCache = node[ expando ] || (node[ expando ] = {});
1743
+ // Use previously-cached element index if available
1744
+ } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1745
+ diff = cache[1];
1792
1746
 
1793
- // Support: IE <9 only
1794
- // Defend against cloned attroperties (jQuery gh-1709)
1795
- uniqueCache = outerCache[ node.uniqueID ] ||
1796
- (outerCache[ node.uniqueID ] = {});
1747
+ // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1748
+ } else {
1749
+ // Use the same loop as above to seek `elem` from the start
1750
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1751
+ (diff = nodeIndex = 0) || start.pop()) ) {
1797
1752
 
1798
- cache = uniqueCache[ type ] || [];
1799
- nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1800
- diff = nodeIndex;
1801
- }
1753
+ if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1754
+ // Cache the index of each encountered element
1755
+ if ( useCache ) {
1756
+ (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1757
+ }
1802
1758
 
1803
- // xml :nth-child(...)
1804
- // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1805
- if ( diff === false ) {
1806
- // Use the same loop as above to seek `elem` from the start
1807
- while ( (node = ++nodeIndex && node && node[ dir ] ||
1808
- (diff = nodeIndex = 0) || start.pop()) ) {
1809
-
1810
- if ( ( ofType ?
1811
- node.nodeName.toLowerCase() === name :
1812
- node.nodeType === 1 ) &&
1813
- ++diff ) {
1814
-
1815
- // Cache the index of each encountered element
1816
- if ( useCache ) {
1817
- outerCache = node[ expando ] || (node[ expando ] = {});
1818
-
1819
- // Support: IE <9 only
1820
- // Defend against cloned attroperties (jQuery gh-1709)
1821
- uniqueCache = outerCache[ node.uniqueID ] ||
1822
- (outerCache[ node.uniqueID ] = {});
1823
-
1824
- uniqueCache[ type ] = [ dirruns, diff ];
1825
- }
1826
-
1827
- if ( node === elem ) {
1828
- break;
1829
- }
1759
+ if ( node === elem ) {
1760
+ break;
1830
1761
  }
1831
1762
  }
1832
1763
  }
@@ -1864,7 +1795,7 @@ Expr = Sizzle.selectors = {
1864
1795
  matched = fn( seed, argument ),
1865
1796
  i = matched.length;
1866
1797
  while ( i-- ) {
1867
- idx = indexOf( seed, matched[i] );
1798
+ idx = indexOf.call( seed, matched[i] );
1868
1799
  seed[ idx ] = !( matches[ idx ] = matched[i] );
1869
1800
  }
1870
1801
  }) :
@@ -1903,8 +1834,6 @@ Expr = Sizzle.selectors = {
1903
1834
  function( elem, context, xml ) {
1904
1835
  input[0] = elem;
1905
1836
  matcher( input, null, xml, results );
1906
- // Don't keep the element (issue #299)
1907
- input[0] = null;
1908
1837
  return !results.pop();
1909
1838
  };
1910
1839
  }),
@@ -1916,7 +1845,6 @@ Expr = Sizzle.selectors = {
1916
1845
  }),
1917
1846
 
1918
1847
  "contains": markFunction(function( text ) {
1919
- text = text.replace( runescape, funescape );
1920
1848
  return function( elem ) {
1921
1849
  return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1922
1850
  };
@@ -2188,10 +2116,10 @@ function addCombinator( matcher, combinator, base ) {
2188
2116
 
2189
2117
  // Check against all ancestor/preceding elements
2190
2118
  function( elem, context, xml ) {
2191
- var oldCache, uniqueCache, outerCache,
2119
+ var oldCache, outerCache,
2192
2120
  newCache = [ dirruns, doneName ];
2193
2121
 
2194
- // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2122
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2195
2123
  if ( xml ) {
2196
2124
  while ( (elem = elem[ dir ]) ) {
2197
2125
  if ( elem.nodeType === 1 || checkNonElements ) {
@@ -2204,19 +2132,14 @@ function addCombinator( matcher, combinator, base ) {
2204
2132
  while ( (elem = elem[ dir ]) ) {
2205
2133
  if ( elem.nodeType === 1 || checkNonElements ) {
2206
2134
  outerCache = elem[ expando ] || (elem[ expando ] = {});
2207
-
2208
- // Support: IE <9 only
2209
- // Defend against cloned attroperties (jQuery gh-1709)
2210
- uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2211
-
2212
- if ( (oldCache = uniqueCache[ dir ]) &&
2135
+ if ( (oldCache = outerCache[ dir ]) &&
2213
2136
  oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2214
2137
 
2215
2138
  // Assign to newCache so results back-propagate to previous elements
2216
2139
  return (newCache[ 2 ] = oldCache[ 2 ]);
2217
2140
  } else {
2218
2141
  // Reuse newcache so results back-propagate to previous elements
2219
- uniqueCache[ dir ] = newCache;
2142
+ outerCache[ dir ] = newCache;
2220
2143
 
2221
2144
  // A match means we're done; a fail means we have to keep checking
2222
2145
  if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
@@ -2343,7 +2266,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
2343
2266
  i = matcherOut.length;
2344
2267
  while ( i-- ) {
2345
2268
  if ( (elem = matcherOut[i]) &&
2346
- (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2269
+ (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2347
2270
 
2348
2271
  seed[temp] = !(results[temp] = elem);
2349
2272
  }
@@ -2378,16 +2301,13 @@ function matcherFromTokens( tokens ) {
2378
2301
  return elem === checkContext;
2379
2302
  }, implicitRelative, true ),
2380
2303
  matchAnyContext = addCombinator( function( elem ) {
2381
- return indexOf( checkContext, elem ) > -1;
2304
+ return indexOf.call( checkContext, elem ) > -1;
2382
2305
  }, implicitRelative, true ),
2383
2306
  matchers = [ function( elem, context, xml ) {
2384
- var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2307
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2385
2308
  (checkContext = context).nodeType ?
2386
2309
  matchContext( elem, context, xml ) :
2387
2310
  matchAnyContext( elem, context, xml ) );
2388
- // Avoid hanging onto element (issue #299)
2389
- checkContext = null;
2390
- return ret;
2391
2311
  } ];
2392
2312
 
2393
2313
  for ( ; i < len; i++ ) {
@@ -2441,21 +2361,18 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2441
2361
  len = elems.length;
2442
2362
 
2443
2363
  if ( outermost ) {
2444
- outermostContext = context === document || context || outermost;
2364
+ outermostContext = context !== document && context;
2445
2365
  }
2446
2366
 
2447
2367
  // Add elements passing elementMatchers directly to results
2368
+ // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2448
2369
  // Support: IE<9, Safari
2449
2370
  // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2450
2371
  for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2451
2372
  if ( byElement && elem ) {
2452
2373
  j = 0;
2453
- if ( !context && elem.ownerDocument !== document ) {
2454
- setDocument( elem );
2455
- xml = !documentIsHTML;
2456
- }
2457
2374
  while ( (matcher = elementMatchers[j++]) ) {
2458
- if ( matcher( elem, context || document, xml) ) {
2375
+ if ( matcher( elem, context, xml ) ) {
2459
2376
  results.push( elem );
2460
2377
  break;
2461
2378
  }
@@ -2479,17 +2396,8 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2479
2396
  }
2480
2397
  }
2481
2398
 
2482
- // `i` is now the count of elements visited above, and adding it to `matchedCount`
2483
- // makes the latter nonnegative.
2484
- matchedCount += i;
2485
-
2486
2399
  // Apply set filters to unmatched elements
2487
- // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2488
- // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2489
- // no element matchers and no seed.
2490
- // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2491
- // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2492
- // numerically zero.
2400
+ matchedCount += i;
2493
2401
  if ( bySet && i !== matchedCount ) {
2494
2402
  j = 0;
2495
2403
  while ( (matcher = setMatchers[j++]) ) {
@@ -2581,11 +2489,10 @@ select = Sizzle.select = function( selector, context, results, seed ) {
2581
2489
 
2582
2490
  results = results || [];
2583
2491
 
2584
- // Try to minimize operations if there is only one selector in the list and no seed
2585
- // (the latter of which guarantees us context)
2492
+ // Try to minimize operations if there is no seed and only one group
2586
2493
  if ( match.length === 1 ) {
2587
2494
 
2588
- // Reduce context if the leading compound selector is an ID
2495
+ // Take a shortcut and set the context if the root selector is an ID
2589
2496
  tokens = match[0] = match[0].slice( 0 );
2590
2497
  if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2591
2498
  support.getById && context.nodeType === 9 && documentIsHTML &&
@@ -2640,7 +2547,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
2640
2547
  context,
2641
2548
  !documentIsHTML,
2642
2549
  results,
2643
- !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2550
+ rsibling.test( selector ) && testContext( context.parentNode ) || context
2644
2551
  );
2645
2552
  return results;
2646
2553
  };
@@ -2650,7 +2557,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
2650
2557
  // Sort stability
2651
2558
  support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2652
2559
 
2653
- // Support: Chrome 14-35+
2560
+ // Support: Chrome<14
2654
2561
  // Always assume duplicates if they aren't passed to the comparison function
2655
2562
  support.detectDuplicates = !!hasDuplicate;
2656
2563
 
@@ -2716,46 +2623,17 @@ return Sizzle;
2716
2623
 
2717
2624
  jQuery.find = Sizzle;
2718
2625
  jQuery.expr = Sizzle.selectors;
2719
- jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2720
- jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2626
+ jQuery.expr[":"] = jQuery.expr.pseudos;
2627
+ jQuery.unique = Sizzle.uniqueSort;
2721
2628
  jQuery.text = Sizzle.getText;
2722
2629
  jQuery.isXMLDoc = Sizzle.isXML;
2723
2630
  jQuery.contains = Sizzle.contains;
2724
2631
 
2725
2632
 
2726
2633
 
2727
- var dir = function( elem, dir, until ) {
2728
- var matched = [],
2729
- truncate = until !== undefined;
2730
-
2731
- while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2732
- if ( elem.nodeType === 1 ) {
2733
- if ( truncate && jQuery( elem ).is( until ) ) {
2734
- break;
2735
- }
2736
- matched.push( elem );
2737
- }
2738
- }
2739
- return matched;
2740
- };
2741
-
2742
-
2743
- var siblings = function( n, elem ) {
2744
- var matched = [];
2745
-
2746
- for ( ; n; n = n.nextSibling ) {
2747
- if ( n.nodeType === 1 && n !== elem ) {
2748
- matched.push( n );
2749
- }
2750
- }
2751
-
2752
- return matched;
2753
- };
2754
-
2755
-
2756
2634
  var rneedsContext = jQuery.expr.match.needsContext;
2757
2635
 
2758
- var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2636
+ var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2759
2637
 
2760
2638
 
2761
2639
 
@@ -2767,14 +2645,14 @@ function winnow( elements, qualifier, not ) {
2767
2645
  return jQuery.grep( elements, function( elem, i ) {
2768
2646
  /* jshint -W018 */
2769
2647
  return !!qualifier.call( elem, i, elem ) !== not;
2770
- } );
2648
+ });
2771
2649
 
2772
2650
  }
2773
2651
 
2774
2652
  if ( qualifier.nodeType ) {
2775
2653
  return jQuery.grep( elements, function( elem ) {
2776
2654
  return ( elem === qualifier ) !== not;
2777
- } );
2655
+ });
2778
2656
 
2779
2657
  }
2780
2658
 
@@ -2787,8 +2665,8 @@ function winnow( elements, qualifier, not ) {
2787
2665
  }
2788
2666
 
2789
2667
  return jQuery.grep( elements, function( elem ) {
2790
- return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
2791
- } );
2668
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
2669
+ });
2792
2670
  }
2793
2671
 
2794
2672
  jQuery.filter = function( expr, elems, not ) {
@@ -2802,10 +2680,10 @@ jQuery.filter = function( expr, elems, not ) {
2802
2680
  jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2803
2681
  jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2804
2682
  return elem.nodeType === 1;
2805
- } ) );
2683
+ }));
2806
2684
  };
2807
2685
 
2808
- jQuery.fn.extend( {
2686
+ jQuery.fn.extend({
2809
2687
  find: function( selector ) {
2810
2688
  var i,
2811
2689
  ret = [],
@@ -2813,13 +2691,13 @@ jQuery.fn.extend( {
2813
2691
  len = self.length;
2814
2692
 
2815
2693
  if ( typeof selector !== "string" ) {
2816
- return this.pushStack( jQuery( selector ).filter( function() {
2694
+ return this.pushStack( jQuery( selector ).filter(function() {
2817
2695
  for ( i = 0; i < len; i++ ) {
2818
2696
  if ( jQuery.contains( self[ i ], this ) ) {
2819
2697
  return true;
2820
2698
  }
2821
2699
  }
2822
- } ) );
2700
+ }) );
2823
2701
  }
2824
2702
 
2825
2703
  for ( i = 0; i < len; i++ ) {
@@ -2832,10 +2710,10 @@ jQuery.fn.extend( {
2832
2710
  return ret;
2833
2711
  },
2834
2712
  filter: function( selector ) {
2835
- return this.pushStack( winnow( this, selector || [], false ) );
2713
+ return this.pushStack( winnow(this, selector || [], false) );
2836
2714
  },
2837
2715
  not: function( selector ) {
2838
- return this.pushStack( winnow( this, selector || [], true ) );
2716
+ return this.pushStack( winnow(this, selector || [], true) );
2839
2717
  },
2840
2718
  is: function( selector ) {
2841
2719
  return !!winnow(
@@ -2849,7 +2727,7 @@ jQuery.fn.extend( {
2849
2727
  false
2850
2728
  ).length;
2851
2729
  }
2852
- } );
2730
+ });
2853
2731
 
2854
2732
 
2855
2733
  // Initialize a jQuery object
@@ -2858,12 +2736,15 @@ jQuery.fn.extend( {
2858
2736
  // A central reference to the root jQuery(document)
2859
2737
  var rootjQuery,
2860
2738
 
2739
+ // Use the correct document accordingly with window argument (sandbox)
2740
+ document = window.document,
2741
+
2861
2742
  // A simple way to check for HTML strings
2862
2743
  // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2863
2744
  // Strict HTML recognition (#11290: must start with <)
2864
2745
  rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2865
2746
 
2866
- init = jQuery.fn.init = function( selector, context, root ) {
2747
+ init = jQuery.fn.init = function( selector, context ) {
2867
2748
  var match, elem;
2868
2749
 
2869
2750
  // HANDLE: $(""), $(null), $(undefined), $(false)
@@ -2871,16 +2752,9 @@ var rootjQuery,
2871
2752
  return this;
2872
2753
  }
2873
2754
 
2874
- // init accepts an alternate rootjQuery
2875
- // so migrate can support jQuery.sub (gh-2101)
2876
- root = root || rootjQuery;
2877
-
2878
2755
  // Handle HTML strings
2879
2756
  if ( typeof selector === "string" ) {
2880
- if ( selector.charAt( 0 ) === "<" &&
2881
- selector.charAt( selector.length - 1 ) === ">" &&
2882
- selector.length >= 3 ) {
2883
-
2757
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
2884
2758
  // Assume that strings that start and end with <> are HTML and skip the regex check
2885
2759
  match = [ null, selector, null ];
2886
2760
 
@@ -2889,24 +2763,23 @@ var rootjQuery,
2889
2763
  }
2890
2764
 
2891
2765
  // Match html or make sure no context is specified for #id
2892
- if ( match && ( match[ 1 ] || !context ) ) {
2766
+ if ( match && (match[1] || !context) ) {
2893
2767
 
2894
2768
  // HANDLE: $(html) -> $(array)
2895
- if ( match[ 1 ] ) {
2896
- context = context instanceof jQuery ? context[ 0 ] : context;
2769
+ if ( match[1] ) {
2770
+ context = context instanceof jQuery ? context[0] : context;
2897
2771
 
2898
2772
  // scripts is true for back-compat
2899
2773
  // Intentionally let the error be thrown if parseHTML is not present
2900
2774
  jQuery.merge( this, jQuery.parseHTML(
2901
- match[ 1 ],
2775
+ match[1],
2902
2776
  context && context.nodeType ? context.ownerDocument || context : document,
2903
2777
  true
2904
2778
  ) );
2905
2779
 
2906
2780
  // HANDLE: $(html, props)
2907
- if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2781
+ if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2908
2782
  for ( match in context ) {
2909
-
2910
2783
  // Properties of context are called as methods if possible
2911
2784
  if ( jQuery.isFunction( this[ match ] ) ) {
2912
2785
  this[ match ]( context[ match ] );
@@ -2922,21 +2795,20 @@ var rootjQuery,
2922
2795
 
2923
2796
  // HANDLE: $(#id)
2924
2797
  } else {
2925
- elem = document.getElementById( match[ 2 ] );
2798
+ elem = document.getElementById( match[2] );
2926
2799
 
2927
2800
  // Check parentNode to catch when Blackberry 4.6 returns
2928
2801
  // nodes that are no longer in the document #6963
2929
2802
  if ( elem && elem.parentNode ) {
2930
-
2931
2803
  // Handle the case where IE and Opera return items
2932
2804
  // by name instead of ID
2933
- if ( elem.id !== match[ 2 ] ) {
2805
+ if ( elem.id !== match[2] ) {
2934
2806
  return rootjQuery.find( selector );
2935
2807
  }
2936
2808
 
2937
2809
  // Otherwise, we inject the element directly into the jQuery object
2938
2810
  this.length = 1;
2939
- this[ 0 ] = elem;
2811
+ this[0] = elem;
2940
2812
  }
2941
2813
 
2942
2814
  this.context = document;
@@ -2946,7 +2818,7 @@ var rootjQuery,
2946
2818
 
2947
2819
  // HANDLE: $(expr, $(...))
2948
2820
  } else if ( !context || context.jquery ) {
2949
- return ( context || root ).find( selector );
2821
+ return ( context || rootjQuery ).find( selector );
2950
2822
 
2951
2823
  // HANDLE: $(expr, context)
2952
2824
  // (which is just equivalent to: $(context).find(expr)
@@ -2956,16 +2828,15 @@ var rootjQuery,
2956
2828
 
2957
2829
  // HANDLE: $(DOMElement)
2958
2830
  } else if ( selector.nodeType ) {
2959
- this.context = this[ 0 ] = selector;
2831
+ this.context = this[0] = selector;
2960
2832
  this.length = 1;
2961
2833
  return this;
2962
2834
 
2963
2835
  // HANDLE: $(function)
2964
2836
  // Shortcut for document ready
2965
2837
  } else if ( jQuery.isFunction( selector ) ) {
2966
- return typeof root.ready !== "undefined" ?
2967
- root.ready( selector ) :
2968
-
2838
+ return typeof rootjQuery.ready !== "undefined" ?
2839
+ rootjQuery.ready( selector ) :
2969
2840
  // Execute immediately if ready is not present
2970
2841
  selector( jQuery );
2971
2842
  }
@@ -2986,7 +2857,6 @@ rootjQuery = jQuery( document );
2986
2857
 
2987
2858
 
2988
2859
  var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2989
-
2990
2860
  // methods guaranteed to produce a unique set when starting from a unique set
2991
2861
  guaranteedUnique = {
2992
2862
  children: true,
@@ -2995,19 +2865,46 @@ var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2995
2865
  prev: true
2996
2866
  };
2997
2867
 
2998
- jQuery.fn.extend( {
2868
+ jQuery.extend({
2869
+ dir: function( elem, dir, until ) {
2870
+ var matched = [],
2871
+ cur = elem[ dir ];
2872
+
2873
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
2874
+ if ( cur.nodeType === 1 ) {
2875
+ matched.push( cur );
2876
+ }
2877
+ cur = cur[dir];
2878
+ }
2879
+ return matched;
2880
+ },
2881
+
2882
+ sibling: function( n, elem ) {
2883
+ var r = [];
2884
+
2885
+ for ( ; n; n = n.nextSibling ) {
2886
+ if ( n.nodeType === 1 && n !== elem ) {
2887
+ r.push( n );
2888
+ }
2889
+ }
2890
+
2891
+ return r;
2892
+ }
2893
+ });
2894
+
2895
+ jQuery.fn.extend({
2999
2896
  has: function( target ) {
3000
2897
  var i,
3001
2898
  targets = jQuery( target, this ),
3002
2899
  len = targets.length;
3003
2900
 
3004
- return this.filter( function() {
2901
+ return this.filter(function() {
3005
2902
  for ( i = 0; i < len; i++ ) {
3006
- if ( jQuery.contains( this, targets[ i ] ) ) {
2903
+ if ( jQuery.contains( this, targets[i] ) ) {
3007
2904
  return true;
3008
2905
  }
3009
2906
  }
3010
- } );
2907
+ });
3011
2908
  },
3012
2909
 
3013
2910
  closest: function( selectors, context ) {
@@ -3020,15 +2917,14 @@ jQuery.fn.extend( {
3020
2917
  0;
3021
2918
 
3022
2919
  for ( ; i < l; i++ ) {
3023
- for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3024
-
2920
+ for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
3025
2921
  // Always skip document fragments
3026
- if ( cur.nodeType < 11 && ( pos ?
3027
- pos.index( cur ) > -1 :
2922
+ if ( cur.nodeType < 11 && (pos ?
2923
+ pos.index(cur) > -1 :
3028
2924
 
3029
2925
  // Don't pass non-elements to Sizzle
3030
2926
  cur.nodeType === 1 &&
3031
- jQuery.find.matchesSelector( cur, selectors ) ) ) {
2927
+ jQuery.find.matchesSelector(cur, selectors)) ) {
3032
2928
 
3033
2929
  matched.push( cur );
3034
2930
  break;
@@ -3036,7 +2932,7 @@ jQuery.fn.extend( {
3036
2932
  }
3037
2933
  }
3038
2934
 
3039
- return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
2935
+ return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
3040
2936
  },
3041
2937
 
3042
2938
  // Determine the position of an element within
@@ -3045,24 +2941,23 @@ jQuery.fn.extend( {
3045
2941
 
3046
2942
  // No argument, return index in parent
3047
2943
  if ( !elem ) {
3048
- return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
2944
+ return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
3049
2945
  }
3050
2946
 
3051
2947
  // index in selector
3052
2948
  if ( typeof elem === "string" ) {
3053
- return jQuery.inArray( this[ 0 ], jQuery( elem ) );
2949
+ return jQuery.inArray( this[0], jQuery( elem ) );
3054
2950
  }
3055
2951
 
3056
2952
  // Locate the position of the desired element
3057
2953
  return jQuery.inArray(
3058
-
3059
2954
  // If it receives a jQuery object, the first element is used
3060
- elem.jquery ? elem[ 0 ] : elem, this );
2955
+ elem.jquery ? elem[0] : elem, this );
3061
2956
  },
3062
2957
 
3063
2958
  add: function( selector, context ) {
3064
2959
  return this.pushStack(
3065
- jQuery.uniqueSort(
2960
+ jQuery.unique(
3066
2961
  jQuery.merge( this.get(), jQuery( selector, context ) )
3067
2962
  )
3068
2963
  );
@@ -3070,10 +2965,10 @@ jQuery.fn.extend( {
3070
2965
 
3071
2966
  addBack: function( selector ) {
3072
2967
  return this.add( selector == null ?
3073
- this.prevObject : this.prevObject.filter( selector )
2968
+ this.prevObject : this.prevObject.filter(selector)
3074
2969
  );
3075
2970
  }
3076
- } );
2971
+ });
3077
2972
 
3078
2973
  function sibling( cur, dir ) {
3079
2974
  do {
@@ -3083,16 +2978,16 @@ function sibling( cur, dir ) {
3083
2978
  return cur;
3084
2979
  }
3085
2980
 
3086
- jQuery.each( {
2981
+ jQuery.each({
3087
2982
  parent: function( elem ) {
3088
2983
  var parent = elem.parentNode;
3089
2984
  return parent && parent.nodeType !== 11 ? parent : null;
3090
2985
  },
3091
2986
  parents: function( elem ) {
3092
- return dir( elem, "parentNode" );
2987
+ return jQuery.dir( elem, "parentNode" );
3093
2988
  },
3094
2989
  parentsUntil: function( elem, i, until ) {
3095
- return dir( elem, "parentNode", until );
2990
+ return jQuery.dir( elem, "parentNode", until );
3096
2991
  },
3097
2992
  next: function( elem ) {
3098
2993
  return sibling( elem, "nextSibling" );
@@ -3101,22 +2996,22 @@ jQuery.each( {
3101
2996
  return sibling( elem, "previousSibling" );
3102
2997
  },
3103
2998
  nextAll: function( elem ) {
3104
- return dir( elem, "nextSibling" );
2999
+ return jQuery.dir( elem, "nextSibling" );
3105
3000
  },
3106
3001
  prevAll: function( elem ) {
3107
- return dir( elem, "previousSibling" );
3002
+ return jQuery.dir( elem, "previousSibling" );
3108
3003
  },
3109
3004
  nextUntil: function( elem, i, until ) {
3110
- return dir( elem, "nextSibling", until );
3005
+ return jQuery.dir( elem, "nextSibling", until );
3111
3006
  },
3112
3007
  prevUntil: function( elem, i, until ) {
3113
- return dir( elem, "previousSibling", until );
3008
+ return jQuery.dir( elem, "previousSibling", until );
3114
3009
  },
3115
3010
  siblings: function( elem ) {
3116
- return siblings( ( elem.parentNode || {} ).firstChild, elem );
3011
+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
3117
3012
  },
3118
3013
  children: function( elem ) {
3119
- return siblings( elem.firstChild );
3014
+ return jQuery.sibling( elem.firstChild );
3120
3015
  },
3121
3016
  contents: function( elem ) {
3122
3017
  return jQuery.nodeName( elem, "iframe" ) ?
@@ -3136,10 +3031,9 @@ jQuery.each( {
3136
3031
  }
3137
3032
 
3138
3033
  if ( this.length > 1 ) {
3139
-
3140
3034
  // Remove duplicates
3141
3035
  if ( !guaranteedUnique[ name ] ) {
3142
- ret = jQuery.uniqueSort( ret );
3036
+ ret = jQuery.unique( ret );
3143
3037
  }
3144
3038
 
3145
3039
  // Reverse order for parents* and prev-derivatives
@@ -3150,17 +3044,20 @@ jQuery.each( {
3150
3044
 
3151
3045
  return this.pushStack( ret );
3152
3046
  };
3153
- } );
3154
- var rnotwhite = ( /\S+/g );
3047
+ });
3048
+ var rnotwhite = (/\S+/g);
3049
+
3155
3050
 
3156
3051
 
3052
+ // String to Object options format cache
3053
+ var optionsCache = {};
3157
3054
 
3158
- // Convert String-formatted options into Object-formatted ones
3055
+ // Convert String-formatted options into Object-formatted ones and store in cache
3159
3056
  function createOptions( options ) {
3160
- var object = {};
3057
+ var object = optionsCache[ options ] = {};
3161
3058
  jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3162
3059
  object[ flag ] = true;
3163
- } );
3060
+ });
3164
3061
  return object;
3165
3062
  }
3166
3063
 
@@ -3191,186 +3088,156 @@ jQuery.Callbacks = function( options ) {
3191
3088
  // Convert options from String-formatted to Object-formatted if needed
3192
3089
  // (we check in cache first)
3193
3090
  options = typeof options === "string" ?
3194
- createOptions( options ) :
3091
+ ( optionsCache[ options ] || createOptions( options ) ) :
3195
3092
  jQuery.extend( {}, options );
3196
3093
 
3197
3094
  var // Flag to know if list is currently firing
3198
3095
  firing,
3199
-
3200
- // Last fire value for non-forgettable lists
3096
+ // Last fire value (for non-forgettable lists)
3201
3097
  memory,
3202
-
3203
3098
  // Flag to know if list was already fired
3204
3099
  fired,
3205
-
3206
- // Flag to prevent firing
3207
- locked,
3208
-
3100
+ // End of the loop when firing
3101
+ firingLength,
3102
+ // Index of currently firing callback (modified by remove if needed)
3103
+ firingIndex,
3104
+ // First callback to fire (used internally by add and fireWith)
3105
+ firingStart,
3209
3106
  // Actual callback list
3210
3107
  list = [],
3211
-
3212
- // Queue of execution data for repeatable lists
3213
- queue = [],
3214
-
3215
- // Index of currently firing callback (modified by add/remove as needed)
3216
- firingIndex = -1,
3217
-
3108
+ // Stack of fire calls for repeatable lists
3109
+ stack = !options.once && [],
3218
3110
  // Fire callbacks
3219
- fire = function() {
3220
-
3221
- // Enforce single-firing
3222
- locked = options.once;
3223
-
3224
- // Execute callbacks for all pending executions,
3225
- // respecting firingIndex overrides and runtime changes
3226
- fired = firing = true;
3227
- for ( ; queue.length; firingIndex = -1 ) {
3228
- memory = queue.shift();
3229
- while ( ++firingIndex < list.length ) {
3230
-
3231
- // Run callback and check for early termination
3232
- if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3233
- options.stopOnFalse ) {
3234
-
3235
- // Jump to end and forget the data so .add doesn't re-fire
3236
- firingIndex = list.length;
3237
- memory = false;
3238
- }
3111
+ fire = function( data ) {
3112
+ memory = options.memory && data;
3113
+ fired = true;
3114
+ firingIndex = firingStart || 0;
3115
+ firingStart = 0;
3116
+ firingLength = list.length;
3117
+ firing = true;
3118
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3119
+ if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3120
+ memory = false; // To prevent further calls using add
3121
+ break;
3239
3122
  }
3240
3123
  }
3241
-
3242
- // Forget the data if we're done with it
3243
- if ( !options.memory ) {
3244
- memory = false;
3245
- }
3246
-
3247
3124
  firing = false;
3248
-
3249
- // Clean up if we're done firing for good
3250
- if ( locked ) {
3251
-
3252
- // Keep an empty list if we have data for future add calls
3253
- if ( memory ) {
3125
+ if ( list ) {
3126
+ if ( stack ) {
3127
+ if ( stack.length ) {
3128
+ fire( stack.shift() );
3129
+ }
3130
+ } else if ( memory ) {
3254
3131
  list = [];
3255
-
3256
- // Otherwise, this object is spent
3257
3132
  } else {
3258
- list = "";
3133
+ self.disable();
3259
3134
  }
3260
3135
  }
3261
3136
  },
3262
-
3263
3137
  // Actual Callbacks object
3264
3138
  self = {
3265
-
3266
3139
  // Add a callback or a collection of callbacks to the list
3267
3140
  add: function() {
3268
3141
  if ( list ) {
3269
-
3270
- // If we have memory from a past run, we should fire after adding
3271
- if ( memory && !firing ) {
3272
- firingIndex = list.length - 1;
3273
- queue.push( memory );
3274
- }
3275
-
3276
- ( function add( args ) {
3142
+ // First, we save the current length
3143
+ var start = list.length;
3144
+ (function add( args ) {
3277
3145
  jQuery.each( args, function( _, arg ) {
3278
- if ( jQuery.isFunction( arg ) ) {
3146
+ var type = jQuery.type( arg );
3147
+ if ( type === "function" ) {
3279
3148
  if ( !options.unique || !self.has( arg ) ) {
3280
3149
  list.push( arg );
3281
3150
  }
3282
- } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3283
-
3151
+ } else if ( arg && arg.length && type !== "string" ) {
3284
3152
  // Inspect recursively
3285
3153
  add( arg );
3286
3154
  }
3287
- } );
3288
- } )( arguments );
3289
-
3290
- if ( memory && !firing ) {
3291
- fire();
3155
+ });
3156
+ })( arguments );
3157
+ // Do we need to add the callbacks to the
3158
+ // current firing batch?
3159
+ if ( firing ) {
3160
+ firingLength = list.length;
3161
+ // With memory, if we're not firing then
3162
+ // we should call right away
3163
+ } else if ( memory ) {
3164
+ firingStart = start;
3165
+ fire( memory );
3292
3166
  }
3293
3167
  }
3294
3168
  return this;
3295
3169
  },
3296
-
3297
3170
  // Remove a callback from the list
3298
3171
  remove: function() {
3299
- jQuery.each( arguments, function( _, arg ) {
3300
- var index;
3301
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3302
- list.splice( index, 1 );
3303
-
3304
- // Handle firing indexes
3305
- if ( index <= firingIndex ) {
3306
- firingIndex--;
3172
+ if ( list ) {
3173
+ jQuery.each( arguments, function( _, arg ) {
3174
+ var index;
3175
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3176
+ list.splice( index, 1 );
3177
+ // Handle firing indexes
3178
+ if ( firing ) {
3179
+ if ( index <= firingLength ) {
3180
+ firingLength--;
3181
+ }
3182
+ if ( index <= firingIndex ) {
3183
+ firingIndex--;
3184
+ }
3185
+ }
3307
3186
  }
3308
- }
3309
- } );
3187
+ });
3188
+ }
3310
3189
  return this;
3311
3190
  },
3312
-
3313
3191
  // Check if a given callback is in the list.
3314
3192
  // If no argument is given, return whether or not list has callbacks attached.
3315
3193
  has: function( fn ) {
3316
- return fn ?
3317
- jQuery.inArray( fn, list ) > -1 :
3318
- list.length > 0;
3194
+ return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3319
3195
  },
3320
-
3321
3196
  // Remove all callbacks from the list
3322
3197
  empty: function() {
3323
- if ( list ) {
3324
- list = [];
3325
- }
3198
+ list = [];
3199
+ firingLength = 0;
3326
3200
  return this;
3327
3201
  },
3328
-
3329
- // Disable .fire and .add
3330
- // Abort any current/pending executions
3331
- // Clear all callbacks and values
3202
+ // Have the list do nothing anymore
3332
3203
  disable: function() {
3333
- locked = queue = [];
3334
- list = memory = "";
3204
+ list = stack = memory = undefined;
3335
3205
  return this;
3336
3206
  },
3207
+ // Is it disabled?
3337
3208
  disabled: function() {
3338
3209
  return !list;
3339
3210
  },
3340
-
3341
- // Disable .fire
3342
- // Also disable .add unless we have memory (since it would have no effect)
3343
- // Abort any pending executions
3211
+ // Lock the list in its current state
3344
3212
  lock: function() {
3345
- locked = true;
3213
+ stack = undefined;
3346
3214
  if ( !memory ) {
3347
3215
  self.disable();
3348
3216
  }
3349
3217
  return this;
3350
3218
  },
3219
+ // Is it locked?
3351
3220
  locked: function() {
3352
- return !!locked;
3221
+ return !stack;
3353
3222
  },
3354
-
3355
3223
  // Call all callbacks with the given context and arguments
3356
3224
  fireWith: function( context, args ) {
3357
- if ( !locked ) {
3225
+ if ( list && ( !fired || stack ) ) {
3358
3226
  args = args || [];
3359
3227
  args = [ context, args.slice ? args.slice() : args ];
3360
- queue.push( args );
3361
- if ( !firing ) {
3362
- fire();
3228
+ if ( firing ) {
3229
+ stack.push( args );
3230
+ } else {
3231
+ fire( args );
3363
3232
  }
3364
3233
  }
3365
3234
  return this;
3366
3235
  },
3367
-
3368
3236
  // Call all the callbacks with the given arguments
3369
3237
  fire: function() {
3370
3238
  self.fireWith( this, arguments );
3371
3239
  return this;
3372
3240
  },
3373
-
3374
3241
  // To know if the callbacks have already been called at least once
3375
3242
  fired: function() {
3376
3243
  return !!fired;
@@ -3381,15 +3248,14 @@ jQuery.Callbacks = function( options ) {
3381
3248
  };
3382
3249
 
3383
3250
 
3384
- jQuery.extend( {
3251
+ jQuery.extend({
3385
3252
 
3386
3253
  Deferred: function( func ) {
3387
3254
  var tuples = [
3388
-
3389
3255
  // action, add listener, listener list, final state
3390
- [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3391
- [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3392
- [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3256
+ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3257
+ [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3258
+ [ "notify", "progress", jQuery.Callbacks("memory") ]
3393
3259
  ],
3394
3260
  state = "pending",
3395
3261
  promise = {
@@ -3402,30 +3268,25 @@ jQuery.extend( {
3402
3268
  },
3403
3269
  then: function( /* fnDone, fnFail, fnProgress */ ) {
3404
3270
  var fns = arguments;
3405
- return jQuery.Deferred( function( newDefer ) {
3271
+ return jQuery.Deferred(function( newDefer ) {
3406
3272
  jQuery.each( tuples, function( i, tuple ) {
3407
3273
  var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3408
-
3409
3274
  // deferred[ done | fail | progress ] for forwarding actions to newDefer
3410
- deferred[ tuple[ 1 ] ]( function() {
3275
+ deferred[ tuple[1] ](function() {
3411
3276
  var returned = fn && fn.apply( this, arguments );
3412
3277
  if ( returned && jQuery.isFunction( returned.promise ) ) {
3413
3278
  returned.promise()
3414
- .progress( newDefer.notify )
3415
3279
  .done( newDefer.resolve )
3416
- .fail( newDefer.reject );
3280
+ .fail( newDefer.reject )
3281
+ .progress( newDefer.notify );
3417
3282
  } else {
3418
- newDefer[ tuple[ 0 ] + "With" ](
3419
- this === promise ? newDefer.promise() : this,
3420
- fn ? [ returned ] : arguments
3421
- );
3283
+ newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3422
3284
  }
3423
- } );
3424
- } );
3285
+ });
3286
+ });
3425
3287
  fns = null;
3426
- } ).promise();
3288
+ }).promise();
3427
3289
  },
3428
-
3429
3290
  // Get a promise for this deferred
3430
3291
  // If obj is provided, the promise aspect is added to the object
3431
3292
  promise: function( obj ) {
@@ -3443,12 +3304,11 @@ jQuery.extend( {
3443
3304
  stateString = tuple[ 3 ];
3444
3305
 
3445
3306
  // promise[ done | fail | progress ] = list.add
3446
- promise[ tuple[ 1 ] ] = list.add;
3307
+ promise[ tuple[1] ] = list.add;
3447
3308
 
3448
3309
  // Handle state
3449
3310
  if ( stateString ) {
3450
- list.add( function() {
3451
-
3311
+ list.add(function() {
3452
3312
  // state = [ resolved | rejected ]
3453
3313
  state = stateString;
3454
3314
 
@@ -3457,12 +3317,12 @@ jQuery.extend( {
3457
3317
  }
3458
3318
 
3459
3319
  // deferred[ resolve | reject | notify ]
3460
- deferred[ tuple[ 0 ] ] = function() {
3461
- deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3320
+ deferred[ tuple[0] ] = function() {
3321
+ deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3462
3322
  return this;
3463
3323
  };
3464
- deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3465