Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/js/sizzle/sizzle-raw.js
2868 views
1
/*!
2
* Sizzle CSS Selector Engine
3
* Copyright 2011, The Dojo Foundation
4
* Released under the MIT, BSD, and GPL Licenses.
5
* More information: http://sizzlejs.com/
6
*/
7
(function(){
8
9
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
10
expando = "sizcache" + (Math.random() + '').replace('.', ''),
11
done = 0,
12
toString = Object.prototype.toString,
13
hasDuplicate = false,
14
baseHasDuplicate = true,
15
rBackslash = /\\/g,
16
rReturn = /\r\n/g,
17
rNonWord = /\W/;
18
19
// Here we check if the JavaScript engine is using some sort of
20
// optimization where it does not always call our comparision
21
// function. If that is the case, discard the hasDuplicate value.
22
// Thus far that includes Google Chrome.
23
[0, 0].sort(function() {
24
baseHasDuplicate = false;
25
return 0;
26
});
27
28
var Sizzle = function( selector, context, results, seed ) {
29
results = results || [];
30
context = context || document;
31
32
var origContext = context;
33
34
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
35
return [];
36
}
37
38
if ( !selector || typeof selector !== "string" ) {
39
return results;
40
}
41
42
var m, set, checkSet, extra, ret, cur, pop, i,
43
prune = true,
44
contextXML = Sizzle.isXML( context ),
45
parts = [],
46
soFar = selector;
47
48
// Reset the position of the chunker regexp (start from head)
49
do {
50
chunker.exec( "" );
51
m = chunker.exec( soFar );
52
53
if ( m ) {
54
soFar = m[3];
55
56
parts.push( m[1] );
57
58
if ( m[2] ) {
59
extra = m[3];
60
break;
61
}
62
}
63
} while ( m );
64
65
if ( parts.length > 1 && origPOS.exec( selector ) ) {
66
67
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
68
set = posProcess( parts[0] + parts[1], context, seed );
69
70
} else {
71
set = Expr.relative[ parts[0] ] ?
72
[ context ] :
73
Sizzle( parts.shift(), context );
74
75
while ( parts.length ) {
76
selector = parts.shift();
77
78
if ( Expr.relative[ selector ] ) {
79
selector += parts.shift();
80
}
81
82
set = posProcess( selector, set, seed );
83
}
84
}
85
86
} else {
87
// Take a shortcut and set the context if the root selector is an ID
88
// (but not if it'll be faster if the inner selector is an ID)
89
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
90
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
91
92
ret = Sizzle.find( parts.shift(), context, contextXML );
93
context = ret.expr ?
94
Sizzle.filter( ret.expr, ret.set )[0] :
95
ret.set[0];
96
}
97
98
if ( context ) {
99
ret = seed ?
100
{ expr: parts.pop(), set: makeArray(seed) } :
101
Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
102
103
set = ret.expr ?
104
Sizzle.filter( ret.expr, ret.set ) :
105
ret.set;
106
107
if ( parts.length > 0 ) {
108
checkSet = makeArray( set );
109
110
} else {
111
prune = false;
112
}
113
114
while ( parts.length ) {
115
cur = parts.pop();
116
pop = cur;
117
118
if ( !Expr.relative[ cur ] ) {
119
cur = "";
120
} else {
121
pop = parts.pop();
122
}
123
124
if ( pop == null ) {
125
pop = context;
126
}
127
128
Expr.relative[ cur ]( checkSet, pop, contextXML );
129
}
130
131
} else {
132
checkSet = parts = [];
133
}
134
}
135
136
if ( !checkSet ) {
137
checkSet = set;
138
}
139
140
if ( !checkSet ) {
141
Sizzle.error( cur || selector );
142
}
143
144
if ( toString.call(checkSet) === "[object Array]" ) {
145
if ( !prune ) {
146
results.push.apply( results, checkSet );
147
148
} else if ( context && context.nodeType === 1 ) {
149
for ( i = 0; checkSet[i] != null; i++ ) {
150
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
151
results.push( set[i] );
152
}
153
}
154
155
} else {
156
for ( i = 0; checkSet[i] != null; i++ ) {
157
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
158
results.push( set[i] );
159
}
160
}
161
}
162
163
} else {
164
makeArray( checkSet, results );
165
}
166
167
if ( extra ) {
168
Sizzle( extra, origContext, results, seed );
169
Sizzle.uniqueSort( results );
170
}
171
172
return results;
173
};
174
175
Sizzle.uniqueSort = function( results ) {
176
if ( sortOrder ) {
177
hasDuplicate = baseHasDuplicate;
178
results.sort( sortOrder );
179
180
if ( hasDuplicate ) {
181
for ( var i = 1; i < results.length; i++ ) {
182
if ( results[i] === results[ i - 1 ] ) {
183
results.splice( i--, 1 );
184
}
185
}
186
}
187
}
188
189
return results;
190
};
191
192
Sizzle.matches = function( expr, set ) {
193
return Sizzle( expr, null, null, set );
194
};
195
196
Sizzle.matchesSelector = function( node, expr ) {
197
return Sizzle( expr, null, null, [node] ).length > 0;
198
};
199
200
Sizzle.find = function( expr, context, isXML ) {
201
var set, i, len, match, type, left;
202
203
if ( !expr ) {
204
return [];
205
}
206
207
for ( i = 0, len = Expr.order.length; i < len; i++ ) {
208
type = Expr.order[i];
209
210
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
211
left = match[1];
212
match.splice( 1, 1 );
213
214
if ( left.substr( left.length - 1 ) !== "\\" ) {
215
match[1] = (match[1] || "").replace( rBackslash, "" );
216
set = Expr.find[ type ]( match, context, isXML );
217
218
if ( set != null ) {
219
expr = expr.replace( Expr.match[ type ], "" );
220
break;
221
}
222
}
223
}
224
}
225
226
if ( !set ) {
227
set = typeof context.getElementsByTagName !== "undefined" ?
228
context.getElementsByTagName( "*" ) :
229
[];
230
}
231
232
return { set: set, expr: expr };
233
};
234
235
Sizzle.filter = function( expr, set, inplace, not ) {
236
var match, anyFound,
237
type, found, item, filter, left,
238
i, pass,
239
old = expr,
240
result = [],
241
curLoop = set,
242
isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
243
244
while ( expr && set.length ) {
245
for ( type in Expr.filter ) {
246
if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
247
filter = Expr.filter[ type ];
248
left = match[1];
249
250
anyFound = false;
251
252
match.splice(1,1);
253
254
if ( left.substr( left.length - 1 ) === "\\" ) {
255
continue;
256
}
257
258
if ( curLoop === result ) {
259
result = [];
260
}
261
262
if ( Expr.preFilter[ type ] ) {
263
match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
264
265
if ( !match ) {
266
anyFound = found = true;
267
268
} else if ( match === true ) {
269
continue;
270
}
271
}
272
273
if ( match ) {
274
for ( i = 0; (item = curLoop[i]) != null; i++ ) {
275
if ( item ) {
276
found = filter( item, match, i, curLoop );
277
pass = not ^ found;
278
279
if ( inplace && found != null ) {
280
if ( pass ) {
281
anyFound = true;
282
283
} else {
284
curLoop[i] = false;
285
}
286
287
} else if ( pass ) {
288
result.push( item );
289
anyFound = true;
290
}
291
}
292
}
293
}
294
295
if ( found !== undefined ) {
296
if ( !inplace ) {
297
curLoop = result;
298
}
299
300
expr = expr.replace( Expr.match[ type ], "" );
301
302
if ( !anyFound ) {
303
return [];
304
}
305
306
break;
307
}
308
}
309
}
310
311
// Improper expression
312
if ( expr === old ) {
313
if ( anyFound == null ) {
314
Sizzle.error( expr );
315
316
} else {
317
break;
318
}
319
}
320
321
old = expr;
322
}
323
324
return curLoop;
325
};
326
327
Sizzle.error = function( msg ) {
328
throw new Error( "Syntax error, unrecognized expression: " + msg );
329
};
330
331
/**
332
* Utility function for retreiving the text value of an array of DOM nodes
333
* @param {Array|Element} elem
334
*/
335
var getText = Sizzle.getText = function( elem ) {
336
var i, node,
337
nodeType = elem.nodeType,
338
ret = "";
339
340
if ( nodeType ) {
341
if ( nodeType === 1 || nodeType === 9 ) {
342
// Use textContent || innerText for elements
343
if ( typeof elem.textContent === 'string' ) {
344
return elem.textContent;
345
} else if ( typeof elem.innerText === 'string' ) {
346
// Replace IE's carriage returns
347
return elem.innerText.replace( rReturn, '' );
348
} else {
349
// Traverse it's children
350
for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
351
ret += getText( elem );
352
}
353
}
354
} else if ( nodeType === 3 || nodeType === 4 ) {
355
return elem.nodeValue;
356
}
357
} else {
358
359
// If no nodeType, this is expected to be an array
360
for ( i = 0; (node = elem[i]); i++ ) {
361
// Do not traverse comment nodes
362
if ( node.nodeType !== 8 ) {
363
ret += getText( node );
364
}
365
}
366
}
367
return ret;
368
};
369
370
var Expr = Sizzle.selectors = {
371
order: [ "ID", "NAME", "TAG" ],
372
373
match: {
374
ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
375
CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
376
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
377
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
378
TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
379
CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
380
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
381
PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
382
},
383
384
leftMatch: {},
385
386
attrMap: {
387
"class": "className",
388
"for": "htmlFor"
389
},
390
391
attrHandle: {
392
href: function( elem ) {
393
return elem.getAttribute( "href" );
394
},
395
type: function( elem ) {
396
return elem.getAttribute( "type" );
397
}
398
},
399
400
relative: {
401
"+": function(checkSet, part){
402
var isPartStr = typeof part === "string",
403
isTag = isPartStr && !rNonWord.test( part ),
404
isPartStrNotTag = isPartStr && !isTag;
405
406
if ( isTag ) {
407
part = part.toLowerCase();
408
}
409
410
for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
411
if ( (elem = checkSet[i]) ) {
412
while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
413
414
checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
415
elem || false :
416
elem === part;
417
}
418
}
419
420
if ( isPartStrNotTag ) {
421
Sizzle.filter( part, checkSet, true );
422
}
423
},
424
425
">": function( checkSet, part ) {
426
var elem,
427
isPartStr = typeof part === "string",
428
i = 0,
429
l = checkSet.length;
430
431
if ( isPartStr && !rNonWord.test( part ) ) {
432
part = part.toLowerCase();
433
434
for ( ; i < l; i++ ) {
435
elem = checkSet[i];
436
437
if ( elem ) {
438
var parent = elem.parentNode;
439
checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
440
}
441
}
442
443
} else {
444
for ( ; i < l; i++ ) {
445
elem = checkSet[i];
446
447
if ( elem ) {
448
checkSet[i] = isPartStr ?
449
elem.parentNode :
450
elem.parentNode === part;
451
}
452
}
453
454
if ( isPartStr ) {
455
Sizzle.filter( part, checkSet, true );
456
}
457
}
458
},
459
460
"": function(checkSet, part, isXML){
461
var nodeCheck,
462
doneName = done++,
463
checkFn = dirCheck;
464
465
if ( typeof part === "string" && !rNonWord.test( part ) ) {
466
part = part.toLowerCase();
467
nodeCheck = part;
468
checkFn = dirNodeCheck;
469
}
470
471
checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
472
},
473
474
"~": function( checkSet, part, isXML ) {
475
var nodeCheck,
476
doneName = done++,
477
checkFn = dirCheck;
478
479
if ( typeof part === "string" && !rNonWord.test( part ) ) {
480
part = part.toLowerCase();
481
nodeCheck = part;
482
checkFn = dirNodeCheck;
483
}
484
485
checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
486
}
487
},
488
489
find: {
490
ID: function( match, context, isXML ) {
491
if ( typeof context.getElementById !== "undefined" && !isXML ) {
492
var m = context.getElementById(match[1]);
493
// Check parentNode to catch when Blackberry 4.6 returns
494
// nodes that are no longer in the document #6963
495
return m && m.parentNode ? [m] : [];
496
}
497
},
498
499
NAME: function( match, context ) {
500
if ( typeof context.getElementsByName !== "undefined" ) {
501
var ret = [],
502
results = context.getElementsByName( match[1] );
503
504
for ( var i = 0, l = results.length; i < l; i++ ) {
505
if ( results[i].getAttribute("name") === match[1] ) {
506
ret.push( results[i] );
507
}
508
}
509
510
return ret.length === 0 ? null : ret;
511
}
512
},
513
514
TAG: function( match, context ) {
515
if ( typeof context.getElementsByTagName !== "undefined" ) {
516
return context.getElementsByTagName( match[1] );
517
}
518
}
519
},
520
preFilter: {
521
CLASS: function( match, curLoop, inplace, result, not, isXML ) {
522
match = " " + match[1].replace( rBackslash, "" ) + " ";
523
524
if ( isXML ) {
525
return match;
526
}
527
528
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
529
if ( elem ) {
530
if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
531
if ( !inplace ) {
532
result.push( elem );
533
}
534
535
} else if ( inplace ) {
536
curLoop[i] = false;
537
}
538
}
539
}
540
541
return false;
542
},
543
544
ID: function( match ) {
545
return match[1].replace( rBackslash, "" );
546
},
547
548
TAG: function( match, curLoop ) {
549
return match[1].replace( rBackslash, "" ).toLowerCase();
550
},
551
552
CHILD: function( match ) {
553
if ( match[1] === "nth" ) {
554
if ( !match[2] ) {
555
Sizzle.error( match[0] );
556
}
557
558
match[2] = match[2].replace(/^\+|\s*/g, '');
559
560
// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
561
var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
562
match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
563
!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
564
565
// calculate the numbers (first)n+(last) including if they are negative
566
match[2] = (test[1] + (test[2] || 1)) - 0;
567
match[3] = test[3] - 0;
568
}
569
else if ( match[2] ) {
570
Sizzle.error( match[0] );
571
}
572
573
// TODO: Move to normal caching system
574
match[0] = done++;
575
576
return match;
577
},
578
579
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
580
var name = match[1] = match[1].replace( rBackslash, "" );
581
582
if ( !isXML && Expr.attrMap[name] ) {
583
match[1] = Expr.attrMap[name];
584
}
585
586
// Handle if an un-quoted value was used
587
match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
588
589
if ( match[2] === "~=" ) {
590
match[4] = " " + match[4] + " ";
591
}
592
593
return match;
594
},
595
596
PSEUDO: function( match, curLoop, inplace, result, not ) {
597
if ( match[1] === "not" ) {
598
// If we're dealing with a complex expression, or a simple one
599
if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
600
match[3] = Sizzle(match[3], null, null, curLoop);
601
602
} else {
603
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
604
605
if ( !inplace ) {
606
result.push.apply( result, ret );
607
}
608
609
return false;
610
}
611
612
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
613
return true;
614
}
615
616
return match;
617
},
618
619
POS: function( match ) {
620
match.unshift( true );
621
622
return match;
623
}
624
},
625
626
filters: {
627
enabled: function( elem ) {
628
return elem.disabled === false && elem.type !== "hidden";
629
},
630
631
disabled: function( elem ) {
632
return elem.disabled === true;
633
},
634
635
checked: function( elem ) {
636
return elem.checked === true;
637
},
638
639
selected: function( elem ) {
640
// Accessing this property makes selected-by-default
641
// options in Safari work properly
642
if ( elem.parentNode ) {
643
elem.parentNode.selectedIndex;
644
}
645
646
return elem.selected === true;
647
},
648
649
parent: function( elem ) {
650
return !!elem.firstChild;
651
},
652
653
empty: function( elem ) {
654
return !elem.firstChild;
655
},
656
657
has: function( elem, i, match ) {
658
return !!Sizzle( match[3], elem ).length;
659
},
660
661
header: function( elem ) {
662
return (/h\d/i).test( elem.nodeName );
663
},
664
665
text: function( elem ) {
666
var attr = elem.getAttribute( "type" ), type = elem.type;
667
// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
668
// use getAttribute instead to test this case
669
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
670
},
671
672
radio: function( elem ) {
673
return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
674
},
675
676
checkbox: function( elem ) {
677
return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
678
},
679
680
file: function( elem ) {
681
return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
682
},
683
684
password: function( elem ) {
685
return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
686
},
687
688
submit: function( elem ) {
689
var name = elem.nodeName.toLowerCase();
690
return (name === "input" || name === "button") && "submit" === elem.type;
691
},
692
693
image: function( elem ) {
694
return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
695
},
696
697
reset: function( elem ) {
698
var name = elem.nodeName.toLowerCase();
699
return (name === "input" || name === "button") && "reset" === elem.type;
700
},
701
702
button: function( elem ) {
703
var name = elem.nodeName.toLowerCase();
704
return name === "input" && "button" === elem.type || name === "button";
705
},
706
707
input: function( elem ) {
708
return (/input|select|textarea|button/i).test( elem.nodeName );
709
},
710
711
focus: function( elem ) {
712
return elem === elem.ownerDocument.activeElement;
713
}
714
},
715
setFilters: {
716
first: function( elem, i ) {
717
return i === 0;
718
},
719
720
last: function( elem, i, match, array ) {
721
return i === array.length - 1;
722
},
723
724
even: function( elem, i ) {
725
return i % 2 === 0;
726
},
727
728
odd: function( elem, i ) {
729
return i % 2 === 1;
730
},
731
732
lt: function( elem, i, match ) {
733
return i < match[3] - 0;
734
},
735
736
gt: function( elem, i, match ) {
737
return i > match[3] - 0;
738
},
739
740
nth: function( elem, i, match ) {
741
return match[3] - 0 === i;
742
},
743
744
eq: function( elem, i, match ) {
745
return match[3] - 0 === i;
746
}
747
},
748
filter: {
749
PSEUDO: function( elem, match, i, array ) {
750
var name = match[1],
751
filter = Expr.filters[ name ];
752
753
if ( filter ) {
754
return filter( elem, i, match, array );
755
756
} else if ( name === "contains" ) {
757
return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
758
759
} else if ( name === "not" ) {
760
var not = match[3];
761
762
for ( var j = 0, l = not.length; j < l; j++ ) {
763
if ( not[j] === elem ) {
764
return false;
765
}
766
}
767
768
return true;
769
770
} else {
771
Sizzle.error( name );
772
}
773
},
774
775
CHILD: function( elem, match ) {
776
var first, last,
777
doneName, parent, cache,
778
count, diff,
779
type = match[1],
780
node = elem;
781
782
switch ( type ) {
783
case "only":
784
case "first":
785
while ( (node = node.previousSibling) ) {
786
if ( node.nodeType === 1 ) {
787
return false;
788
}
789
}
790
791
if ( type === "first" ) {
792
return true;
793
}
794
795
node = elem;
796
797
/* falls through */
798
case "last":
799
while ( (node = node.nextSibling) ) {
800
if ( node.nodeType === 1 ) {
801
return false;
802
}
803
}
804
805
return true;
806
807
case "nth":
808
first = match[2];
809
last = match[3];
810
811
if ( first === 1 && last === 0 ) {
812
return true;
813
}
814
815
doneName = match[0];
816
parent = elem.parentNode;
817
818
if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
819
count = 0;
820
821
for ( node = parent.firstChild; node; node = node.nextSibling ) {
822
if ( node.nodeType === 1 ) {
823
node.nodeIndex = ++count;
824
}
825
}
826
827
parent[ expando ] = doneName;
828
}
829
830
diff = elem.nodeIndex - last;
831
832
if ( first === 0 ) {
833
return diff === 0;
834
835
} else {
836
return ( diff % first === 0 && diff / first >= 0 );
837
}
838
}
839
},
840
841
ID: function( elem, match ) {
842
return elem.nodeType === 1 && elem.getAttribute("id") === match;
843
},
844
845
TAG: function( elem, match ) {
846
return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
847
},
848
849
CLASS: function( elem, match ) {
850
return (" " + (elem.className || elem.getAttribute("class")) + " ")
851
.indexOf( match ) > -1;
852
},
853
854
ATTR: function( elem, match ) {
855
var name = match[1],
856
result = Sizzle.attr ?
857
Sizzle.attr( elem, name ) :
858
Expr.attrHandle[ name ] ?
859
Expr.attrHandle[ name ]( elem ) :
860
elem[ name ] != null ?
861
elem[ name ] :
862
elem.getAttribute( name ),
863
value = result + "",
864
type = match[2],
865
check = match[4];
866
867
return result == null ?
868
type === "!=" :
869
!type && Sizzle.attr ?
870
result != null :
871
type === "=" ?
872
value === check :
873
type === "*=" ?
874
value.indexOf(check) >= 0 :
875
type === "~=" ?
876
(" " + value + " ").indexOf(check) >= 0 :
877
!check ?
878
value && result !== false :
879
type === "!=" ?
880
value !== check :
881
type === "^=" ?
882
value.indexOf(check) === 0 :
883
type === "$=" ?
884
value.substr(value.length - check.length) === check :
885
type === "|=" ?
886
value === check || value.substr(0, check.length + 1) === check + "-" :
887
false;
888
},
889
890
POS: function( elem, match, i, array ) {
891
var name = match[2],
892
filter = Expr.setFilters[ name ];
893
894
if ( filter ) {
895
return filter( elem, i, match, array );
896
}
897
}
898
}
899
};
900
901
var origPOS = Expr.match.POS,
902
fescape = function(all, num){
903
return "\\" + (num - 0 + 1);
904
};
905
906
for ( var type in Expr.match ) {
907
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
908
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
909
}
910
// Expose origPOS
911
// "global" as in regardless of relation to brackets/parens
912
Expr.match.globalPOS = origPOS;
913
914
var makeArray = function( array, results ) {
915
array = Array.prototype.slice.call( array, 0 );
916
917
if ( results ) {
918
results.push.apply( results, array );
919
return results;
920
}
921
922
return array;
923
};
924
925
// Perform a simple check to determine if the browser is capable of
926
// converting a NodeList to an array using builtin methods.
927
// Also verifies that the returned array holds DOM nodes
928
// (which is not the case in the Blackberry browser)
929
try {
930
Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
931
932
// Provide a fallback method if it does not work
933
} catch( e ) {
934
makeArray = function( array, results ) {
935
var i = 0,
936
ret = results || [];
937
938
if ( toString.call(array) === "[object Array]" ) {
939
Array.prototype.push.apply( ret, array );
940
941
} else {
942
if ( typeof array.length === "number" ) {
943
for ( var l = array.length; i < l; i++ ) {
944
ret.push( array[i] );
945
}
946
947
} else {
948
for ( ; array[i]; i++ ) {
949
ret.push( array[i] );
950
}
951
}
952
}
953
954
return ret;
955
};
956
}
957
958
var sortOrder, siblingCheck;
959
960
if ( document.documentElement.compareDocumentPosition ) {
961
sortOrder = function( a, b ) {
962
if ( a === b ) {
963
hasDuplicate = true;
964
return 0;
965
}
966
967
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
968
return a.compareDocumentPosition ? -1 : 1;
969
}
970
971
return a.compareDocumentPosition(b) & 4 ? -1 : 1;
972
};
973
974
} else {
975
sortOrder = function( a, b ) {
976
// The nodes are identical, we can exit early
977
if ( a === b ) {
978
hasDuplicate = true;
979
return 0;
980
981
// Fallback to using sourceIndex (in IE) if it's available on both nodes
982
} else if ( a.sourceIndex && b.sourceIndex ) {
983
return a.sourceIndex - b.sourceIndex;
984
}
985
986
var al, bl,
987
ap = [],
988
bp = [],
989
aup = a.parentNode,
990
bup = b.parentNode,
991
cur = aup;
992
993
// If the nodes are siblings (or identical) we can do a quick check
994
if ( aup === bup ) {
995
return siblingCheck( a, b );
996
997
// If no parents were found then the nodes are disconnected
998
} else if ( !aup ) {
999
return -1;
1000
1001
} else if ( !bup ) {
1002
return 1;
1003
}
1004
1005
// Otherwise they're somewhere else in the tree so we need
1006
// to build up a full list of the parentNodes for comparison
1007
while ( cur ) {
1008
ap.unshift( cur );
1009
cur = cur.parentNode;
1010
}
1011
1012
cur = bup;
1013
1014
while ( cur ) {
1015
bp.unshift( cur );
1016
cur = cur.parentNode;
1017
}
1018
1019
al = ap.length;
1020
bl = bp.length;
1021
1022
// Start walking down the tree looking for a discrepancy
1023
for ( var i = 0; i < al && i < bl; i++ ) {
1024
if ( ap[i] !== bp[i] ) {
1025
return siblingCheck( ap[i], bp[i] );
1026
}
1027
}
1028
1029
// We ended someplace up the tree so do a sibling check
1030
return i === al ?
1031
siblingCheck( a, bp[i], -1 ) :
1032
siblingCheck( ap[i], b, 1 );
1033
};
1034
1035
siblingCheck = function( a, b, ret ) {
1036
if ( a === b ) {
1037
return ret;
1038
}
1039
1040
var cur = a.nextSibling;
1041
1042
while ( cur ) {
1043
if ( cur === b ) {
1044
return -1;
1045
}
1046
1047
cur = cur.nextSibling;
1048
}
1049
1050
return 1;
1051
};
1052
}
1053
1054
// Check to see if the browser returns elements by name when
1055
// querying by getElementById (and provide a workaround)
1056
(function(){
1057
// We're going to inject a fake input element with a specified name
1058
var form = document.createElement("div"),
1059
id = "script" + (new Date()).getTime(),
1060
root = document.documentElement;
1061
1062
form.innerHTML = "<a name='" + id + "'/>";
1063
1064
// Inject it into the root element, check its status, and remove it quickly
1065
root.insertBefore( form, root.firstChild );
1066
1067
// The workaround has to do additional checks after a getElementById
1068
// Which slows things down for other browsers (hence the branching)
1069
if ( document.getElementById( id ) ) {
1070
Expr.find.ID = function( match, context, isXML ) {
1071
if ( typeof context.getElementById !== "undefined" && !isXML ) {
1072
var m = context.getElementById(match[1]);
1073
1074
return m ?
1075
m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
1076
[m] :
1077
undefined :
1078
[];
1079
}
1080
};
1081
1082
Expr.filter.ID = function( elem, match ) {
1083
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1084
1085
return elem.nodeType === 1 && node && node.nodeValue === match;
1086
};
1087
}
1088
1089
root.removeChild( form );
1090
1091
// release memory in IE
1092
root = form = null;
1093
})();
1094
1095
(function(){
1096
// Check to see if the browser returns only elements
1097
// when doing getElementsByTagName("*")
1098
1099
// Create a fake element
1100
var div = document.createElement("div");
1101
div.appendChild( document.createComment("") );
1102
1103
// Make sure no comments are found
1104
if ( div.getElementsByTagName("*").length > 0 ) {
1105
Expr.find.TAG = function( match, context ) {
1106
var results = context.getElementsByTagName( match[1] );
1107
1108
// Filter out possible comments
1109
if ( match[1] === "*" ) {
1110
var tmp = [];
1111
1112
for ( var i = 0; results[i]; i++ ) {
1113
if ( results[i].nodeType === 1 ) {
1114
tmp.push( results[i] );
1115
}
1116
}
1117
1118
results = tmp;
1119
}
1120
1121
return results;
1122
};
1123
}
1124
1125
// Check to see if an attribute returns normalized href attributes
1126
div.innerHTML = "<a href='#'></a>";
1127
1128
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
1129
div.firstChild.getAttribute("href") !== "#" ) {
1130
1131
Expr.attrHandle.href = function( elem ) {
1132
return elem.getAttribute( "href", 2 );
1133
};
1134
}
1135
1136
// release memory in IE
1137
div = null;
1138
})();
1139
1140
if ( document.querySelectorAll ) {
1141
(function(){
1142
var oldSizzle = Sizzle,
1143
div = document.createElement("div"),
1144
id = "__sizzle__";
1145
1146
div.innerHTML = "<p class='TEST'></p>";
1147
1148
// Safari can't handle uppercase or unicode characters when
1149
// in quirks mode.
1150
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
1151
return;
1152
}
1153
1154
Sizzle = function( query, context, extra, seed ) {
1155
context = context || document;
1156
1157
// Only use querySelectorAll on non-XML documents
1158
// (ID selectors don't work in non-HTML documents)
1159
if ( !seed && !Sizzle.isXML(context) ) {
1160
// See if we find a selector to speed up
1161
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
1162
1163
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
1164
// Speed-up: Sizzle("TAG")
1165
if ( match[1] ) {
1166
return makeArray( context.getElementsByTagName( query ), extra );
1167
1168
// Speed-up: Sizzle(".CLASS")
1169
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
1170
return makeArray( context.getElementsByClassName( match[2] ), extra );
1171
}
1172
}
1173
1174
if ( context.nodeType === 9 ) {
1175
// Speed-up: Sizzle("body")
1176
// The body element only exists once, optimize finding it
1177
if ( query === "body" && context.body ) {
1178
return makeArray( [ context.body ], extra );
1179
1180
// Speed-up: Sizzle("#ID")
1181
} else if ( match && match[3] ) {
1182
var elem = context.getElementById( match[3] );
1183
1184
// Check parentNode to catch when Blackberry 4.6 returns
1185
// nodes that are no longer in the document #6963
1186
if ( elem && elem.parentNode ) {
1187
// Handle the case where IE and Opera return items
1188
// by name instead of ID
1189
if ( elem.id === match[3] ) {
1190
return makeArray( [ elem ], extra );
1191
}
1192
1193
} else {
1194
return makeArray( [], extra );
1195
}
1196
}
1197
1198
try {
1199
return makeArray( context.querySelectorAll(query), extra );
1200
} catch(qsaError) {}
1201
1202
// qSA works strangely on Element-rooted queries
1203
// We can work around this by specifying an extra ID on the root
1204
// and working up from there (Thanks to Andrew Dupont for the technique)
1205
// IE 8 doesn't work on object elements
1206
} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
1207
var oldContext = context,
1208
old = context.getAttribute( "id" ),
1209
nid = old || id,
1210
hasParent = context.parentNode,
1211
relativeHierarchySelector = /^\s*[+~]/.test( query );
1212
1213
if ( !old ) {
1214
context.setAttribute( "id", nid );
1215
} else {
1216
nid = nid.replace( /'/g, "\\$&" );
1217
}
1218
if ( relativeHierarchySelector && hasParent ) {
1219
context = context.parentNode;
1220
}
1221
1222
try {
1223
if ( !relativeHierarchySelector || hasParent ) {
1224
return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
1225
}
1226
1227
} catch(pseudoError) {
1228
} finally {
1229
if ( !old ) {
1230
oldContext.removeAttribute( "id" );
1231
}
1232
}
1233
}
1234
}
1235
1236
return oldSizzle(query, context, extra, seed);
1237
};
1238
1239
for ( var prop in oldSizzle ) {
1240
Sizzle[ prop ] = oldSizzle[ prop ];
1241
}
1242
1243
// release memory in IE
1244
div = null;
1245
})();
1246
}
1247
1248
(function(){
1249
var html = document.documentElement,
1250
matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
1251
1252
if ( matches ) {
1253
// Check to see if it's possible to do matchesSelector
1254
// on a disconnected node (IE 9 fails this)
1255
var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
1256
pseudoWorks = false;
1257
1258
try {
1259
// This should fail with an exception
1260
// Gecko does not error, returns false instead
1261
matches.call( document.documentElement, "[test!='']:sizzle" );
1262
1263
} catch( pseudoError ) {
1264
pseudoWorks = true;
1265
}
1266
1267
Sizzle.matchesSelector = function( node, expr ) {
1268
// Make sure that attribute selectors are quoted
1269
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
1270
1271
if ( !Sizzle.isXML( node ) ) {
1272
try {
1273
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
1274
var ret = matches.call( node, expr );
1275
1276
// IE 9's matchesSelector returns false on disconnected nodes
1277
if ( ret || !disconnectedMatch ||
1278
// As well, disconnected nodes are said to be in a document
1279
// fragment in IE 9, so check for that
1280
node.document && node.document.nodeType !== 11 ) {
1281
return ret;
1282
}
1283
}
1284
} catch(e) {}
1285
}
1286
1287
return Sizzle(expr, null, null, [node]).length > 0;
1288
};
1289
}
1290
})();
1291
1292
(function(){
1293
var div = document.createElement("div");
1294
1295
div.innerHTML = "<div class='test e'></div><div class='test'></div>";
1296
1297
// Opera can't find a second classname (in 9.6)
1298
// Also, make sure that getElementsByClassName actually exists
1299
if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
1300
return;
1301
}
1302
1303
// Safari caches class attributes, doesn't catch changes (in 3.2)
1304
div.lastChild.className = "e";
1305
1306
if ( div.getElementsByClassName("e").length === 1 ) {
1307
return;
1308
}
1309
1310
Expr.order.splice(1, 0, "CLASS");
1311
Expr.find.CLASS = function( match, context, isXML ) {
1312
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
1313
return context.getElementsByClassName(match[1]);
1314
}
1315
};
1316
1317
// release memory in IE
1318
div = null;
1319
})();
1320
1321
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
1322
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1323
var elem = checkSet[i];
1324
1325
if ( elem ) {
1326
var match = false;
1327
1328
elem = elem[dir];
1329
1330
while ( elem ) {
1331
if ( elem[ expando ] === doneName ) {
1332
match = checkSet[elem.sizset];
1333
break;
1334
}
1335
1336
if ( elem.nodeType === 1 && !isXML ){
1337
elem[ expando ] = doneName;
1338
elem.sizset = i;
1339
}
1340
1341
if ( elem.nodeName.toLowerCase() === cur ) {
1342
match = elem;
1343
break;
1344
}
1345
1346
elem = elem[dir];
1347
}
1348
1349
checkSet[i] = match;
1350
}
1351
}
1352
}
1353
1354
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
1355
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1356
var elem = checkSet[i];
1357
1358
if ( elem ) {
1359
var match = false;
1360
1361
elem = elem[dir];
1362
1363
while ( elem ) {
1364
if ( elem[ expando ] === doneName ) {
1365
match = checkSet[elem.sizset];
1366
break;
1367
}
1368
1369
if ( elem.nodeType === 1 ) {
1370
if ( !isXML ) {
1371
elem[ expando ] = doneName;
1372
elem.sizset = i;
1373
}
1374
1375
if ( typeof cur !== "string" ) {
1376
if ( elem === cur ) {
1377
match = true;
1378
break;
1379
}
1380
1381
} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
1382
match = elem;
1383
break;
1384
}
1385
}
1386
1387
elem = elem[dir];
1388
}
1389
1390
checkSet[i] = match;
1391
}
1392
}
1393
}
1394
1395
if ( document.documentElement.contains ) {
1396
Sizzle.contains = function( a, b ) {
1397
return a !== b && (a.contains ? a.contains(b) : true);
1398
};
1399
1400
} else if ( document.documentElement.compareDocumentPosition ) {
1401
Sizzle.contains = function( a, b ) {
1402
return !!(a.compareDocumentPosition(b) & 16);
1403
};
1404
1405
} else {
1406
Sizzle.contains = function() {
1407
return false;
1408
};
1409
}
1410
1411
Sizzle.isXML = function( elem ) {
1412
// documentElement is verified for cases where it doesn't yet exist
1413
// (such as loading iframes in IE - #4833)
1414
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
1415
1416
return documentElement ? documentElement.nodeName !== "HTML" : false;
1417
};
1418
1419
var posProcess = function( selector, context, seed ) {
1420
var match,
1421
tmpSet = [],
1422
later = "",
1423
root = context.nodeType ? [context] : context;
1424
1425
// Position selectors must be done after the filter
1426
// And so must :not(positional) so we move all PSEUDOs to the end
1427
while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
1428
later += match[0];
1429
selector = selector.replace( Expr.match.PSEUDO, "" );
1430
}
1431
1432
selector = Expr.relative[selector] ? selector + "*" : selector;
1433
1434
for ( var i = 0, l = root.length; i < l; i++ ) {
1435
Sizzle( selector, root[i], tmpSet, seed );
1436
}
1437
1438
return Sizzle.filter( later, tmpSet );
1439
};
1440
1441
// EXPOSE
1442
1443
window.Sizzle = Sizzle;
1444
1445
})();
1446
1447