js-rails 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -21,10 +21,10 @@ Add the necessary libraries to `app/assets/javascripts/application.js`:
21
21
 
22
22
  ## What's included?
23
23
 
24
- * jQuery 1.8.0 (jquery, jquery.min, jquery_ujs)
24
+ * jQuery 1.8.1 (jquery, jquery.min, jquery_ujs)
25
25
  * Zepto 1.0rc1 (zepto, zepto.min)
26
26
  * Underscore.js 1.3.3 (underscore, underscore.min)
27
- * Handlebars 1.0.0.beta.6 (handlebars)
27
+ * Handlebars 1.0.0.beta.6 (handlebars, handlebars.runtime)
28
28
  * Backbone 0.9.2 (backbone, backbone.min)
29
29
  * Ember 0.9.8.1 (ember, ember.min)
30
30
  * Angular 1.0.1 (angular)
@@ -1,6 +1,9 @@
1
1
  module Js
2
2
  module Rails
3
3
  class Engine < ::Rails::Engine
4
+ initializer 'js-rails' do |app|
5
+ app.middleware.use ::ActionDispatch::Static, "#{root}/vendor"
6
+ end
4
7
  end
5
8
  end
6
9
  end
@@ -1,5 +1,5 @@
1
1
  module Js
2
2
  module Rails
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -0,0 +1,223 @@
1
+ // lib/handlebars/base.js
2
+ var Handlebars = {};
3
+
4
+ Handlebars.VERSION = "1.0.beta.6";
5
+
6
+ Handlebars.helpers = {};
7
+ Handlebars.partials = {};
8
+
9
+ Handlebars.registerHelper = function(name, fn, inverse) {
10
+ if(inverse) { fn.not = inverse; }
11
+ this.helpers[name] = fn;
12
+ };
13
+
14
+ Handlebars.registerPartial = function(name, str) {
15
+ this.partials[name] = str;
16
+ };
17
+
18
+ Handlebars.registerHelper('helperMissing', function(arg) {
19
+ if(arguments.length === 2) {
20
+ return undefined;
21
+ } else {
22
+ throw new Error("Could not find property '" + arg + "'");
23
+ }
24
+ });
25
+
26
+ var toString = Object.prototype.toString, functionType = "[object Function]";
27
+
28
+ Handlebars.registerHelper('blockHelperMissing', function(context, options) {
29
+ var inverse = options.inverse || function() {}, fn = options.fn;
30
+
31
+
32
+ var ret = "";
33
+ var type = toString.call(context);
34
+
35
+ if(type === functionType) { context = context.call(this); }
36
+
37
+ if(context === true) {
38
+ return fn(this);
39
+ } else if(context === false || context == null) {
40
+ return inverse(this);
41
+ } else if(type === "[object Array]") {
42
+ if(context.length > 0) {
43
+ for(var i=0, j=context.length; i<j; i++) {
44
+ ret = ret + fn(context[i]);
45
+ }
46
+ } else {
47
+ ret = inverse(this);
48
+ }
49
+ return ret;
50
+ } else {
51
+ return fn(context);
52
+ }
53
+ });
54
+
55
+ Handlebars.registerHelper('each', function(context, options) {
56
+ var fn = options.fn, inverse = options.inverse;
57
+ var ret = "";
58
+
59
+ if(context && context.length > 0) {
60
+ for(var i=0, j=context.length; i<j; i++) {
61
+ ret = ret + fn(context[i]);
62
+ }
63
+ } else {
64
+ ret = inverse(this);
65
+ }
66
+ return ret;
67
+ });
68
+
69
+ Handlebars.registerHelper('if', function(context, options) {
70
+ var type = toString.call(context);
71
+ if(type === functionType) { context = context.call(this); }
72
+
73
+ if(!context || Handlebars.Utils.isEmpty(context)) {
74
+ return options.inverse(this);
75
+ } else {
76
+ return options.fn(this);
77
+ }
78
+ });
79
+
80
+ Handlebars.registerHelper('unless', function(context, options) {
81
+ var fn = options.fn, inverse = options.inverse;
82
+ options.fn = inverse;
83
+ options.inverse = fn;
84
+
85
+ return Handlebars.helpers['if'].call(this, context, options);
86
+ });
87
+
88
+ Handlebars.registerHelper('with', function(context, options) {
89
+ return options.fn(context);
90
+ });
91
+
92
+ Handlebars.registerHelper('log', function(context) {
93
+ Handlebars.log(context);
94
+ });
95
+ ;
96
+ // lib/handlebars/utils.js
97
+ Handlebars.Exception = function(message) {
98
+ var tmp = Error.prototype.constructor.apply(this, arguments);
99
+
100
+ for (var p in tmp) {
101
+ if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
102
+ }
103
+
104
+ this.message = tmp.message;
105
+ };
106
+ Handlebars.Exception.prototype = new Error;
107
+
108
+ // Build out our basic SafeString type
109
+ Handlebars.SafeString = function(string) {
110
+ this.string = string;
111
+ };
112
+ Handlebars.SafeString.prototype.toString = function() {
113
+ return this.string.toString();
114
+ };
115
+
116
+ (function() {
117
+ var escape = {
118
+ "<": "&lt;",
119
+ ">": "&gt;",
120
+ '"': "&quot;",
121
+ "'": "&#x27;",
122
+ "`": "&#x60;"
123
+ };
124
+
125
+ var badChars = /&(?!\w+;)|[<>"'`]/g;
126
+ var possible = /[&<>"'`]/;
127
+
128
+ var escapeChar = function(chr) {
129
+ return escape[chr] || "&amp;";
130
+ };
131
+
132
+ Handlebars.Utils = {
133
+ escapeExpression: function(string) {
134
+ // don't escape SafeStrings, since they're already safe
135
+ if (string instanceof Handlebars.SafeString) {
136
+ return string.toString();
137
+ } else if (string == null || string === false) {
138
+ return "";
139
+ }
140
+
141
+ if(!possible.test(string)) { return string; }
142
+ return string.replace(badChars, escapeChar);
143
+ },
144
+
145
+ isEmpty: function(value) {
146
+ if (typeof value === "undefined") {
147
+ return true;
148
+ } else if (value === null) {
149
+ return true;
150
+ } else if (value === false) {
151
+ return true;
152
+ } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
153
+ return true;
154
+ } else {
155
+ return false;
156
+ }
157
+ }
158
+ };
159
+ })();;
160
+ // lib/handlebars/runtime.js
161
+ Handlebars.VM = {
162
+ template: function(templateSpec) {
163
+ // Just add water
164
+ var container = {
165
+ escapeExpression: Handlebars.Utils.escapeExpression,
166
+ invokePartial: Handlebars.VM.invokePartial,
167
+ programs: [],
168
+ program: function(i, fn, data) {
169
+ var programWrapper = this.programs[i];
170
+ if(data) {
171
+ return Handlebars.VM.program(fn, data);
172
+ } else if(programWrapper) {
173
+ return programWrapper;
174
+ } else {
175
+ programWrapper = this.programs[i] = Handlebars.VM.program(fn);
176
+ return programWrapper;
177
+ }
178
+ },
179
+ programWithDepth: Handlebars.VM.programWithDepth,
180
+ noop: Handlebars.VM.noop
181
+ };
182
+
183
+ return function(context, options) {
184
+ options = options || {};
185
+ return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
186
+ };
187
+ },
188
+
189
+ programWithDepth: function(fn, data, $depth) {
190
+ var args = Array.prototype.slice.call(arguments, 2);
191
+
192
+ return function(context, options) {
193
+ options = options || {};
194
+
195
+ return fn.apply(this, [context, options.data || data].concat(args));
196
+ };
197
+ },
198
+ program: function(fn, data) {
199
+ return function(context, options) {
200
+ options = options || {};
201
+
202
+ return fn(context, options.data || data);
203
+ };
204
+ },
205
+ noop: function() { return ""; },
206
+ invokePartial: function(partial, name, context, helpers, partials, data) {
207
+ options = { helpers: helpers, partials: partials, data: data };
208
+
209
+ if(partial === undefined) {
210
+ throw new Handlebars.Exception("The partial " + name + " could not be found");
211
+ } else if(partial instanceof Function) {
212
+ return partial(context, options);
213
+ } else if (!Handlebars.compile) {
214
+ throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
215
+ } else {
216
+ partials[name] = Handlebars.compile(partial);
217
+ return partials[name](context, options);
218
+ }
219
+ }
220
+ };
221
+
222
+ Handlebars.template = Handlebars.VM.template;
223
+ ;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * jQuery JavaScript Library v1.8.0
2
+ * jQuery JavaScript Library v1.8.1
3
3
  * http://jquery.com/
4
4
  *
5
5
  * Includes Sizzle.js
@@ -9,7 +9,7 @@
9
9
  * Released under the MIT license
10
10
  * http://jquery.org/license
11
11
  *
12
- * Date: Thu Aug 09 2012 16:24:48 GMT-0400 (Eastern Daylight Time)
12
+ * Date: Thu Aug 30 2012 17:17:22 GMT-0400 (Eastern Daylight Time)
13
13
  */
14
14
  (function( window, undefined ) {
15
15
  var
@@ -51,8 +51,8 @@ var
51
51
  core_rnotwhite = /\S/,
52
52
  core_rspace = /\s+/,
53
53
 
54
- // IE doesn't match non-breaking spaces with \s
55
- rtrim = core_rnotwhite.test("\xA0") ? (/^[\s\xA0]+|[\s\xA0]+$/g) : /^\s+|\s+$/g,
54
+ // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
55
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
56
56
 
57
57
  // A simple way to check for HTML strings
58
58
  // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
@@ -186,7 +186,7 @@ jQuery.fn = jQuery.prototype = {
186
186
  selector: "",
187
187
 
188
188
  // The current version of jQuery being used
189
- jquery: "1.8.0",
189
+ jquery: "1.8.1",
190
190
 
191
191
  // The default length of a jQuery object is 0
192
192
  length: 0,
@@ -619,7 +619,7 @@ jQuery.extend({
619
619
  },
620
620
 
621
621
  // Use native String.trim function wherever possible
622
- trim: core_trim ?
622
+ trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
623
623
  function( text ) {
624
624
  return text == null ?
625
625
  "" :
@@ -844,9 +844,10 @@ jQuery.ready.promise = function( obj ) {
844
844
 
845
845
  readyList = jQuery.Deferred();
846
846
 
847
- // Catch cases where $(document).ready() is called after the
848
- // browser event has already occurred.
849
- if ( document.readyState === "complete" || ( document.readyState !== "loading" && document.addEventListener ) ) {
847
+ // Catch cases where $(document).ready() is called after the browser event has already occurred.
848
+ // we once tried to use readyState "interactive" here, but it caused issues like the one
849
+ // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
850
+ if ( document.readyState === "complete" ) {
850
851
  // Handle it asynchronously to allow scripts the opportunity to delay ready
851
852
  setTimeout( jQuery.ready, 1 );
852
853
 
@@ -997,9 +998,10 @@ jQuery.Callbacks = function( options ) {
997
998
  var start = list.length;
998
999
  (function add( args ) {
999
1000
  jQuery.each( args, function( _, arg ) {
1000
- if ( jQuery.isFunction( arg ) && ( !options.unique || !self.has( arg ) ) ) {
1001
+ var type = jQuery.type( arg );
1002
+ if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) {
1001
1003
  list.push( arg );
1002
- } else if ( arg && arg.length ) {
1004
+ } else if ( arg && arg.length && type !== "string" ) {
1003
1005
  // Inspect recursively
1004
1006
  add( arg );
1005
1007
  }
@@ -1452,10 +1454,8 @@ jQuery.support = (function() {
1452
1454
  support.boxSizing = ( div.offsetWidth === 4 );
1453
1455
  support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
1454
1456
 
1455
- // NOTE: To any future maintainer, window.getComputedStyle was used here
1456
- // instead of getComputedStyle because it gave a better gzip size.
1457
- // The difference between window.getComputedStyle and getComputedStyle is
1458
- // 7 bytes
1457
+ // NOTE: To any future maintainer, we've window.getComputedStyle
1458
+ // because jsdom on node.js will break without it.
1459
1459
  if ( window.getComputedStyle ) {
1460
1460
  support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
1461
1461
  support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
@@ -1505,7 +1505,7 @@ jQuery.support = (function() {
1505
1505
 
1506
1506
  return support;
1507
1507
  })();
1508
- var rbrace = /^(?:\{.*\}|\[.*\])$/,
1508
+ var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
1509
1509
  rmultiDash = /([A-Z])/g;
1510
1510
 
1511
1511
  jQuery.extend({
@@ -1868,6 +1868,7 @@ jQuery.extend({
1868
1868
  type = type || "fx";
1869
1869
 
1870
1870
  var queue = jQuery.queue( elem, type ),
1871
+ startLength = queue.length,
1871
1872
  fn = queue.shift(),
1872
1873
  hooks = jQuery._queueHooks( elem, type ),
1873
1874
  next = function() {
@@ -1877,6 +1878,7 @@ jQuery.extend({
1877
1878
  // If the fx queue is dequeued, always remove the progress sentinel
1878
1879
  if ( fn === "inprogress" ) {
1879
1880
  fn = queue.shift();
1881
+ startLength--;
1880
1882
  }
1881
1883
 
1882
1884
  if ( fn ) {
@@ -1891,7 +1893,8 @@ jQuery.extend({
1891
1893
  delete hooks.stop;
1892
1894
  fn.call( elem, next, hooks );
1893
1895
  }
1894
- if ( !queue.length && hooks ) {
1896
+
1897
+ if ( !startLength && hooks ) {
1895
1898
  hooks.empty.fire();
1896
1899
  }
1897
1900
  },
@@ -1977,7 +1980,8 @@ jQuery.fn.extend({
1977
1980
  type = type || "fx";
1978
1981
 
1979
1982
  while( i-- ) {
1980
- if ( (tmp = jQuery._data( elements[ i ], type + "queueHooks" )) && tmp.empty ) {
1983
+ tmp = jQuery._data( elements[ i ], type + "queueHooks" );
1984
+ if ( tmp && tmp.empty ) {
1981
1985
  count++;
1982
1986
  tmp.empty.add( resolve );
1983
1987
  }
@@ -2987,7 +2991,7 @@ jQuery.event = {
2987
2991
  // Make a writable jQuery.Event from the native event object
2988
2992
  event = jQuery.event.fix( event || window.event );
2989
2993
 
2990
- var i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related,
2994
+ var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
2991
2995
  handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
2992
2996
  delegateCount = handlers.delegateCount,
2993
2997
  args = [].slice.call( arguments ),
@@ -3008,23 +3012,18 @@ jQuery.event = {
3008
3012
  // Avoid non-left-click bubbling in Firefox (#3861)
3009
3013
  if ( delegateCount && !(event.button && event.type === "click") ) {
3010
3014
 
3011
- // Pregenerate a single jQuery object for reuse with .is()
3012
- jqcur = jQuery(this);
3013
- jqcur.context = this;
3014
-
3015
3015
  for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3016
3016
 
3017
- // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #xxxx)
3017
+ // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
3018
3018
  if ( cur.disabled !== true || event.type !== "click" ) {
3019
3019
  selMatch = {};
3020
3020
  matches = [];
3021
- jqcur[0] = cur;
3022
3021
  for ( i = 0; i < delegateCount; i++ ) {
3023
3022
  handleObj = handlers[ i ];
3024
3023
  sel = handleObj.selector;
3025
3024
 
3026
3025
  if ( selMatch[ sel ] === undefined ) {
3027
- selMatch[ sel ] = jqcur.is( sel );
3026
+ selMatch[ sel ] = jQuery( sel, this ).index( cur ) >= 0;
3028
3027
  }
3029
3028
  if ( selMatch[ sel ] ) {
3030
3029
  matches.push( handleObj );
@@ -3165,11 +3164,6 @@ jQuery.event = {
3165
3164
  },
3166
3165
 
3167
3166
  special: {
3168
- ready: {
3169
- // Make sure the ready event is setup
3170
- setup: jQuery.bindReady
3171
- },
3172
-
3173
3167
  load: {
3174
3168
  // Prevent triggered image.load events from bubbling to window.load
3175
3169
  noBubble: true
@@ -3458,7 +3452,7 @@ if ( !jQuery.support.changeBubbles ) {
3458
3452
  teardown: function() {
3459
3453
  jQuery.event.remove( this, "._change" );
3460
3454
 
3461
- return rformElems.test( this.nodeName );
3455
+ return !rformElems.test( this.nodeName );
3462
3456
  }
3463
3457
  };
3464
3458
  }
@@ -3676,23 +3670,51 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
3676
3670
  */
3677
3671
  (function( window, undefined ) {
3678
3672
 
3679
- var cachedruns,
3680
- dirruns,
3681
- sortOrder,
3682
- siblingCheck,
3673
+ var dirruns,
3674
+ cachedruns,
3683
3675
  assertGetIdNotName,
3676
+ Expr,
3677
+ getText,
3678
+ isXML,
3679
+ contains,
3680
+ compile,
3681
+ sortOrder,
3682
+ hasDuplicate,
3683
+
3684
+ baseHasDuplicate = true,
3685
+ strundefined = "undefined",
3686
+
3687
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
3684
3688
 
3685
3689
  document = window.document,
3686
3690
  docElem = document.documentElement,
3687
-
3688
- strundefined = "undefined",
3689
- hasDuplicate = false,
3690
- baseHasDuplicate = true,
3691
3691
  done = 0,
3692
3692
  slice = [].slice,
3693
3693
  push = [].push,
3694
3694
 
3695
- expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
3695
+ // Augment a function for special use by Sizzle
3696
+ markFunction = function( fn, value ) {
3697
+ fn[ expando ] = value || true;
3698
+ return fn;
3699
+ },
3700
+
3701
+ createCache = function() {
3702
+ var cache = {},
3703
+ keys = [];
3704
+
3705
+ return markFunction(function( key, value ) {
3706
+ // Only keep the most recent entries
3707
+ if ( keys.push( key ) > Expr.cacheLength ) {
3708
+ delete cache[ keys.shift() ];
3709
+ }
3710
+
3711
+ return (cache[ key ] = value);
3712
+ }, cache );
3713
+ },
3714
+
3715
+ classCache = createCache(),
3716
+ tokenCache = createCache(),
3717
+ compilerCache = createCache(),
3696
3718
 
3697
3719
  // Regex
3698
3720
 
@@ -3710,29 +3732,28 @@ var cachedruns,
3710
3732
  operators = "([*^$|!~]?=)",
3711
3733
  attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
3712
3734
  "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
3713
- pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",
3714
- pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",
3715
- combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*",
3716
- groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+",
3717
-
3718
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
3719
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
3720
3735
 
3721
- rcombinators = new RegExp( "^" + combinators ),
3736
+ // Prefer arguments not in parens/brackets,
3737
+ // then attribute selectors and non-pseudos (denoted by :),
3738
+ // then anything else
3739
+ // These preferences are here to reduce the number of selectors
3740
+ // needing tokenize in the PSEUDO preFilter
3741
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
3722
3742
 
3723
- // All simple (non-comma) selectors, excluding insignifant trailing whitespace
3724
- rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ),
3743
+ // For matchExpr.POS and matchExpr.needsContext
3744
+ pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)",
3725
3745
 
3726
- // A selector, or everything after leading whitespace
3727
- // Optionally followed in either case by a ")" for terminating sub-selectors
3728
- rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ),
3746
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
3747
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
3729
3748
 
3730
- // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive
3731
- rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ),
3749
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
3750
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
3751
+ rpseudo = new RegExp( pseudos ),
3732
3752
 
3733
3753
  // Easily-parseable/retrievable ID or TAG or CLASS selectors
3734
3754
  rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
3735
3755
 
3756
+ rnot = /^:not/,
3736
3757
  rsibling = /[\x20\t\r\n\f]*[+~]/,
3737
3758
  rendsWithNot = /:not\($/,
3738
3759
 
@@ -3745,7 +3766,7 @@ var cachedruns,
3745
3766
  "ID": new RegExp( "^#(" + characterEncoding + ")" ),
3746
3767
  "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
3747
3768
  "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
3748
- "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ),
3769
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
3749
3770
  "ATTR": new RegExp( "^" + attributes ),
3750
3771
  "PSEUDO": new RegExp( "^" + pseudos ),
3751
3772
  "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +
@@ -3756,45 +3777,35 @@ var cachedruns,
3756
3777
  "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
3757
3778
  },
3758
3779
 
3759
- classCache = {},
3760
- cachedClasses = [],
3761
- compilerCache = {},
3762
- cachedSelectors = [],
3763
-
3764
- // Mark a function for use in filtering
3765
- markFunction = function( fn ) {
3766
- fn.sizzleFilter = true;
3767
- return fn;
3768
- },
3769
-
3770
- // Returns a function to use in pseudos for input types
3771
- createInputFunction = function( type ) {
3772
- return function( elem ) {
3773
- // Check the input's nodeName and type
3774
- return elem.nodeName.toLowerCase() === "input" && elem.type === type;
3775
- };
3776
- },
3777
-
3778
- // Returns a function to use in pseudos for buttons
3779
- createButtonFunction = function( type ) {
3780
- return function( elem ) {
3781
- var name = elem.nodeName.toLowerCase();
3782
- return (name === "input" || name === "button") && elem.type === type;
3783
- };
3784
- },
3780
+ // Support
3785
3781
 
3786
3782
  // Used for testing something on an element
3787
3783
  assert = function( fn ) {
3788
- var pass = false,
3789
- div = document.createElement("div");
3784
+ var div = document.createElement("div");
3785
+
3790
3786
  try {
3791
- pass = fn( div );
3792
- } catch (e) {}
3793
- // release memory in IE
3794
- div = null;
3795
- return pass;
3787
+ return fn( div );
3788
+ } catch (e) {
3789
+ return false;
3790
+ } finally {
3791
+ // release memory in IE
3792
+ div = null;
3793
+ }
3796
3794
  },
3797
3795
 
3796
+ // Check if getElementsByTagName("*") returns only elements
3797
+ assertTagNameNoComments = assert(function( div ) {
3798
+ div.appendChild( document.createComment("") );
3799
+ return !div.getElementsByTagName("*").length;
3800
+ }),
3801
+
3802
+ // Check if getAttribute returns normalized href attributes
3803
+ assertHrefNotNormalized = assert(function( div ) {
3804
+ div.innerHTML = "<a href='#'></a>";
3805
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
3806
+ div.firstChild.getAttribute("href") === "#";
3807
+ }),
3808
+
3798
3809
  // Check if attributes should be retrieved by attribute nodes
3799
3810
  assertAttributes = assert(function( div ) {
3800
3811
  div.innerHTML = "<select></select>";
@@ -3803,6 +3814,19 @@ var cachedruns,
3803
3814
  return type !== "boolean" && type !== "string";
3804
3815
  }),
3805
3816
 
3817
+ // Check if getElementsByClassName can be trusted
3818
+ assertUsableClassName = assert(function( div ) {
3819
+ // Opera can't find a second classname (in 9.6)
3820
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
3821
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
3822
+ return false;
3823
+ }
3824
+
3825
+ // Safari 3.2 caches class attributes and doesn't catch changes
3826
+ div.lastChild.className = "e";
3827
+ return div.getElementsByClassName("e").length === 2;
3828
+ }),
3829
+
3806
3830
  // Check if getElementById returns elements by name
3807
3831
  // Check if getElementsByName privileges form controls or returns elements by ID
3808
3832
  assertUsableName = assert(function( div ) {
@@ -3814,45 +3838,31 @@ var cachedruns,
3814
3838
  // Test
3815
3839
  var pass = document.getElementsByName &&
3816
3840
  // buggy browsers will return fewer than the correct 2
3817
- document.getElementsByName( expando ).length ===
3841
+ document.getElementsByName( expando ).length === 2 +
3818
3842
  // buggy browsers will return more than the correct 0
3819
- 2 + document.getElementsByName( expando + 0 ).length;
3843
+ document.getElementsByName( expando + 0 ).length;
3820
3844
  assertGetIdNotName = !document.getElementById( expando );
3821
3845
 
3822
3846
  // Cleanup
3823
3847
  docElem.removeChild( div );
3824
3848
 
3825
3849
  return pass;
3826
- }),
3827
-
3828
- // Check if the browser returns only elements
3829
- // when doing getElementsByTagName("*")
3830
- assertTagNameNoComments = assert(function( div ) {
3831
- div.appendChild( document.createComment("") );
3832
- return div.getElementsByTagName("*").length === 0;
3833
- }),
3834
-
3835
- // Check if getAttribute returns normalized href attributes
3836
- assertHrefNotNormalized = assert(function( div ) {
3837
- div.innerHTML = "<a href='#'></a>";
3838
- return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
3839
- div.firstChild.getAttribute("href") === "#";
3840
- }),
3850
+ });
3841
3851
 
3842
- // Check if getElementsByClassName can be trusted
3843
- assertUsableClassName = assert(function( div ) {
3844
- // Opera can't find a second classname (in 9.6)
3845
- div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
3846
- if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
3847
- return false;
3852
+ // If slice is not available, provide a backup
3853
+ try {
3854
+ slice.call( docElem.childNodes, 0 )[0].nodeType;
3855
+ } catch ( e ) {
3856
+ slice = function( i ) {
3857
+ var elem, results = [];
3858
+ for ( ; (elem = this[i]); i++ ) {
3859
+ results.push( elem );
3848
3860
  }
3861
+ return results;
3862
+ };
3863
+ }
3849
3864
 
3850
- // Safari caches class attributes, doesn't catch changes (in 3.2)
3851
- div.lastChild.className = "e";
3852
- return div.getElementsByClassName("e").length !== 1;
3853
- });
3854
-
3855
- var Sizzle = function( selector, context, results, seed ) {
3865
+ function Sizzle( selector, context, results, seed ) {
3856
3866
  results = results || [];
3857
3867
  context = context || document;
3858
3868
  var match, elem, xml, m,
@@ -3910,21 +3920,143 @@ var Sizzle = function( selector, context, results, seed ) {
3910
3920
 
3911
3921
  // All others
3912
3922
  return select( selector, context, results, seed, xml );
3923
+ }
3924
+
3925
+ Sizzle.matches = function( expr, elements ) {
3926
+ return Sizzle( expr, null, null, elements );
3913
3927
  };
3914
3928
 
3915
- var Expr = Sizzle.selectors = {
3929
+ Sizzle.matchesSelector = function( elem, expr ) {
3930
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;
3931
+ };
3916
3932
 
3917
- // Can be adjusted by the user
3918
- cacheLength: 50,
3933
+ // Returns a function to use in pseudos for input types
3934
+ function createInputPseudo( type ) {
3935
+ return function( elem ) {
3936
+ var name = elem.nodeName.toLowerCase();
3937
+ return name === "input" && elem.type === type;
3938
+ };
3939
+ }
3919
3940
 
3920
- match: matchExpr,
3941
+ // Returns a function to use in pseudos for buttons
3942
+ function createButtonPseudo( type ) {
3943
+ return function( elem ) {
3944
+ var name = elem.nodeName.toLowerCase();
3945
+ return (name === "input" || name === "button") && elem.type === type;
3946
+ };
3947
+ }
3921
3948
 
3922
- order: [ "ID", "TAG" ],
3949
+ /**
3950
+ * Utility function for retrieving the text value of an array of DOM nodes
3951
+ * @param {Array|Element} elem
3952
+ */
3953
+ getText = Sizzle.getText = function( elem ) {
3954
+ var node,
3955
+ ret = "",
3956
+ i = 0,
3957
+ nodeType = elem.nodeType;
3923
3958
 
3924
- attrHandle: {},
3959
+ if ( nodeType ) {
3960
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
3961
+ // Use textContent for elements
3962
+ // innerText usage removed for consistency of new lines (see #11153)
3963
+ if ( typeof elem.textContent === "string" ) {
3964
+ return elem.textContent;
3965
+ } else {
3966
+ // Traverse its children
3967
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
3968
+ ret += getText( elem );
3969
+ }
3970
+ }
3971
+ } else if ( nodeType === 3 || nodeType === 4 ) {
3972
+ return elem.nodeValue;
3973
+ }
3974
+ // Do not include comment or processing instruction nodes
3975
+ } else {
3976
+
3977
+ // If no nodeType, this is expected to be an array
3978
+ for ( ; (node = elem[i]); i++ ) {
3979
+ // Do not traverse comment nodes
3980
+ ret += getText( node );
3981
+ }
3982
+ }
3983
+ return ret;
3984
+ };
3985
+
3986
+ isXML = Sizzle.isXML = function isXML( elem ) {
3987
+ // documentElement is verified for cases where it doesn't yet exist
3988
+ // (such as loading iframes in IE - #4833)
3989
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
3990
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
3991
+ };
3992
+
3993
+ // Element contains another
3994
+ contains = Sizzle.contains = docElem.contains ?
3995
+ function( a, b ) {
3996
+ var adown = a.nodeType === 9 ? a.documentElement : a,
3997
+ bup = b && b.parentNode;
3998
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
3999
+ } :
4000
+ docElem.compareDocumentPosition ?
4001
+ function( a, b ) {
4002
+ return b && !!( a.compareDocumentPosition( b ) & 16 );
4003
+ } :
4004
+ function( a, b ) {
4005
+ while ( (b = b.parentNode) ) {
4006
+ if ( b === a ) {
4007
+ return true;
4008
+ }
4009
+ }
4010
+ return false;
4011
+ };
4012
+
4013
+ Sizzle.attr = function( elem, name ) {
4014
+ var attr,
4015
+ xml = isXML( elem );
4016
+
4017
+ if ( !xml ) {
4018
+ name = name.toLowerCase();
4019
+ }
4020
+ if ( Expr.attrHandle[ name ] ) {
4021
+ return Expr.attrHandle[ name ]( elem );
4022
+ }
4023
+ if ( assertAttributes || xml ) {
4024
+ return elem.getAttribute( name );
4025
+ }
4026
+ attr = elem.getAttributeNode( name );
4027
+ return attr ?
4028
+ typeof elem[ name ] === "boolean" ?
4029
+ elem[ name ] ? name : null :
4030
+ attr.specified ? attr.value : null :
4031
+ null;
4032
+ };
4033
+
4034
+ Expr = Sizzle.selectors = {
4035
+
4036
+ // Can be adjusted by the user
4037
+ cacheLength: 50,
3925
4038
 
3926
4039
  createPseudo: markFunction,
3927
4040
 
4041
+ match: matchExpr,
4042
+
4043
+ order: new RegExp( "ID|TAG" +
4044
+ (assertUsableName ? "|NAME" : "") +
4045
+ (assertUsableClassName ? "|CLASS" : "")
4046
+ ),
4047
+
4048
+ // IE6/7 return a modified href
4049
+ attrHandle: assertHrefNotNormalized ?
4050
+ {} :
4051
+ {
4052
+ "href": function( elem ) {
4053
+ return elem.getAttribute( "href", 2 );
4054
+ },
4055
+ "type": function( elem ) {
4056
+ return elem.getAttribute("type");
4057
+ }
4058
+ },
4059
+
3928
4060
  find: {
3929
4061
  "ID": assertGetIdNotName ?
3930
4062
  function( id, context, xml ) {
@@ -3971,7 +4103,19 @@ var Expr = Sizzle.selectors = {
3971
4103
  return tmp;
3972
4104
  }
3973
4105
  return results;
4106
+ },
4107
+
4108
+ "NAME": function( tag, context ) {
4109
+ if ( typeof context.getElementsByName !== strundefined ) {
4110
+ return context.getElementsByName( name );
3974
4111
  }
4112
+ },
4113
+
4114
+ "CLASS": function( className, context, xml ) {
4115
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
4116
+ return context.getElementsByClassName( className );
4117
+ }
4118
+ }
3975
4119
  },
3976
4120
 
3977
4121
  relative: {
@@ -4026,25 +4170,31 @@ var Expr = Sizzle.selectors = {
4026
4170
  return match;
4027
4171
  },
4028
4172
 
4029
- "PSEUDO": function( match ) {
4030
- var argument,
4031
- unquoted = match[4];
4032
-
4173
+ "PSEUDO": function( match, context, xml ) {
4174
+ var unquoted, excess;
4033
4175
  if ( matchExpr["CHILD"].test( match[0] ) ) {
4034
4176
  return null;
4035
4177
  }
4036
4178
 
4037
- // Relinquish our claim on characters in `unquoted` from a closing parenthesis on
4038
- if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) {
4039
-
4040
- match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 );
4041
- unquoted = argument[0].slice( 0, -1 );
4179
+ if ( match[3] ) {
4180
+ match[2] = match[3];
4181
+ } else if ( (unquoted = match[4]) ) {
4182
+ // Only check arguments that contain a pseudo
4183
+ if ( rpseudo.test(unquoted) &&
4184
+ // Get excess from tokenize (recursively)
4185
+ (excess = tokenize( unquoted, context, xml, true )) &&
4186
+ // advance to the next closing parenthesis
4187
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
4188
+
4189
+ // excess is a negative index
4190
+ unquoted = unquoted.slice( 0, excess );
4191
+ match[0] = match[0].slice( 0, excess );
4192
+ }
4193
+ match[2] = unquoted;
4042
4194
  }
4043
4195
 
4044
- // Quoted or unquoted, we have the full argument
4045
4196
  // Return only captures needed by the pseudo filter method (type and argument)
4046
- match.splice( 2, 3, unquoted || match[3] );
4047
- return match;
4197
+ return match.slice( 0, 3 );
4048
4198
  }
4049
4199
  },
4050
4200
 
@@ -4076,14 +4226,9 @@ var Expr = Sizzle.selectors = {
4076
4226
  },
4077
4227
 
4078
4228
  "CLASS": function( className ) {
4079
- var pattern = classCache[ className ];
4229
+ var pattern = classCache[ expando ][ className ];
4080
4230
  if ( !pattern ) {
4081
- pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" );
4082
- cachedClasses.push( className );
4083
- // Avoid too large of a cache
4084
- if ( cachedClasses.length > Expr.cacheLength ) {
4085
- delete classCache[ cachedClasses.shift() ];
4086
- }
4231
+ pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );
4087
4232
  }
4088
4233
  return function( elem ) {
4089
4234
  return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
@@ -4199,16 +4344,23 @@ var Expr = Sizzle.selectors = {
4199
4344
  // pseudo-class names are case-insensitive
4200
4345
  // http://www.w3.org/TR/selectors/#pseudo-classes
4201
4346
  // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
4202
- var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
4347
+ var args,
4348
+ fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];
4203
4349
 
4204
4350
  if ( !fn ) {
4205
4351
  Sizzle.error( "unsupported pseudo: " + pseudo );
4206
4352
  }
4207
4353
 
4208
- // The user may set fn.sizzleFilter to indicate
4209
- // that arguments are needed to create the filter function
4354
+ // The user may use createPseudo to indicate that
4355
+ // arguments are needed to create the filter function
4210
4356
  // just as Sizzle does
4211
- if ( !fn.sizzleFilter ) {
4357
+ if ( !fn[ expando ] ) {
4358
+ if ( fn.length > 1 ) {
4359
+ args = [ pseudo, pseudo, "", argument ];
4360
+ return function( elem ) {
4361
+ return fn( elem, 0, args );
4362
+ };
4363
+ }
4212
4364
  return fn;
4213
4365
  }
4214
4366
 
@@ -4299,14 +4451,14 @@ var Expr = Sizzle.selectors = {
4299
4451
  },
4300
4452
 
4301
4453
  // Input types
4302
- "radio": createInputFunction("radio"),
4303
- "checkbox": createInputFunction("checkbox"),
4304
- "file": createInputFunction("file"),
4305
- "password": createInputFunction("password"),
4306
- "image": createInputFunction("image"),
4454
+ "radio": createInputPseudo("radio"),
4455
+ "checkbox": createInputPseudo("checkbox"),
4456
+ "file": createInputPseudo("file"),
4457
+ "password": createInputPseudo("password"),
4458
+ "image": createInputPseudo("image"),
4307
4459
 
4308
- "submit": createButtonFunction("submit"),
4309
- "reset": createButtonFunction("reset"),
4460
+ "submit": createButtonPseudo("submit"),
4461
+ "reset": createButtonPseudo("reset"),
4310
4462
 
4311
4463
  "button": function( elem ) {
4312
4464
  var name = elem.nodeName.toLowerCase();
@@ -4354,175 +4506,44 @@ var Expr = Sizzle.selectors = {
4354
4506
  for ( ; i < len; i = i + 2 ) {
4355
4507
  results.push( elements[i] );
4356
4508
  }
4357
- return results;
4358
- },
4359
-
4360
- "lt": function( elements, argument, not ) {
4361
- return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
4362
- },
4363
-
4364
- "gt": function( elements, argument, not ) {
4365
- return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
4366
- },
4367
-
4368
- "eq": function( elements, argument, not ) {
4369
- var elem = elements.splice( +argument, 1 );
4370
- return not ? elements : elem;
4371
- }
4372
- }
4373
- };
4374
-
4375
- // Deprecated
4376
- Expr.setFilters["nth"] = Expr.setFilters["eq"];
4377
-
4378
- // Back-compat
4379
- Expr.filters = Expr.pseudos;
4380
-
4381
- // IE6/7 return a modified href
4382
- if ( !assertHrefNotNormalized ) {
4383
- Expr.attrHandle = {
4384
- "href": function( elem ) {
4385
- return elem.getAttribute( "href", 2 );
4386
- },
4387
- "type": function( elem ) {
4388
- return elem.getAttribute("type");
4389
- }
4390
- };
4391
- }
4392
-
4393
- // Add getElementsByName if usable
4394
- if ( assertUsableName ) {
4395
- Expr.order.push("NAME");
4396
- Expr.find["NAME"] = function( name, context ) {
4397
- if ( typeof context.getElementsByName !== strundefined ) {
4398
- return context.getElementsByName( name );
4399
- }
4400
- };
4401
- }
4402
-
4403
- // Add getElementsByClassName if usable
4404
- if ( assertUsableClassName ) {
4405
- Expr.order.splice( 1, 0, "CLASS" );
4406
- Expr.find["CLASS"] = function( className, context, xml ) {
4407
- if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
4408
- return context.getElementsByClassName( className );
4409
- }
4410
- };
4411
- }
4412
-
4413
- // If slice is not available, provide a backup
4414
- try {
4415
- slice.call( docElem.childNodes, 0 )[0].nodeType;
4416
- } catch ( e ) {
4417
- slice = function( i ) {
4418
- var elem, results = [];
4419
- for ( ; (elem = this[i]); i++ ) {
4420
- results.push( elem );
4421
- }
4422
- return results;
4423
- };
4424
- }
4425
-
4426
- var isXML = Sizzle.isXML = function( elem ) {
4427
- // documentElement is verified for cases where it doesn't yet exist
4428
- // (such as loading iframes in IE - #4833)
4429
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4430
- return documentElement ? documentElement.nodeName !== "HTML" : false;
4431
- };
4432
-
4433
- // Element contains another
4434
- var contains = Sizzle.contains = docElem.compareDocumentPosition ?
4435
- function( a, b ) {
4436
- return !!( a.compareDocumentPosition( b ) & 16 );
4437
- } :
4438
- docElem.contains ?
4439
- function( a, b ) {
4440
- var adown = a.nodeType === 9 ? a.documentElement : a,
4441
- bup = b.parentNode;
4442
- return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
4443
- } :
4444
- function( a, b ) {
4445
- while ( (b = b.parentNode) ) {
4446
- if ( b === a ) {
4447
- return true;
4448
- }
4449
- }
4450
- return false;
4451
- };
4452
-
4453
- /**
4454
- * Utility function for retrieving the text value of an array of DOM nodes
4455
- * @param {Array|Element} elem
4456
- */
4457
- var getText = Sizzle.getText = function( elem ) {
4458
- var node,
4459
- ret = "",
4460
- i = 0,
4461
- nodeType = elem.nodeType;
4462
-
4463
- if ( nodeType ) {
4464
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
4465
- // Use textContent for elements
4466
- // innerText usage removed for consistency of new lines (see #11153)
4467
- if ( typeof elem.textContent === "string" ) {
4468
- return elem.textContent;
4469
- } else {
4470
- // Traverse its children
4471
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4472
- ret += getText( elem );
4473
- }
4474
- }
4475
- } else if ( nodeType === 3 || nodeType === 4 ) {
4476
- return elem.nodeValue;
4477
- }
4478
- // Do not include comment or processing instruction nodes
4479
- } else {
4509
+ return results;
4510
+ },
4480
4511
 
4481
- // If no nodeType, this is expected to be an array
4482
- for ( ; (node = elem[i]); i++ ) {
4483
- // Do not traverse comment nodes
4484
- ret += getText( node );
4512
+ "lt": function( elements, argument, not ) {
4513
+ return not ? elements.slice( +argument ) : elements.slice( 0, +argument );
4514
+ },
4515
+
4516
+ "gt": function( elements, argument, not ) {
4517
+ return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );
4518
+ },
4519
+
4520
+ "eq": function( elements, argument, not ) {
4521
+ var elem = elements.splice( +argument, 1 );
4522
+ return not ? elements : elem;
4485
4523
  }
4486
4524
  }
4487
- return ret;
4488
4525
  };
4489
4526
 
4490
- Sizzle.attr = function( elem, name ) {
4491
- var attr,
4492
- xml = isXML( elem );
4493
-
4494
- if ( !xml ) {
4495
- name = name.toLowerCase();
4496
- }
4497
- if ( Expr.attrHandle[ name ] ) {
4498
- return Expr.attrHandle[ name ]( elem );
4527
+ function siblingCheck( a, b, ret ) {
4528
+ if ( a === b ) {
4529
+ return ret;
4499
4530
  }
4500
- if ( assertAttributes || xml ) {
4501
- return elem.getAttribute( name );
4502
- }
4503
- attr = elem.getAttributeNode( name );
4504
- return attr ?
4505
- typeof elem[ name ] === "boolean" ?
4506
- elem[ name ] ? name : null :
4507
- attr.specified ? attr.value : null :
4508
- null;
4509
- };
4510
4531
 
4511
- Sizzle.error = function( msg ) {
4512
- throw new Error( "Syntax error, unrecognized expression: " + msg );
4513
- };
4532
+ var cur = a.nextSibling;
4533
+
4534
+ while ( cur ) {
4535
+ if ( cur === b ) {
4536
+ return -1;
4537
+ }
4514
4538
 
4515
- // Check if the JavaScript engine is using some sort of
4516
- // optimization where it does not always call our comparision
4517
- // function. If that is the case, discard the hasDuplicate value.
4518
- // Thus far that includes Google Chrome.
4519
- [0, 0].sort(function() {
4520
- return (baseHasDuplicate = 0);
4521
- });
4539
+ cur = cur.nextSibling;
4540
+ }
4522
4541
 
4542
+ return 1;
4543
+ }
4523
4544
 
4524
- if ( docElem.compareDocumentPosition ) {
4525
- sortOrder = function( a, b ) {
4545
+ sortOrder = docElem.compareDocumentPosition ?
4546
+ function( a, b ) {
4526
4547
  if ( a === b ) {
4527
4548
  hasDuplicate = true;
4528
4549
  return 0;
@@ -4532,10 +4553,8 @@ if ( docElem.compareDocumentPosition ) {
4532
4553
  a.compareDocumentPosition :
4533
4554
  a.compareDocumentPosition(b) & 4
4534
4555
  ) ? -1 : 1;
4535
- };
4536
-
4537
- } else {
4538
- sortOrder = function( a, b ) {
4556
+ } :
4557
+ function( a, b ) {
4539
4558
  // The nodes are identical, we can exit early
4540
4559
  if ( a === b ) {
4541
4560
  hasDuplicate = true;
@@ -4595,39 +4614,23 @@ if ( docElem.compareDocumentPosition ) {
4595
4614
  siblingCheck( ap[i], b, 1 );
4596
4615
  };
4597
4616
 
4598
- siblingCheck = function( a, b, ret ) {
4599
- if ( a === b ) {
4600
- return ret;
4601
- }
4602
-
4603
- var cur = a.nextSibling;
4604
-
4605
- while ( cur ) {
4606
- if ( cur === b ) {
4607
- return -1;
4608
- }
4609
-
4610
- cur = cur.nextSibling;
4611
- }
4612
-
4613
- return 1;
4614
- };
4615
- }
4617
+ // Always assume the presence of duplicates if sort doesn't
4618
+ // pass them to our comparison function (as in Google Chrome).
4619
+ [0, 0].sort( sortOrder );
4620
+ baseHasDuplicate = !hasDuplicate;
4616
4621
 
4617
4622
  // Document sorting and removing duplicates
4618
4623
  Sizzle.uniqueSort = function( results ) {
4619
4624
  var elem,
4620
4625
  i = 1;
4621
4626
 
4622
- if ( sortOrder ) {
4623
- hasDuplicate = baseHasDuplicate;
4624
- results.sort( sortOrder );
4627
+ hasDuplicate = baseHasDuplicate;
4628
+ results.sort( sortOrder );
4625
4629
 
4626
- if ( hasDuplicate ) {
4627
- for ( ; (elem = results[i]); i++ ) {
4628
- if ( elem === results[ i - 1 ] ) {
4629
- results.splice( i--, 1 );
4630
- }
4630
+ if ( hasDuplicate ) {
4631
+ for ( ; (elem = results[i]); i++ ) {
4632
+ if ( elem === results[ i - 1 ] ) {
4633
+ results.splice( i--, 1 );
4631
4634
  }
4632
4635
  }
4633
4636
  }
@@ -4635,160 +4638,99 @@ Sizzle.uniqueSort = function( results ) {
4635
4638
  return results;
4636
4639
  };
4637
4640
 
4638
- function multipleContexts( selector, contexts, results, seed ) {
4639
- var i = 0,
4640
- len = contexts.length;
4641
- for ( ; i < len; i++ ) {
4642
- Sizzle( selector, contexts[i], results, seed );
4643
- }
4644
- }
4645
-
4646
- function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
4647
- var results,
4648
- fn = Expr.setFilters[ posfilter.toLowerCase() ];
4649
-
4650
- if ( !fn ) {
4651
- Sizzle.error( posfilter );
4652
- }
4641
+ Sizzle.error = function( msg ) {
4642
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
4643
+ };
4653
4644
 
4654
- if ( selector || !(results = seed) ) {
4655
- multipleContexts( selector || "*", contexts, (results = []), seed );
4645
+ function tokenize( selector, context, xml, parseOnly ) {
4646
+ var matched, match, tokens, type,
4647
+ soFar, groups, group, i,
4648
+ preFilters, filters,
4649
+ checkContext = !xml && context !== document,
4650
+ // Token cache should maintain spaces
4651
+ key = ( checkContext ? "<s>" : "" ) + selector.replace( rtrim, "$1<s>" ),
4652
+ cached = tokenCache[ expando ][ key ];
4653
+
4654
+ if ( cached ) {
4655
+ return parseOnly ? 0 : slice.call( cached, 0 );
4656
4656
  }
4657
4657
 
4658
- return results.length > 0 ? fn( results, argument, not ) : [];
4659
- }
4660
-
4661
- function handlePOS( selector, context, results, seed, groups ) {
4662
- var match, not, anchor, ret, elements, currentContexts, part, lastIndex,
4663
- i = 0,
4664
- len = groups.length,
4665
- rpos = matchExpr["POS"],
4666
- // This is generated here in case matchExpr["POS"] is extended
4667
- rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
4668
- // This is for making sure non-participating
4669
- // matching groups are represented cross-browser (IE6-8)
4670
- setUndefined = function() {
4671
- var i = 1,
4672
- len = arguments.length - 2;
4673
- for ( ; i < len; i++ ) {
4674
- if ( arguments[i] === undefined ) {
4675
- match[i] = undefined;
4676
- }
4677
- }
4678
- };
4679
-
4680
- for ( ; i < len; i++ ) {
4681
- // Reset regex index to 0
4682
- rpos.exec("");
4683
- selector = groups[i];
4684
- ret = [];
4685
- anchor = 0;
4686
- elements = seed;
4687
- while ( (match = rpos.exec( selector )) ) {
4688
- lastIndex = rpos.lastIndex = match.index + match[0].length;
4689
- if ( lastIndex > anchor ) {
4690
- part = selector.slice( anchor, match.index );
4691
- anchor = lastIndex;
4692
- currentContexts = [ context ];
4693
-
4694
- if ( rcombinators.test(part) ) {
4695
- if ( elements ) {
4696
- currentContexts = elements;
4697
- }
4698
- elements = seed;
4699
- }
4658
+ soFar = selector;
4659
+ groups = [];
4660
+ i = 0;
4661
+ preFilters = Expr.preFilter;
4662
+ filters = Expr.filter;
4700
4663
 
4701
- if ( (not = rendsWithNot.test( part )) ) {
4702
- part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
4703
- }
4664
+ while ( soFar ) {
4704
4665
 
4705
- if ( match.length > 1 ) {
4706
- match[0].replace( rposgroups, setUndefined );
4707
- }
4708
- elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
4666
+ // Comma and first run
4667
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
4668
+ if ( match ) {
4669
+ soFar = soFar.slice( match[0].length );
4670
+ tokens.selector = group;
4709
4671
  }
4710
- }
4711
-
4712
- if ( elements ) {
4713
- ret = ret.concat( elements );
4672
+ groups.push( tokens = [] );
4673
+ group = "";
4714
4674
 
4715
- if ( (part = selector.slice( anchor )) && part !== ")" ) {
4716
- if ( rcombinators.test(part) ) {
4717
- multipleContexts( part, ret, results, seed );
4718
- } else {
4719
- Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
4720
- }
4721
- } else {
4722
- push.apply( results, ret );
4675
+ // Need to make sure we're within a narrower context if necessary
4676
+ // Adding a descendant combinator will generate what is needed
4677
+ if ( checkContext ) {
4678
+ soFar = " " + soFar;
4723
4679
  }
4724
- } else {
4725
- Sizzle( selector, context, results, seed );
4726
4680
  }
4727
- }
4728
-
4729
- // Do not sort if this is a single filter
4730
- return len === 1 ? results : Sizzle.uniqueSort( results );
4731
- }
4732
-
4733
- function tokenize( selector, context, xml ) {
4734
- var tokens, soFar, type,
4735
- groups = [],
4736
- i = 0,
4737
-
4738
- // Catch obvious selector issues: terminal ")"; nonempty fallback match
4739
- // rselector never fails to match *something*
4740
- match = rselector.exec( selector ),
4741
- matched = !match.pop() && !match.pop(),
4742
- selectorGroups = matched && selector.match( rgroups ) || [""],
4743
4681
 
4744
- preFilters = Expr.preFilter,
4745
- filters = Expr.filter,
4746
- checkContext = !xml && context !== document;
4682
+ matched = false;
4747
4683
 
4748
- for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) {
4749
- groups.push( tokens = [] );
4684
+ // Combinators
4685
+ if ( (match = rcombinators.exec( soFar )) ) {
4686
+ group += match[0];
4687
+ soFar = soFar.slice( match[0].length );
4750
4688
 
4751
- // Need to make sure we're within a narrower context if necessary
4752
- // Adding a descendant combinator will generate what is needed
4753
- if ( checkContext ) {
4754
- soFar = " " + soFar;
4689
+ // Cast descendant combinators to space
4690
+ matched = tokens.push({
4691
+ part: match.pop().replace( rtrim, " " ),
4692
+ string: match[0],
4693
+ captures: match
4694
+ });
4755
4695
  }
4756
4696
 
4757
- while ( soFar ) {
4758
- matched = false;
4697
+ // Filters
4698
+ for ( type in filters ) {
4699
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
4700
+ ( match = preFilters[ type ](match, context, xml) )) ) {
4759
4701
 
4760
- // Combinators
4761
- if ( (match = rcombinators.exec( soFar )) ) {
4702
+ group += match[0];
4762
4703
  soFar = soFar.slice( match[0].length );
4763
-
4764
- // Cast descendant combinators to space
4765
- matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match });
4766
- }
4767
-
4768
- // Filters
4769
- for ( type in filters ) {
4770
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
4771
- (match = preFilters[ type ]( match, context, xml )) ) ) {
4772
-
4773
- soFar = soFar.slice( match.shift().length );
4774
- matched = tokens.push({ part: type, captures: match });
4775
- }
4704
+ matched = tokens.push({
4705
+ part: type,
4706
+ string: match.shift(),
4707
+ captures: match
4708
+ });
4776
4709
  }
4710
+ }
4777
4711
 
4778
- if ( !matched ) {
4779
- break;
4780
- }
4712
+ if ( !matched ) {
4713
+ break;
4781
4714
  }
4782
4715
  }
4783
4716
 
4784
- if ( !matched ) {
4785
- Sizzle.error( selector );
4717
+ // Attach the full group as a selector
4718
+ if ( group ) {
4719
+ tokens.selector = group;
4786
4720
  }
4787
4721
 
4788
- return groups;
4722
+ // Return the length of the invalid excess
4723
+ // if we're just parsing
4724
+ // Otherwise, throw an error or return tokens
4725
+ return parseOnly ?
4726
+ soFar.length :
4727
+ soFar ?
4728
+ Sizzle.error( selector ) :
4729
+ // Cache the tokens
4730
+ slice.call( tokenCache(key, groups), 0 );
4789
4731
  }
4790
4732
 
4791
- function addCombinator( matcher, combinator, context ) {
4733
+ function addCombinator( matcher, combinator, context, xml ) {
4792
4734
  var dir = combinator.dir,
4793
4735
  doneName = done++;
4794
4736
 
@@ -4799,43 +4741,53 @@ function addCombinator( matcher, combinator, context ) {
4799
4741
  };
4800
4742
  }
4801
4743
  return combinator.first ?
4802
- function( elem, context ) {
4744
+ function( elem ) {
4803
4745
  while ( (elem = elem[ dir ]) ) {
4804
4746
  if ( elem.nodeType === 1 ) {
4805
- return matcher( elem, context ) && elem;
4747
+ return matcher( elem ) && elem;
4806
4748
  }
4807
4749
  }
4808
4750
  } :
4809
- function( elem, context ) {
4810
- var cache,
4811
- dirkey = doneName + "." + dirruns,
4812
- cachedkey = dirkey + "." + cachedruns;
4813
- while ( (elem = elem[ dir ]) ) {
4814
- if ( elem.nodeType === 1 ) {
4815
- if ( (cache = elem[ expando ]) === cachedkey ) {
4816
- return elem.sizset;
4817
- } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
4818
- if ( elem.sizset ) {
4751
+ xml ?
4752
+ function( elem ) {
4753
+ while ( (elem = elem[ dir ]) ) {
4754
+ if ( elem.nodeType === 1 ) {
4755
+ if ( matcher( elem ) ) {
4819
4756
  return elem;
4820
4757
  }
4821
- } else {
4822
- elem[ expando ] = cachedkey;
4823
- if ( matcher( elem, context ) ) {
4824
- elem.sizset = true;
4825
- return elem;
4758
+ }
4759
+ }
4760
+ } :
4761
+ function( elem ) {
4762
+ var cache,
4763
+ dirkey = doneName + "." + dirruns,
4764
+ cachedkey = dirkey + "." + cachedruns;
4765
+ while ( (elem = elem[ dir ]) ) {
4766
+ if ( elem.nodeType === 1 ) {
4767
+ if ( (cache = elem[ expando ]) === cachedkey ) {
4768
+ return elem.sizset;
4769
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
4770
+ if ( elem.sizset ) {
4771
+ return elem;
4772
+ }
4773
+ } else {
4774
+ elem[ expando ] = cachedkey;
4775
+ if ( matcher( elem ) ) {
4776
+ elem.sizset = true;
4777
+ return elem;
4778
+ }
4779
+ elem.sizset = false;
4826
4780
  }
4827
- elem.sizset = false;
4828
4781
  }
4829
4782
  }
4830
- }
4831
- };
4783
+ };
4832
4784
  }
4833
4785
 
4834
4786
  function addMatcher( higher, deeper ) {
4835
4787
  return higher ?
4836
- function( elem, context ) {
4837
- var result = deeper( elem, context );
4838
- return result && higher( result === true ? elem : result, context );
4788
+ function( elem ) {
4789
+ var result = deeper( elem );
4790
+ return result && higher( result === true ? elem : result );
4839
4791
  } :
4840
4792
  deeper;
4841
4793
  }
@@ -4847,10 +4799,9 @@ function matcherFromTokens( tokens, context, xml ) {
4847
4799
 
4848
4800
  for ( ; (token = tokens[i]); i++ ) {
4849
4801
  if ( Expr.relative[ token.part ] ) {
4850
- matcher = addCombinator( matcher, Expr.relative[ token.part ], context );
4802
+ matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml );
4851
4803
  } else {
4852
- token.captures.push( context, xml );
4853
- matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) );
4804
+ matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) );
4854
4805
  }
4855
4806
  }
4856
4807
 
@@ -4858,11 +4809,11 @@ function matcherFromTokens( tokens, context, xml ) {
4858
4809
  }
4859
4810
 
4860
4811
  function matcherFromGroupMatchers( matchers ) {
4861
- return function( elem, context ) {
4812
+ return function( elem ) {
4862
4813
  var matcher,
4863
4814
  j = 0;
4864
4815
  for ( ; (matcher = matchers[j]); j++ ) {
4865
- if ( matcher(elem, context) ) {
4816
+ if ( matcher(elem) ) {
4866
4817
  return true;
4867
4818
  }
4868
4819
  }
@@ -4870,9 +4821,9 @@ function matcherFromGroupMatchers( matchers ) {
4870
4821
  };
4871
4822
  }
4872
4823
 
4873
- var compile = Sizzle.compile = function( selector, context, xml ) {
4874
- var tokens, group, i,
4875
- cached = compilerCache[ selector ];
4824
+ compile = Sizzle.compile = function( selector, context, xml ) {
4825
+ var group, i, len,
4826
+ cached = compilerCache[ expando ][ selector ];
4876
4827
 
4877
4828
  // Return a cached group function if already generated (context dependent)
4878
4829
  if ( cached && cached.context === context ) {
@@ -4881,42 +4832,134 @@ var compile = Sizzle.compile = function( selector, context, xml ) {
4881
4832
 
4882
4833
  // Generate a function of recursive functions that can be used to check each element
4883
4834
  group = tokenize( selector, context, xml );
4884
- for ( i = 0; (tokens = group[i]); i++ ) {
4885
- group[i] = matcherFromTokens( tokens, context, xml );
4835
+ for ( i = 0, len = group.length; i < len; i++ ) {
4836
+ group[i] = matcherFromTokens(group[i], context, xml);
4886
4837
  }
4887
4838
 
4888
4839
  // Cache the compiled function
4889
- cached = compilerCache[ selector ] = matcherFromGroupMatchers( group );
4840
+ cached = compilerCache( selector, matcherFromGroupMatchers(group) );
4890
4841
  cached.context = context;
4891
4842
  cached.runs = cached.dirruns = 0;
4892
- cachedSelectors.push( selector );
4893
- // Ensure only the most recent are cached
4894
- if ( cachedSelectors.length > Expr.cacheLength ) {
4895
- delete compilerCache[ cachedSelectors.shift() ];
4896
- }
4897
4843
  return cached;
4898
4844
  };
4899
4845
 
4900
- Sizzle.matches = function( expr, elements ) {
4901
- return Sizzle( expr, null, null, elements );
4902
- };
4846
+ function multipleContexts( selector, contexts, results, seed ) {
4847
+ var i = 0,
4848
+ len = contexts.length;
4849
+ for ( ; i < len; i++ ) {
4850
+ Sizzle( selector, contexts[i], results, seed );
4851
+ }
4852
+ }
4903
4853
 
4904
- Sizzle.matchesSelector = function( elem, expr ) {
4905
- return Sizzle( expr, null, null, [ elem ] ).length > 0;
4906
- };
4854
+ function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {
4855
+ var results,
4856
+ fn = Expr.setFilters[ posfilter.toLowerCase() ];
4857
+
4858
+ if ( !fn ) {
4859
+ Sizzle.error( posfilter );
4860
+ }
4861
+
4862
+ if ( selector || !(results = seed) ) {
4863
+ multipleContexts( selector || "*", contexts, (results = []), seed );
4864
+ }
4865
+
4866
+ return results.length > 0 ? fn( results, argument, not ) : [];
4867
+ }
4868
+
4869
+ function handlePOS( groups, context, results, seed ) {
4870
+ var group, part, j, groupLen, token, selector,
4871
+ anchor, elements, match, matched,
4872
+ lastIndex, currentContexts, not,
4873
+ i = 0,
4874
+ len = groups.length,
4875
+ rpos = matchExpr["POS"],
4876
+ // This is generated here in case matchExpr["POS"] is extended
4877
+ rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),
4878
+ // This is for making sure non-participating
4879
+ // matching groups are represented cross-browser (IE6-8)
4880
+ setUndefined = function() {
4881
+ var i = 1,
4882
+ len = arguments.length - 2;
4883
+ for ( ; i < len; i++ ) {
4884
+ if ( arguments[i] === undefined ) {
4885
+ match[i] = undefined;
4886
+ }
4887
+ }
4888
+ };
4889
+
4890
+ for ( ; i < len; i++ ) {
4891
+ group = groups[i];
4892
+ part = "";
4893
+ elements = seed;
4894
+ for ( j = 0, groupLen = group.length; j < groupLen; j++ ) {
4895
+ token = group[j];
4896
+ selector = token.string;
4897
+ if ( token.part === "PSEUDO" ) {
4898
+ // Reset regex index to 0
4899
+ rpos.exec("");
4900
+ anchor = 0;
4901
+ while ( (match = rpos.exec( selector )) ) {
4902
+ matched = true;
4903
+ lastIndex = rpos.lastIndex = match.index + match[0].length;
4904
+ if ( lastIndex > anchor ) {
4905
+ part += selector.slice( anchor, match.index );
4906
+ anchor = lastIndex;
4907
+ currentContexts = [ context ];
4908
+
4909
+ if ( rcombinators.test(part) ) {
4910
+ if ( elements ) {
4911
+ currentContexts = elements;
4912
+ }
4913
+ elements = seed;
4914
+ }
4915
+
4916
+ if ( (not = rendsWithNot.test( part )) ) {
4917
+ part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );
4918
+ anchor++;
4919
+ }
4920
+
4921
+ if ( match.length > 1 ) {
4922
+ match[0].replace( rposgroups, setUndefined );
4923
+ }
4924
+ elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );
4925
+ }
4926
+ part = "";
4927
+ }
4928
+
4929
+ }
4930
+
4931
+ if ( !matched ) {
4932
+ part += selector;
4933
+ }
4934
+ matched = false;
4935
+ }
4936
+
4937
+ if ( part ) {
4938
+ if ( rcombinators.test(part) ) {
4939
+ multipleContexts( part, elements || [ context ], results, seed );
4940
+ } else {
4941
+ Sizzle( part, context, results, seed ? seed.concat(elements) : elements );
4942
+ }
4943
+ } else {
4944
+ push.apply( results, elements );
4945
+ }
4946
+ }
4947
+
4948
+ // Do not sort if this is a single filter
4949
+ return len === 1 ? results : Sizzle.uniqueSort( results );
4950
+ }
4907
4951
 
4908
- var select = function( selector, context, results, seed, xml ) {
4952
+ function select( selector, context, results, seed, xml ) {
4909
4953
  // Remove excessive whitespace
4910
4954
  selector = selector.replace( rtrim, "$1" );
4911
- var elements, matcher, i, len, elem, token,
4912
- type, findContext, notTokens,
4913
- match = selector.match( rgroups ),
4914
- tokens = selector.match( rtokens ),
4955
+ var elements, matcher, cached, elem,
4956
+ i, tokens, token, lastToken, findContext, type,
4957
+ match = tokenize( selector, context, xml ),
4915
4958
  contextNodeType = context.nodeType;
4916
4959
 
4917
4960
  // POS handling
4918
4961
  if ( matchExpr["POS"].test(selector) ) {
4919
- return handlePOS( selector, context, results, seed, match );
4962
+ return handlePOS( match, context, results, seed );
4920
4963
  }
4921
4964
 
4922
4965
  if ( seed ) {
@@ -4924,68 +4967,69 @@ var select = function( selector, context, results, seed, xml ) {
4924
4967
 
4925
4968
  // To maintain document order, only narrow the
4926
4969
  // set if there is one group
4927
- } else if ( match && match.length === 1 ) {
4970
+ } else if ( match.length === 1 ) {
4928
4971
 
4929
4972
  // Take a shortcut and set the context if the root selector is an ID
4930
- if ( tokens.length > 1 && contextNodeType === 9 && !xml &&
4931
- (match = matchExpr["ID"].exec( tokens[0] )) ) {
4973
+ if ( (tokens = slice.call( match[0], 0 )).length > 2 &&
4974
+ (token = tokens[0]).part === "ID" &&
4975
+ contextNodeType === 9 && !xml &&
4976
+ Expr.relative[ tokens[1].part ] ) {
4932
4977
 
4933
- context = Expr.find["ID"]( match[1], context, xml )[0];
4978
+ context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0];
4934
4979
  if ( !context ) {
4935
4980
  return results;
4936
4981
  }
4937
4982
 
4938
- selector = selector.slice( tokens.shift().length );
4983
+ selector = selector.slice( tokens.shift().string.length );
4939
4984
  }
4940
4985
 
4941
- findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context;
4942
-
4943
- // Get the last token, excluding :not
4944
- notTokens = tokens.pop();
4945
- token = notTokens.split(":not")[0];
4946
-
4947
- for ( i = 0, len = Expr.order.length; i < len; i++ ) {
4948
- type = Expr.order[i];
4949
-
4950
- if ( (match = matchExpr[ type ].exec( token )) ) {
4951
- elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml );
4986
+ findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context;
4952
4987
 
4988
+ // Reduce the set if possible
4989
+ lastToken = "";
4990
+ for ( i = tokens.length - 1; i >= 0; i-- ) {
4991
+ token = tokens[i];
4992
+ type = token.part;
4993
+ lastToken = token.string + lastToken;
4994
+ if ( Expr.relative[ type ] ) {
4995
+ break;
4996
+ }
4997
+ if ( Expr.order.test(type) ) {
4998
+ elements = Expr.find[ type ]( token.captures[0].replace( rbackslash, "" ), findContext, xml );
4953
4999
  if ( elements == null ) {
4954
5000
  continue;
4955
- }
4956
-
4957
- if ( token === notTokens ) {
4958
- selector = selector.slice( 0, selector.length - notTokens.length ) +
4959
- token.replace( matchExpr[ type ], "" );
5001
+ } else {
5002
+ selector = selector.slice( 0, selector.length - lastToken.length ) +
5003
+ lastToken.replace( matchExpr[ type ], "" );
4960
5004
 
4961
5005
  if ( !selector ) {
4962
5006
  push.apply( results, slice.call(elements, 0) );
4963
5007
  }
5008
+
5009
+ break;
4964
5010
  }
4965
- break;
4966
5011
  }
4967
5012
  }
4968
5013
  }
4969
5014
 
4970
5015
  // Only loop over the given elements once
4971
- // If selector is empty, we're already done
4972
5016
  if ( selector ) {
4973
5017
  matcher = compile( selector, context, xml );
4974
5018
  dirruns = matcher.dirruns++;
4975
-
4976
5019
  if ( elements == null ) {
4977
5020
  elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );
4978
5021
  }
5022
+
4979
5023
  for ( i = 0; (elem = elements[i]); i++ ) {
4980
5024
  cachedruns = matcher.runs++;
4981
- if ( matcher(elem, context) ) {
5025
+ if ( matcher(elem) ) {
4982
5026
  results.push( elem );
4983
5027
  }
4984
5028
  }
4985
5029
  }
4986
5030
 
4987
5031
  return results;
4988
- };
5032
+ }
4989
5033
 
4990
5034
  if ( document.querySelectorAll ) {
4991
5035
  (function() {
@@ -5007,7 +5051,12 @@ if ( document.querySelectorAll ) {
5007
5051
  // Build QSA regex
5008
5052
  // Regex strategy adopted from Diego Perini
5009
5053
  assert(function( div ) {
5010
- div.innerHTML = "<select><option selected></option></select>";
5054
+ // Select is set to empty string on purpose
5055
+ // This is to test IE's treatment of not explictly
5056
+ // setting a boolean content attribute,
5057
+ // since its presence should be enough
5058
+ // http://bugs.jquery.com/ticket/12359
5059
+ div.innerHTML = "<select><option selected=''></option></select>";
5011
5060
 
5012
5061
  // IE8 - Some boolean attributes are not treated correctly
5013
5062
  if ( !div.querySelectorAll("[selected]").length ) {
@@ -5033,7 +5082,7 @@ if ( document.querySelectorAll ) {
5033
5082
 
5034
5083
  // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
5035
5084
  // IE8 throws error here (do not put tests after this one)
5036
- div.innerHTML = "<input type='hidden'>";
5085
+ div.innerHTML = "<input type='hidden'/>";
5037
5086
  if ( !div.querySelectorAll(":enabled").length ) {
5038
5087
  rbuggyQSA.push(":enabled", ":disabled");
5039
5088
  }
@@ -5056,7 +5105,8 @@ if ( document.querySelectorAll ) {
5056
5105
  // and working up from there (Thanks to Andrew Dupont for the technique)
5057
5106
  // IE 8 doesn't work on object elements
5058
5107
  } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5059
- var old = context.getAttribute("id"),
5108
+ var groups, i, len,
5109
+ old = context.getAttribute("id"),
5060
5110
  nid = old || expando,
5061
5111
  newContext = rsibling.test( selector ) && context.parentNode || context;
5062
5112
 
@@ -5066,9 +5116,16 @@ if ( document.querySelectorAll ) {
5066
5116
  context.setAttribute( "id", nid );
5067
5117
  }
5068
5118
 
5119
+ groups = tokenize(selector, context, xml);
5120
+ // Trailing space is unnecessary
5121
+ // There is always a context check
5122
+ nid = "[id='" + nid + "']";
5123
+ for ( i = 0, len = groups.length; i < len; i++ ) {
5124
+ groups[i] = nid + groups[i].selector;
5125
+ }
5069
5126
  try {
5070
5127
  push.apply( results, slice.call( newContext.querySelectorAll(
5071
- selector.replace( rgroups, "[id='" + nid + "'] $&" )
5128
+ groups.join(",")
5072
5129
  ), 0 ) );
5073
5130
  return results;
5074
5131
  } catch(qsaError) {
@@ -5093,7 +5150,7 @@ if ( document.querySelectorAll ) {
5093
5150
  // Gecko does not error, returns false instead
5094
5151
  try {
5095
5152
  matches.call( div, "[test!='']:sizzle" );
5096
- rbuggyMatches.push( Expr.match.PSEUDO );
5153
+ rbuggyMatches.push( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" );
5097
5154
  } catch ( e ) {}
5098
5155
  });
5099
5156
 
@@ -5125,6 +5182,12 @@ if ( document.querySelectorAll ) {
5125
5182
  })();
5126
5183
  }
5127
5184
 
5185
+ // Deprecated
5186
+ Expr.setFilters["nth"] = Expr.setFilters["eq"];
5187
+
5188
+ // Back-compat
5189
+ Expr.filters = Expr.pseudos;
5190
+
5128
5191
  // Override sizzle attribute retrieval
5129
5192
  Sizzle.attr = jQuery.attr;
5130
5193
  jQuery.find = Sizzle;
@@ -5923,15 +5986,11 @@ jQuery.buildFragment = function( args, context, scripts ) {
5923
5986
  first = args[ 0 ];
5924
5987
 
5925
5988
  // Set context from what may come in as undefined or a jQuery collection or a node
5989
+ // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
5990
+ // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
5926
5991
  context = context || document;
5927
- context = (context[0] || context).ownerDocument || context[0] || context;
5928
-
5929
- // Ensure that an attr object doesn't incorrectly stand in as a document object
5930
- // Chrome and Firefox seem to allow this to occur and will throw exception
5931
- // Fixes #8950
5932
- if ( typeof context.createDocumentFragment === "undefined" ) {
5933
- context = document;
5934
- }
5992
+ context = !context.nodeType && context[0] || context;
5993
+ context = context.ownerDocument || context;
5935
5994
 
5936
5995
  // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5937
5996
  // Cloning options loses the selected state, so don't cache them
@@ -6076,8 +6135,8 @@ jQuery.extend({
6076
6135
  },
6077
6136
 
6078
6137
  clean: function( elems, context, fragment, scripts ) {
6079
- var j, safe, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
6080
- i = 0,
6138
+ var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
6139
+ safe = context === document && safeFragment,
6081
6140
  ret = [];
6082
6141
 
6083
6142
  // Ensure that context is a document
@@ -6086,7 +6145,7 @@ jQuery.extend({
6086
6145
  }
6087
6146
 
6088
6147
  // Use the already-created safe fragment if context permits
6089
- for ( safe = context === document && safeFragment; (elem = elems[i]) != null; i++ ) {
6148
+ for ( i = 0; (elem = elems[i]) != null; i++ ) {
6090
6149
  if ( typeof elem === "number" ) {
6091
6150
  elem += "";
6092
6151
  }
@@ -6102,7 +6161,8 @@ jQuery.extend({
6102
6161
  } else {
6103
6162
  // Ensure a safe container in which to render the html
6104
6163
  safe = safe || createSafeFragment( context );
6105
- div = div || safe.appendChild( context.createElement("div") );
6164
+ div = context.createElement("div");
6165
+ safe.appendChild( div );
6106
6166
 
6107
6167
  // Fix "XHTML"-style tags in all browsers
6108
6168
  elem = elem.replace(rxhtmlTag, "<$1></$2>");
@@ -6145,21 +6205,20 @@ jQuery.extend({
6145
6205
 
6146
6206
  elem = div.childNodes;
6147
6207
 
6148
- // Remember the top-level container for proper cleanup
6149
- div = safe.lastChild;
6208
+ // Take out of fragment container (we need a fresh div each time)
6209
+ div.parentNode.removeChild( div );
6150
6210
  }
6151
6211
  }
6152
6212
 
6153
6213
  if ( elem.nodeType ) {
6154
6214
  ret.push( elem );
6155
6215
  } else {
6156
- ret = jQuery.merge( ret, elem );
6216
+ jQuery.merge( ret, elem );
6157
6217
  }
6158
6218
  }
6159
6219
 
6160
6220
  // Fix #11356: Clear elements from safeFragment
6161
6221
  if ( div ) {
6162
- safe.removeChild( div );
6163
6222
  elem = div = safe = null;
6164
6223
  }
6165
6224
 
@@ -6294,9 +6353,10 @@ if ( matched.browser ) {
6294
6353
  browser.version = matched.version;
6295
6354
  }
6296
6355
 
6297
- // Deprecated, use jQuery.browser.webkit instead
6298
- // Maintained for back-compat only
6299
- if ( browser.webkit ) {
6356
+ // Chrome is Webkit, but Webkit is also Safari.
6357
+ if ( browser.chrome ) {
6358
+ browser.webkit = true;
6359
+ } else if ( browser.webkit ) {
6300
6360
  browser.safari = true;
6301
6361
  }
6302
6362
 
@@ -6322,12 +6382,15 @@ jQuery.sub = function() {
6322
6382
  var rootjQuerySub = jQuerySub(document);
6323
6383
  return jQuerySub;
6324
6384
  };
6325
-
6385
+
6326
6386
  })();
6327
6387
  var curCSS, iframe, iframeDoc,
6328
6388
  ralpha = /alpha\([^)]*\)/i,
6329
6389
  ropacity = /opacity=([^)]*)/,
6330
6390
  rposition = /^(top|right|bottom|left)$/,
6391
+ // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6392
+ // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6393
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6331
6394
  rmargin = /^margin/,
6332
6395
  rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6333
6396
  rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
@@ -6337,8 +6400,7 @@ var curCSS, iframe, iframeDoc,
6337
6400
  cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6338
6401
  cssNormalTransform = {
6339
6402
  letterSpacing: 0,
6340
- fontWeight: 400,
6341
- lineHeight: 1
6403
+ fontWeight: 400
6342
6404
  },
6343
6405
 
6344
6406
  cssExpand = [ "Top", "Right", "Bottom", "Left" ],
@@ -6604,18 +6666,18 @@ jQuery.extend({
6604
6666
  }
6605
6667
  });
6606
6668
 
6607
- // NOTE: To any future maintainer, we've used both window.getComputedStyle
6608
- // and getComputedStyle here to produce a better gzip size
6669
+ // NOTE: To any future maintainer, we've window.getComputedStyle
6670
+ // because jsdom on node.js will break without it.
6609
6671
  if ( window.getComputedStyle ) {
6610
6672
  curCSS = function( elem, name ) {
6611
6673
  var ret, width, minWidth, maxWidth,
6612
- computed = getComputedStyle( elem, null ),
6674
+ computed = window.getComputedStyle( elem, null ),
6613
6675
  style = elem.style;
6614
6676
 
6615
6677
  if ( computed ) {
6616
6678
 
6617
6679
  ret = computed[ name ];
6618
- if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6680
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6619
6681
  ret = jQuery.style( elem, name );
6620
6682
  }
6621
6683
 
@@ -6738,7 +6800,10 @@ function getWidthOrHeight( elem, name, extra ) {
6738
6800
  valueIsBorderBox = true,
6739
6801
  isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
6740
6802
 
6741
- if ( val <= 0 ) {
6803
+ // some non-html elements return undefined for offsetWidth, so check for null/undefined
6804
+ // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6805
+ // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6806
+ if ( val <= 0 || val == null ) {
6742
6807
  // Fall back to computed then uncomputed css if necessary
6743
6808
  val = curCSS( elem, name );
6744
6809
  if ( val < 0 || val == null ) {
@@ -6817,12 +6882,14 @@ jQuery.each([ "height", "width" ], function( i, name ) {
6817
6882
  jQuery.cssHooks[ name ] = {
6818
6883
  get: function( elem, computed, extra ) {
6819
6884
  if ( computed ) {
6820
- if ( elem.offsetWidth !== 0 || curCSS( elem, "display" ) !== "none" ) {
6821
- return getWidthOrHeight( elem, name, extra );
6822
- } else {
6885
+ // certain elements can have dimension info if we invisibly show them
6886
+ // however, it must have a current display style that would benefit from this
6887
+ if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
6823
6888
  return jQuery.swap( elem, cssShow, function() {
6824
6889
  return getWidthOrHeight( elem, name, extra );
6825
6890
  });
6891
+ } else {
6892
+ return getWidthOrHeight( elem, name, extra );
6826
6893
  }
6827
6894
  }
6828
6895
  },
@@ -7228,7 +7295,7 @@ jQuery.fn.load = function( url, params, callback ) {
7228
7295
  params = undefined;
7229
7296
 
7230
7297
  // Otherwise, build a param string
7231
- } else if ( typeof params === "object" ) {
7298
+ } else if ( params && typeof params === "object" ) {
7232
7299
  type = "POST";
7233
7300
  }
7234
7301
 
@@ -8709,7 +8776,13 @@ Tween.prototype = {
8709
8776
  var eased,
8710
8777
  hooks = Tween.propHooks[ this.prop ];
8711
8778
 
8712
- this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration );
8779
+ if ( this.options.duration ) {
8780
+ this.pos = eased = jQuery.easing[ this.easing ](
8781
+ percent, this.options.duration * percent, 0, 1, this.options.duration
8782
+ );
8783
+ } else {
8784
+ this.pos = eased = percent;
8785
+ }
8713
8786
  this.now = ( this.end - this.start ) * eased + this.start;
8714
8787
 
8715
8788
  if ( this.options.step ) {
@@ -8867,6 +8940,7 @@ function genFx( type, includeWidth ) {
8867
8940
 
8868
8941
  // if we include width, step value is 1 to do all cssExpand values,
8869
8942
  // if we don't include width, step value is 2 to skip over Left and Right
8943
+ includeWidth = includeWidth? 1 : 0;
8870
8944
  for( ; i < 4 ; i += 2 - includeWidth ) {
8871
8945
  which = cssExpand[ i ];
8872
8946
  attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
@@ -9201,7 +9275,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9201
9275
 
9202
9276
  // Set width or height on the element
9203
9277
  jQuery.style( elem, type, value, extra );
9204
- }, type, chainable ? margin : undefined, chainable );
9278
+ }, type, chainable ? margin : undefined, chainable, null );
9205
9279
  };
9206
9280
  });
9207
9281
  });