~landscape/lazr-js/trunk

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/3.0.0/build/dom/selector.js

  • Committer: Sidnei da Silva
  • Date: 2009-10-21 21:43:07 UTC
  • mfrom: (120.2.15 yui-3.0.0)
  • mto: (124.5.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 126.
  • Revision ID: sidnei.da.silva@canonical.com-20091021214307-mpul9404n317puk5
- Merge from yui-3.0.0, resolving conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.net/yui/license.txt
 
5
version: 3.0.0
 
6
build: 1549
 
7
*/
 
8
YUI.add('selector-native', function(Y) {
 
9
 
 
10
(function(Y) {
 
11
/**
 
12
 * The selector-native module provides support for native querySelector
 
13
 * @module dom
 
14
 * @submodule selector-native
 
15
 * @for Selector
 
16
 */
 
17
 
 
18
/**
 
19
 * Provides support for using CSS selectors to query the DOM 
 
20
 * @class Selector 
 
21
 * @static
 
22
 * @for Selector
 
23
 */
 
24
 
 
25
Y.namespace('Selector'); // allow native module to standalone
 
26
 
 
27
var COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
 
28
    OWNER_DOCUMENT = 'ownerDocument',
 
29
    TMP_PREFIX = 'yui-tmp-',
 
30
    g_counter = 0;
 
31
 
 
32
var Selector = {
 
33
    _foundCache: [],
 
34
 
 
35
    useNative: true,
 
36
 
 
37
    _compare: ('sourceIndex' in document.documentElement) ?
 
38
        function(nodeA, nodeB) {
 
39
            var a = nodeA.sourceIndex,
 
40
                b = nodeB.sourceIndex;
 
41
 
 
42
            if (a === b) {
 
43
                return 0;
 
44
            } else if (a > b) {
 
45
                return 1;
 
46
            }
 
47
 
 
48
            return -1;
 
49
 
 
50
        } : (document.documentElement[COMPARE_DOCUMENT_POSITION] ?
 
51
        function(nodeA, nodeB) {
 
52
            if (nodeA[COMPARE_DOCUMENT_POSITION](nodeB) & 4) {
 
53
                return -1;
 
54
            } else {
 
55
                return 1;
 
56
            }
 
57
        } :
 
58
        function(nodeA, nodeB) {
 
59
            var rangeA, rangeB, compare;
 
60
            if (nodeA && nodeB) {
 
61
                rangeA = nodeA[OWNER_DOCUMENT].createRange();
 
62
                rangeA.setStart(nodeA, 0);
 
63
                rangeB = nodeB[OWNER_DOCUMENT].createRange();
 
64
                rangeB.setStart(nodeB, 0);
 
65
                compare = rangeA.compareBoundaryPoints(1, rangeB); // 1 === Range.START_TO_END
 
66
            }
 
67
 
 
68
            return compare;
 
69
        
 
70
    }),
 
71
 
 
72
    _sort: function(nodes) {
 
73
        if (nodes) {
 
74
            nodes = Y.Array(nodes, 0, true);
 
75
            if (nodes.sort) {
 
76
                nodes.sort(Selector._compare);
 
77
            }
 
78
        }
 
79
 
 
80
        return nodes;
 
81
    },
 
82
 
 
83
    _deDupe: function(nodes) {
 
84
        var ret = [],
 
85
            i, node;
 
86
 
 
87
        for (i = 0; (node = nodes[i++]);) {
 
88
            if (!node._found) {
 
89
                ret[ret.length] = node;
 
90
                node._found = true;
 
91
            }
 
92
        }
 
93
 
 
94
        for (i = 0; (node = ret[i++]);) {
 
95
            node._found = null;
 
96
            node.removeAttribute('_found');
 
97
        }
 
98
 
 
99
        return ret;
 
100
    },
 
101
 
 
102
    /**
 
103
     * Retrieves a set of nodes based on a given CSS selector. 
 
104
     * @method query
 
105
     *
 
106
     * @param {string} selector The CSS Selector to test the node against.
 
107
     * @param {HTMLElement} root optional An HTMLElement to start the query from. Defaults to Y.config.doc
 
108
     * @param {Boolean} firstOnly optional Whether or not to return only the first match.
 
109
     * @return {Array} An array of nodes that match the given selector.
 
110
     * @static
 
111
     */
 
112
    query: function(selector, root, firstOnly, skipNative) {
 
113
        root = root || Y.config.doc;
 
114
        var ret = [],
 
115
            useNative = (Y.Selector.useNative && document.querySelector && !skipNative),
 
116
            queries = [[selector, root]],
 
117
            query,
 
118
            result,
 
119
            i,
 
120
            fn = (useNative) ? Y.Selector._nativeQuery : Y.Selector._bruteQuery;
 
121
 
 
122
        if (selector && fn) {
 
123
            // split group into seperate queries
 
124
            if (!skipNative && // already done if skipping
 
125
                    (!useNative || root.tagName)) { // split native when element scoping is needed
 
126
                queries = Selector._splitQueries(selector, root);
 
127
            }
 
128
 
 
129
            for (i = 0; (query = queries[i++]);) {
 
130
                result = fn(query[0], query[1], firstOnly);
 
131
                if (!firstOnly) { // coerce DOM Collection to Array
 
132
                    result = Y.Array(result, 0, true);
 
133
                }
 
134
                if (result) {
 
135
                    ret = ret.concat(result);
 
136
                }
 
137
            }
 
138
 
 
139
            if (queries.length > 1) { // remove dupes and sort by doc order 
 
140
                ret = Selector._sort(Selector._deDupe(ret));
 
141
            }
 
142
        }
 
143
 
 
144
        return (firstOnly) ? (ret[0] || null) : ret;
 
145
 
 
146
    },
 
147
 
 
148
    // allows element scoped queries to begin with combinator
 
149
    // e.g. query('> p', document.body) === query('body > p')
 
150
    _splitQueries: function(selector, node) {
 
151
        var groups = selector.split(','),
 
152
            queries = [],
 
153
            prefix = '',
 
154
            i, len;
 
155
 
 
156
        if (node) {
 
157
            // enforce for element scoping
 
158
            if (node.tagName) {
 
159
                node.id = node.id || Y.guid();
 
160
                prefix = '#' + node.id + ' ';
 
161
            }
 
162
 
 
163
            for (i = 0, len = groups.length; i < len; ++i) {
 
164
                selector =  prefix + groups[i];
 
165
                queries.push([selector, node]);
 
166
            }
 
167
        }
 
168
 
 
169
        return queries;
 
170
    },
 
171
 
 
172
    _nativeQuery: function(selector, root, one) {
 
173
        try {
 
174
            return root['querySelector' + (one ? '' : 'All')](selector);
 
175
        } catch(e) { // fallback to brute if available
 
176
            return Y.Selector.query(selector, root, one, true); // redo with skipNative true
 
177
        }
 
178
    },
 
179
 
 
180
    filter: function(nodes, selector) {
 
181
        var ret = [],
 
182
            i, node;
 
183
 
 
184
        if (nodes && selector) {
 
185
            for (i = 0; (node = nodes[i++]);) {
 
186
                if (Y.Selector.test(node, selector)) {
 
187
                    ret[ret.length] = node;
 
188
                }
 
189
            }
 
190
        } else {
 
191
        }
 
192
 
 
193
        return ret;
 
194
    },
 
195
 
 
196
    test: function(node, selector, root) {
 
197
        var ret = false,
 
198
            groups = selector.split(','),
 
199
            item,
 
200
            i, group;
 
201
 
 
202
        if (node && node.tagName) { // only test HTMLElements
 
203
            root = root || node.ownerDocument;
 
204
 
 
205
            if (!node.id) {
 
206
                node.id = TMP_PREFIX + g_counter++;
 
207
            }
 
208
            for (i = 0; (group = groups[i++]);) { // TODO: off-dom test
 
209
                group += '#' + node.id; // add ID for uniqueness
 
210
                item = Y.Selector.query(group, root, true);
 
211
                ret = (item === node);
 
212
                if (ret) {
 
213
                    break;
 
214
                }
 
215
            }
 
216
        }
 
217
 
 
218
        return ret;
 
219
    }
 
220
};
 
221
 
 
222
Y.mix(Y.Selector, Selector, true);
 
223
 
 
224
})(Y);
 
225
 
 
226
 
 
227
}, '3.0.0' ,{requires:['dom-base']});
 
228
YUI.add('selector-css2', function(Y) {
 
229
 
 
230
/**
 
231
 * The selector module provides helper methods allowing CSS2 Selectors to be used with DOM elements.
 
232
 * @module dom
 
233
 * @submodule selector-css2
 
234
 * @for Selector
 
235
 */
 
236
 
 
237
/**
 
238
 * Provides helper methods for collecting and filtering DOM elements.
 
239
 */
 
240
 
 
241
var PARENT_NODE = 'parentNode',
 
242
    TAG_NAME = 'tagName',
 
243
    ATTRIBUTES = 'attributes',
 
244
    COMBINATOR = 'combinator',
 
245
    PSEUDOS = 'pseudos',
 
246
 
 
247
    Selector = Y.Selector,
 
248
 
 
249
    SelectorCSS2 = {
 
250
        SORT_RESULTS: true,
 
251
        _children: function(node, tag) {
 
252
            var ret = node.children,
 
253
                i,
 
254
                children = [],
 
255
                childNodes,
 
256
                child;
 
257
 
 
258
            if (node.children && tag && node.children.tags) {
 
259
                children = node.children.tags(tag);
 
260
            } else if ((!ret && node[TAG_NAME]) || (ret && tag)) { // only HTMLElements have children
 
261
                childNodes = ret || node.childNodes;
 
262
                ret = [];
 
263
                for (i = 0; (child = childNodes[i++]);) {
 
264
                    if (child.tagName) {
 
265
                        if (!tag || tag === child.tagName) {
 
266
                            ret.push(child);
 
267
                        }
 
268
                    }
 
269
                }
 
270
            }
 
271
 
 
272
            return ret || [];
 
273
        },
 
274
 
 
275
        _regexCache: {},
 
276
 
 
277
        _re: {
 
278
            attr: /(\[.*\])/g,
 
279
            pseudos: /:([\-\w]+(?:\(?:['"]?(.+)['"]?\)))*/i
 
280
        },
 
281
 
 
282
        /**
 
283
         * Mapping of shorthand tokens to corresponding attribute selector 
 
284
         * @property shorthand
 
285
         * @type object
 
286
         */
 
287
        shorthand: {
 
288
            '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]',
 
289
            '\\.(-?[_a-z]+[-\\w]*)': '[className~=$1]'
 
290
        },
 
291
 
 
292
        /**
 
293
         * List of operators and corresponding boolean functions. 
 
294
         * These functions are passed the attribute and the current node's value of the attribute.
 
295
         * @property operators
 
296
         * @type object
 
297
         */
 
298
        operators: {
 
299
            '': function(node, attr) { return Y.DOM.getAttribute(node, attr) !== ''; }, // Just test for existence of attribute
 
300
            //'': '.+',
 
301
            //'=': '^{val}$', // equality
 
302
            '~=': '(?:^|\\s+){val}(?:\\s+|$)', // space-delimited
 
303
            '|=': '^{val}-?' // optional hyphen-delimited
 
304
        },
 
305
 
 
306
        pseudos: {
 
307
           'first-child': function(node) { 
 
308
                return Y.Selector._children(node[PARENT_NODE])[0] === node; 
 
309
            } 
 
310
        },
 
311
 
 
312
        _bruteQuery: function(selector, root, firstOnly) {
 
313
            var ret = [],
 
314
                nodes = [],
 
315
                tokens = Selector._tokenize(selector),
 
316
                token = tokens[tokens.length - 1],
 
317
                rootDoc = Y.DOM._getDoc(root),
 
318
                id,
 
319
                className,
 
320
                tagName;
 
321
 
 
322
 
 
323
            // if we have an initial ID, set to root when in document
 
324
            if (tokens[0] && rootDoc === root &&  
 
325
                    (id = tokens[0].id) &&
 
326
                    rootDoc.getElementById(id)) {
 
327
                root = rootDoc.getElementById(id);
 
328
            }
 
329
 
 
330
            if (token) {
 
331
                // prefilter nodes
 
332
                id = token.id;
 
333
                className = token.className;
 
334
                tagName = token.tagName || '*';
 
335
 
 
336
                // try ID first
 
337
                if (id) {
 
338
                    if (rootDoc.getElementById(id)) { // if in document
 
339
                    nodes = [rootDoc.getElementById(id)]; // TODO: DOM.byId?
 
340
                }
 
341
                // try className if supported
 
342
                } else if (className) {
 
343
                    nodes = root.getElementsByClassName(className);
 
344
                } else if (tagName) { // default to tagName
 
345
                    nodes = root.getElementsByTagName(tagName || '*');
 
346
                }
 
347
 
 
348
                if (nodes.length) {
 
349
                    ret = Selector._filterNodes(nodes, tokens, firstOnly);
 
350
                }
 
351
            }
 
352
 
 
353
            return ret;
 
354
        },
 
355
        
 
356
        _filterNodes: function(nodes, tokens, firstOnly) {
 
357
            var i = 0,
 
358
                j,
 
359
                len = tokens.length,
 
360
                n = len - 1,
 
361
                result = [],
 
362
                node = nodes[0],
 
363
                tmpNode = node,
 
364
                getters = Y.Selector.getters,
 
365
                operator,
 
366
                combinator,
 
367
                token,
 
368
                path,
 
369
                pass,
 
370
                //FUNCTION = 'function',
 
371
                value,
 
372
                tests,
 
373
                test;
 
374
 
 
375
            //do {
 
376
            for (i = 0; (tmpNode = node = nodes[i++]);) {
 
377
                n = len - 1;
 
378
                path = null;
 
379
                
 
380
                testLoop:
 
381
                while (tmpNode && tmpNode.tagName) {
 
382
                    token = tokens[n];
 
383
                    tests = token.tests;
 
384
                    j = tests.length;
 
385
                    if (j && !pass) {
 
386
                        while ((test = tests[--j])) {
 
387
                            operator = test[1];
 
388
                            if (getters[test[0]]) {
 
389
                                value = getters[test[0]](tmpNode, test[0]);
 
390
                            } else {
 
391
                                value = tmpNode[test[0]];
 
392
                                // use getAttribute for non-standard attributes
 
393
                                if (value === undefined && tmpNode.getAttribute) {
 
394
                                    value = tmpNode.getAttribute(test[0]);
 
395
                                }
 
396
                            }
 
397
 
 
398
                            if ((operator === '=' && value !== test[2]) ||  // fast path for equality
 
399
                                (operator.test && !operator.test(value)) ||  // regex test
 
400
                                (operator.call && !operator(tmpNode, test[0]))) { // function test
 
401
 
 
402
                                // skip non element nodes or non-matching tags
 
403
                                if ((tmpNode = tmpNode[path])) {
 
404
                                    while (tmpNode &&
 
405
                                        (!tmpNode.tagName ||
 
406
                                            (token.tagName && token.tagName !== tmpNode.tagName))
 
407
                                    ) {
 
408
                                        tmpNode = tmpNode[path]; 
 
409
                                    }
 
410
                                }
 
411
                                continue testLoop;
 
412
                            }
 
413
                        }
 
414
                    }
 
415
 
 
416
                    n--; // move to next token
 
417
                    // now that we've passed the test, move up the tree by combinator
 
418
                    if (!pass && (combinator = token.combinator)) {
 
419
                        path = combinator.axis;
 
420
                        tmpNode = tmpNode[path];
 
421
 
 
422
                        // skip non element nodes
 
423
                        while (tmpNode && !tmpNode.tagName) {
 
424
                            tmpNode = tmpNode[path]; 
 
425
                        }
 
426
 
 
427
                        if (combinator.direct) { // one pass only
 
428
                            path = null; 
 
429
                        }
 
430
 
 
431
                    } else { // success if we made it this far
 
432
                        result.push(node);
 
433
                        if (firstOnly) {
 
434
                            return result;
 
435
                        }
 
436
                        break;
 
437
                    }
 
438
                }
 
439
            }// while (tmpNode = node = nodes[++i]);
 
440
            node = tmpNode = null;
 
441
            return result;
 
442
        },
 
443
 
 
444
        _getRegExp: function(str, flags) {
 
445
            var regexCache = Selector._regexCache;
 
446
            flags = flags || '';
 
447
            if (!regexCache[str + flags]) {
 
448
                regexCache[str + flags] = new RegExp(str, flags);
 
449
            }
 
450
            return regexCache[str + flags];
 
451
        },
 
452
 
 
453
        combinators: {
 
454
            ' ': {
 
455
                axis: 'parentNode'
 
456
            },
 
457
 
 
458
            '>': {
 
459
                axis: 'parentNode',
 
460
                direct: true
 
461
            },
 
462
 
 
463
 
 
464
            '+': {
 
465
                axis: 'previousSibling',
 
466
                direct: true
 
467
            }
 
468
        },
 
469
 
 
470
        _parsers: [
 
471
            {
 
472
                name: ATTRIBUTES,
 
473
                re: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^\]]*?)['"]?\]/i,
 
474
                fn: function(match, token) {
 
475
                    var operator = match[2] || '',
 
476
                        operators = Y.Selector.operators,
 
477
                        test;
 
478
 
 
479
                    // add prefiltering for ID and CLASS
 
480
                    if ((match[1] === 'id' && operator === '=') ||
 
481
                            (match[1] === 'className' &&
 
482
                            document.getElementsByClassName &&
 
483
                            (operator === '~=' || operator === '='))) {
 
484
                        token.prefilter = match[1];
 
485
                        token[match[1]] = match[3];
 
486
                    }
 
487
 
 
488
                    // add tests
 
489
                    if (operator in operators) {
 
490
                        test = operators[operator];
 
491
                        if (typeof test === 'string') {
 
492
                            test = Y.Selector._getRegExp(test.replace('{val}', match[3]));
 
493
                        }
 
494
                        match[2] = test;
 
495
                    }
 
496
                    if (!token.last || token.prefilter !== match[1]) {
 
497
                        return match.slice(1);
 
498
                    }
 
499
                }
 
500
 
 
501
            },
 
502
            {
 
503
                name: TAG_NAME,
 
504
                re: /^((?:-?[_a-z]+[\w-]*)|\*)/i,
 
505
                fn: function(match, token) {
 
506
                    var tag = match[1].toUpperCase();
 
507
                    token.tagName = tag;
 
508
 
 
509
                    if (tag !== '*' && (!token.last || token.prefilter)) {
 
510
                        return [TAG_NAME, '=', tag];
 
511
                    }
 
512
                    if (!token.prefilter) {
 
513
                        token.prefilter = 'tagName';
 
514
                    }
 
515
                }
 
516
            },
 
517
            {
 
518
                name: COMBINATOR,
 
519
                re: /^\s*([>+~]|\s)\s*/,
 
520
                fn: function(match, token) {
 
521
                }
 
522
            },
 
523
            {
 
524
                name: PSEUDOS,
 
525
                re: /^:([\-\w]+)(?:\(['"]?(.+)['"]?\))*/i,
 
526
                fn: function(match, token) {
 
527
                    var test = Selector[PSEUDOS][match[1]];
 
528
                    if (test) { // reorder match array
 
529
                        return [match[2], test];
 
530
                    } else { // selector token not supported (possibly missing CSS3 module)
 
531
                        return false;
 
532
                    }
 
533
                }
 
534
            }
 
535
            ],
 
536
 
 
537
        _getToken: function(token) {
 
538
            return {
 
539
                tagName: null,
 
540
                id: null,
 
541
                className: null,
 
542
                attributes: {},
 
543
                combinator: null,
 
544
                tests: []
 
545
            };
 
546
        },
 
547
 
 
548
        /**
 
549
            Break selector into token units per simple selector.
 
550
            Combinator is attached to the previous token.
 
551
         */
 
552
        _tokenize: function(selector) {
 
553
            selector = selector || '';
 
554
            selector = Selector._replaceShorthand(Y.Lang.trim(selector)); 
 
555
            var token = Selector._getToken(),     // one token per simple selector (left selector holds combinator)
 
556
                query = selector, // original query for debug report
 
557
                tokens = [],    // array of tokens
 
558
                found = false,  // whether or not any matches were found this pass
 
559
                match,         // the regex match
 
560
                test,
 
561
                i, parser;
 
562
 
 
563
            /*
 
564
                Search for selector patterns, store, and strip them from the selector string
 
565
                until no patterns match (invalid selector) or we run out of chars.
 
566
 
 
567
                Multiple attributes and pseudos are allowed, in any order.
 
568
                for example:
 
569
                    'form:first-child[type=button]:not(button)[lang|=en]'
 
570
            */
 
571
            outer:
 
572
            do {
 
573
                found = false; // reset after full pass
 
574
                for (i = 0; (parser = Selector._parsers[i++]);) {
 
575
                    if ( (match = parser.re.exec(selector)) ) { // note assignment
 
576
                        if (parser !== COMBINATOR ) {
 
577
                            token.selector = selector;
 
578
                        }
 
579
                        selector = selector.replace(match[0], ''); // strip current match from selector
 
580
                        if (!selector.length) {
 
581
                            token.last = true;
 
582
                        }
 
583
 
 
584
                        if (Selector._attrFilters[match[1]]) { // convert class to className, etc.
 
585
                            match[1] = Selector._attrFilters[match[1]];
 
586
                        }
 
587
 
 
588
                        test = parser.fn(match, token);
 
589
                        if (test === false) { // selector not supported
 
590
                            found = false;
 
591
                            break outer;
 
592
                        } else if (test) {
 
593
                            token.tests.push(test);
 
594
                        }
 
595
 
 
596
                        if (!selector.length || parser.name === COMBINATOR) {
 
597
                            tokens.push(token);
 
598
                            token = Selector._getToken(token);
 
599
                            if (parser.name === COMBINATOR) {
 
600
                                token.combinator = Y.Selector.combinators[match[1]];
 
601
                            }
 
602
                        }
 
603
                        found = true;
 
604
                    }
 
605
                }
 
606
            } while (found && selector.length);
 
607
 
 
608
            if (!found || selector.length) { // not fully parsed
 
609
                tokens = [];
 
610
            }
 
611
            return tokens;
 
612
        },
 
613
 
 
614
        _replaceShorthand: function(selector) {
 
615
            var shorthand = Selector.shorthand,
 
616
                attrs = selector.match(Selector._re.attr), // pull attributes to avoid false pos on "." and "#"
 
617
                pseudos = selector.match(Selector._re.pseudos), // pull attributes to avoid false pos on "." and "#"
 
618
                re, i, len;
 
619
 
 
620
            if (pseudos) {
 
621
                selector = selector.replace(Selector._re.pseudos, '!!REPLACED_PSEUDO!!');
 
622
            }
 
623
 
 
624
            if (attrs) {
 
625
                selector = selector.replace(Selector._re.attr, '!!REPLACED_ATTRIBUTE!!');
 
626
            }
 
627
 
 
628
            for (re in shorthand) {
 
629
                if (shorthand.hasOwnProperty(re)) {
 
630
                    selector = selector.replace(Selector._getRegExp(re, 'gi'), shorthand[re]);
 
631
                }
 
632
            }
 
633
 
 
634
            if (attrs) {
 
635
                for (i = 0, len = attrs.length; i < len; ++i) {
 
636
                    selector = selector.replace('!!REPLACED_ATTRIBUTE!!', attrs[i]);
 
637
                }
 
638
            }
 
639
            if (pseudos) {
 
640
                for (i = 0, len = pseudos.length; i < len; ++i) {
 
641
                    selector = selector.replace('!!REPLACED_PSEUDO!!', pseudos[i]);
 
642
                }
 
643
            }
 
644
            return selector;
 
645
        },
 
646
 
 
647
        _attrFilters: {
 
648
            'class': 'className',
 
649
            'for': 'htmlFor'
 
650
        },
 
651
 
 
652
        getters: {
 
653
            href: function(node, attr) {
 
654
                return Y.DOM.getAttribute(node, attr);
 
655
            }
 
656
        }
 
657
    };
 
658
 
 
659
Y.mix(Y.Selector, SelectorCSS2, true);
 
660
Y.Selector.getters.src = Y.Selector.getters.rel = Y.Selector.getters.href;
 
661
 
 
662
// IE wants class with native queries
 
663
if (Y.Selector.useNative && document.querySelector) {
 
664
    Y.Selector.shorthand['\\.(-?[_a-z]+[-\\w]*)'] = '[class~=$1]';
 
665
}
 
666
 
 
667
 
 
668
 
 
669
}, '3.0.0' ,{requires:['selector-native']});
 
670
 
 
671
 
 
672
YUI.add('selector', function(Y){}, '3.0.0' ,{use:['selector-native', 'selector-css2']});
 
673