source: Dev/branches/jQueryUI/client/d3/lib/sizzle/sizzle.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

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