~ubuntu-branches/ubuntu/jaunty/moodle/jaunty

« back to all changes in this revision

Viewing changes to lib/yui/selector/selector-beta.js

  • Committer: Bazaar Package Importer
  • Author(s): Jordan Mantha, Matt Oquist
  • Date: 2009-02-25 15:16:22 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20090225151622-0ekt1liwhv2obfza
Tags: 1.9.4.dfsg-0ubuntu1
* Merge with Debian git (Closes LP: #322961, #239481, #334611):
  - use Ubuntu's smarty lib directory for linking
  - use internal yui library 
  - add update-notifier support back in

[Matt Oquist]
  * renamed prerm script
  * significantly rewrote postinst and other maintainer scripts to improve
    user experience and package maintainability
    (Closes LP: #225662, #325450, #327843, #303078, #234609)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.net/yui/license.txt
 
5
version: 2.6.0
 
6
*/
 
7
/**
 
8
 * The selector module provides helper methods allowing CSS3 Selectors to be used with DOM elements.
 
9
 * @module selector
 
10
 * @title Selector Utility
 
11
 * @namespace YAHOO.util
 
12
 * @requires yahoo, dom
 
13
 */
 
14
 
 
15
(function() {
 
16
/**
 
17
 * Provides helper methods for collecting and filtering DOM elements.
 
18
 * @namespace YAHOO.util
 
19
 * @class Selector
 
20
 * @static
 
21
 */
 
22
var Selector = function() {};
 
23
 
 
24
var Y = YAHOO.util;
 
25
 
 
26
var reNth = /^(?:([-]?\d*)(n){1}|(odd|even)$)*([-+]?\d*)$/;
 
27
 
 
28
Selector.prototype = {
 
29
    /**
 
30
     * Default document for use queries 
 
31
     * @property document
 
32
     * @type object
 
33
     * @default window.document
 
34
     */
 
35
    document: window.document,
 
36
    /**
 
37
     * Mapping of attributes to aliases, normally to work around HTMLAttributes
 
38
     * that conflict with JS reserved words.
 
39
     * @property attrAliases
 
40
     * @type object
 
41
     */
 
42
    attrAliases: {
 
43
    },
 
44
 
 
45
    /**
 
46
     * Mapping of shorthand tokens to corresponding attribute selector 
 
47
     * @property shorthand
 
48
     * @type object
 
49
     */
 
50
    shorthand: {
 
51
        //'(?:(?:[^\\)\\]\\s*>+~,]+)(?:-?[_a-z]+[-\\w]))+#(-?[_a-z]+[-\\w]*)': '[id=$1]',
 
52
        '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]',
 
53
        '\\.(-?[_a-z]+[-\\w]*)': '[class~=$1]'
 
54
    },
 
55
 
 
56
    /**
 
57
     * List of operators and corresponding boolean functions. 
 
58
     * These functions are passed the attribute and the current node's value of the attribute.
 
59
     * @property operators
 
60
     * @type object
 
61
     */
 
62
    operators: {
 
63
        '=': function(attr, val) { return attr === val; }, // Equality
 
64
        '!=': function(attr, val) { return attr !== val; }, // Inequality
 
65
        '~=': function(attr, val) { // Match one of space seperated words 
 
66
            var s = ' ';
 
67
            return (s + attr + s).indexOf((s + val + s)) > -1;
 
68
        },
 
69
        '|=': function(attr, val) { return getRegExp('^' + val + '[-]?').test(attr); }, // Match start with value followed by optional hyphen
 
70
        '^=': function(attr, val) { return attr.indexOf(val) === 0; }, // Match starts with value
 
71
        '$=': function(attr, val) { return attr.lastIndexOf(val) === attr.length - val.length; }, // Match ends with value
 
72
        '*=': function(attr, val) { return attr.indexOf(val) > -1; }, // Match contains value as substring 
 
73
        '': function(attr, val) { return attr; } // Just test for existence of attribute
 
74
    },
 
75
 
 
76
    /**
 
77
     * List of pseudo-classes and corresponding boolean functions. 
 
78
     * These functions are called with the current node, and any value that was parsed with the pseudo regex.
 
79
     * @property pseudos
 
80
     * @type object
 
81
     */
 
82
    pseudos: {
 
83
        'root': function(node) {
 
84
            return node === node.ownerDocument.documentElement;
 
85
        },
 
86
 
 
87
        'nth-child': function(node, val) {
 
88
            return getNth(node, val);
 
89
        },
 
90
 
 
91
        'nth-last-child': function(node, val) {
 
92
            return getNth(node, val, null, true);
 
93
        },
 
94
 
 
95
        'nth-of-type': function(node, val) {
 
96
            return getNth(node, val, node.tagName);
 
97
        },
 
98
         
 
99
        'nth-last-of-type': function(node, val) {
 
100
            return getNth(node, val, node.tagName, true);
 
101
        },
 
102
         
 
103
        'first-child': function(node) {
 
104
            return getChildren(node.parentNode)[0] === node;
 
105
        },
 
106
 
 
107
        'last-child': function(node) {
 
108
            var children = getChildren(node.parentNode);
 
109
            return children[children.length - 1] === node;
 
110
        },
 
111
 
 
112
        'first-of-type': function(node, val) {
 
113
            return getChildren(node.parentNode, node.tagName.toLowerCase())[0];
 
114
        },
 
115
         
 
116
        'last-of-type': function(node, val) {
 
117
            var children = getChildren(node.parentNode, node.tagName.toLowerCase());
 
118
            return children[children.length - 1];
 
119
        },
 
120
         
 
121
        'only-child': function(node) {
 
122
            var children = getChildren(node.parentNode);
 
123
            return children.length === 1 && children[0] === node;
 
124
        },
 
125
 
 
126
        'only-of-type': function(node) {
 
127
            return getChildren(node.parentNode, node.tagName.toLowerCase()).length === 1;
 
128
        },
 
129
 
 
130
        'empty': function(node) {
 
131
            return node.childNodes.length === 0;
 
132
        },
 
133
 
 
134
        'not': function(node, simple) {
 
135
            return !Selector.test(node, simple);
 
136
        },
 
137
 
 
138
        'contains': function(node, str) {
 
139
            var text = node.innerText || node.textContent || '';
 
140
            return text.indexOf(str) > -1;
 
141
        },
 
142
        'checked': function(node) {
 
143
            return node.checked === true;
 
144
        }
 
145
    },
 
146
 
 
147
    /**
 
148
     * Test if the supplied node matches the supplied selector.
 
149
     * @method test
 
150
     *
 
151
     * @param {HTMLElement | String} node An id or node reference to the HTMLElement being tested.
 
152
     * @param {string} selector The CSS Selector to test the node against.
 
153
     * @return{boolean} Whether or not the node matches the selector.
 
154
     * @static
 
155
    
 
156
     */
 
157
    test: function(node, selector) {
 
158
        node = Selector.document.getElementById(node) || node;
 
159
 
 
160
        if (!node) {
 
161
            return false;
 
162
        }
 
163
 
 
164
        var groups = selector ? selector.split(',') : [];
 
165
        if (groups.length) {
 
166
            for (var i = 0, len = groups.length; i < len; ++i) {
 
167
                if ( rTestNode(node, groups[i]) ) { // passes if ANY group matches
 
168
                    return true;
 
169
                }
 
170
            }
 
171
            return false;
 
172
        }
 
173
        return rTestNode(node, selector);
 
174
    },
 
175
 
 
176
    /**
 
177
     * Filters a set of nodes based on a given CSS selector. 
 
178
     * @method filter
 
179
     *
 
180
     * @param {array} nodes A set of nodes/ids to filter. 
 
181
     * @param {string} selector The selector used to test each node.
 
182
     * @return{array} An array of nodes from the supplied array that match the given selector.
 
183
     * @static
 
184
     */
 
185
    filter: function(nodes, selector) {
 
186
        nodes = nodes || [];
 
187
 
 
188
        var node,
 
189
            result = [],
 
190
            tokens = tokenize(selector);
 
191
 
 
192
        if (!nodes.item) { // if not HTMLCollection, handle arrays of ids and/or nodes
 
193
            for (var i = 0, len = nodes.length; i < len; ++i) {
 
194
                if (!nodes[i].tagName) { // tagName limits to HTMLElements 
 
195
                    node = Selector.document.getElementById(nodes[i]);
 
196
                    if (node) { // skip IDs that return null 
 
197
                        nodes[i] = node;
 
198
                    } else {
 
199
                    }
 
200
                }
 
201
            }
 
202
        }
 
203
        result = rFilter(nodes, tokenize(selector)[0]);
 
204
        clearParentCache();
 
205
        return result;
 
206
    },
 
207
 
 
208
    /**
 
209
     * Retrieves a set of nodes based on a given CSS selector. 
 
210
     * @method query
 
211
     *
 
212
     * @param {string} selector The CSS Selector to test the node against.
 
213
     * @param {HTMLElement | String} root optional An id or HTMLElement to start the query from. Defaults to Selector.document.
 
214
     * @param {Boolean} firstOnly optional Whether or not to return only the first match.
 
215
     * @return {Array} An array of nodes that match the given selector.
 
216
     * @static
 
217
     */
 
218
    query: function(selector, root, firstOnly) {
 
219
        var result = query(selector, root, firstOnly);
 
220
        return result;
 
221
    }
 
222
};
 
223
 
 
224
var query = function(selector, root, firstOnly, deDupe) {
 
225
    var result =  (firstOnly) ? null : [];
 
226
    if (!selector) {
 
227
        return result;
 
228
    }
 
229
 
 
230
    var groups = selector.split(','); // TODO: handle comma in attribute/pseudo
 
231
 
 
232
    if (groups.length > 1) {
 
233
        var found;
 
234
        for (var i = 0, len = groups.length; i < len; ++i) {
 
235
            found = arguments.callee(groups[i], root, firstOnly, true);
 
236
            result = firstOnly ? found : result.concat(found); 
 
237
        }
 
238
        clearFoundCache();
 
239
        return result;
 
240
    }
 
241
 
 
242
    if (root && !root.nodeName) { // assume ID
 
243
        root = Selector.document.getElementById(root);
 
244
        if (!root) {
 
245
            return result;
 
246
        }
 
247
    }
 
248
 
 
249
    root = root || Selector.document;
 
250
    var tokens = tokenize(selector);
 
251
    var idToken = tokens[getIdTokenIndex(tokens)],
 
252
        nodes = [],
 
253
        node,
 
254
        id,
 
255
        token = tokens.pop() || {};
 
256
        
 
257
    if (idToken) {
 
258
        id = getId(idToken.attributes);
 
259
    }
 
260
 
 
261
    // use id shortcut when possible
 
262
    if (id) {
 
263
        node = Selector.document.getElementById(id);
 
264
 
 
265
        if (node && (root.nodeName == '#document' || contains(node, root))) {
 
266
            if ( rTestNode(node, null, idToken) ) {
 
267
                if (idToken === token) {
 
268
                    nodes = [node]; // simple selector
 
269
                } else {
 
270
                    root = node; // start from here
 
271
                }
 
272
            }
 
273
        } else {
 
274
            return result;
 
275
        }
 
276
    }
 
277
 
 
278
    if (root && !nodes.length) {
 
279
        nodes = root.getElementsByTagName(token.tag);
 
280
    }
 
281
 
 
282
    if (nodes.length) {
 
283
        result = rFilter(nodes, token, firstOnly, deDupe); 
 
284
    }
 
285
 
 
286
    clearParentCache();
 
287
    return result;
 
288
};
 
289
 
 
290
var contains = function() {
 
291
    if (document.documentElement.contains && !YAHOO.env.ua.webkit < 422)  { // IE & Opera, Safari < 3 contains is broken
 
292
        return function(needle, haystack) {
 
293
            return haystack.contains(needle);
 
294
        };
 
295
    } else if ( document.documentElement.compareDocumentPosition ) { // gecko
 
296
        return function(needle, haystack) {
 
297
            return !!(haystack.compareDocumentPosition(needle) & 16);
 
298
        };
 
299
    } else  { // Safari < 3
 
300
        return function(needle, haystack) {
 
301
            var parent = needle.parentNode;
 
302
            while (parent) {
 
303
                if (needle === parent) {
 
304
                    return true;
 
305
                }
 
306
                parent = parent.parentNode;
 
307
            } 
 
308
            return false;
 
309
        }; 
 
310
    }
 
311
}();
 
312
 
 
313
var rFilter = function(nodes, token, firstOnly, deDupe) {
 
314
    var result = firstOnly ? null : [];
 
315
 
 
316
    for (var i = 0, len = nodes.length; i < len; i++) {
 
317
        if (! rTestNode(nodes[i], '', token, deDupe)) {
 
318
            continue;
 
319
        }
 
320
 
 
321
        if (firstOnly) {
 
322
            return nodes[i];
 
323
        }
 
324
        if (deDupe) {
 
325
            if (nodes[i]._found) {
 
326
                continue;
 
327
            }
 
328
            nodes[i]._found = true;
 
329
            foundCache[foundCache.length] = nodes[i];
 
330
        }
 
331
 
 
332
        result[result.length] = nodes[i];
 
333
    }
 
334
 
 
335
    return result;
 
336
};
 
337
 
 
338
var rTestNode = function(node, selector, token, deDupe) {
 
339
    token = token || tokenize(selector).pop() || {};
 
340
 
 
341
    if (!node.tagName ||
 
342
        (token.tag !== '*' && node.tagName.toUpperCase() !== token.tag) ||
 
343
        (deDupe && node._found) ) {
 
344
        return false;
 
345
    }
 
346
 
 
347
    if (token.attributes.length) {
 
348
        var attribute;
 
349
        for (var i = 0, len = token.attributes.length; i < len; ++i) {
 
350
            attribute = node.getAttribute(token.attributes[i][0], 2);
 
351
            if (attribute === null || attribute === undefined) {
 
352
                return false;
 
353
            }
 
354
            if ( Selector.operators[token.attributes[i][1]] &&
 
355
                    !Selector.operators[token.attributes[i][1]](attribute, token.attributes[i][2])) {
 
356
                return false;
 
357
            }
 
358
        }
 
359
    }
 
360
 
 
361
    if (token.pseudos.length) {
 
362
        for (var i = 0, len = token.pseudos.length; i < len; ++i) {
 
363
            if (Selector.pseudos[token.pseudos[i][0]] &&
 
364
                    !Selector.pseudos[token.pseudos[i][0]](node, token.pseudos[i][1])) {
 
365
                return false;
 
366
            }
 
367
        }
 
368
    }
 
369
 
 
370
    return (token.previous && token.previous.combinator !== ',') ?
 
371
            combinators[token.previous.combinator](node, token) :
 
372
            true;
 
373
};
 
374
 
 
375
 
 
376
var foundCache = [];
 
377
var parentCache = [];
 
378
var regexCache = {};
 
379
 
 
380
var clearFoundCache = function() {
 
381
    for (var i = 0, len = foundCache.length; i < len; ++i) {
 
382
        try { // IE no like delete
 
383
            delete foundCache[i]._found;
 
384
        } catch(e) {
 
385
            foundCache[i].removeAttribute('_found');
 
386
        }
 
387
    }
 
388
    foundCache = [];
 
389
};
 
390
 
 
391
var clearParentCache = function() {
 
392
    if (!document.documentElement.children) { // caching children lookups for gecko
 
393
        return function() {
 
394
            for (var i = 0, len = parentCache.length; i < len; ++i) {
 
395
                delete parentCache[i]._children;
 
396
            }
 
397
            parentCache = [];
 
398
        };
 
399
    } else return function() {}; // do nothing
 
400
}();
 
401
 
 
402
var getRegExp = function(str, flags) {
 
403
    flags = flags || '';
 
404
    if (!regexCache[str + flags]) {
 
405
        regexCache[str + flags] = new RegExp(str, flags);
 
406
    }
 
407
    return regexCache[str + flags];
 
408
};
 
409
 
 
410
var combinators = {
 
411
    ' ': function(node, token) {
 
412
        while (node = node.parentNode) {
 
413
            if (rTestNode(node, '', token.previous)) {
 
414
                return true;
 
415
            }
 
416
        }  
 
417
        return false;
 
418
    },
 
419
 
 
420
    '>': function(node, token) {
 
421
        return rTestNode(node.parentNode, null, token.previous);
 
422
    },
 
423
 
 
424
    '+': function(node, token) {
 
425
        var sib = node.previousSibling;
 
426
        while (sib && sib.nodeType !== 1) {
 
427
            sib = sib.previousSibling;
 
428
        }
 
429
 
 
430
        if (sib && rTestNode(sib, null, token.previous)) {
 
431
            return true; 
 
432
        }
 
433
        return false;
 
434
    },
 
435
 
 
436
    '~': function(node, token) {
 
437
        var sib = node.previousSibling;
 
438
        while (sib) {
 
439
            if (sib.nodeType === 1 && rTestNode(sib, null, token.previous)) {
 
440
                return true;
 
441
            }
 
442
            sib = sib.previousSibling;
 
443
        }
 
444
 
 
445
        return false;
 
446
    }
 
447
};
 
448
 
 
449
var getChildren = function() {
 
450
    if (document.documentElement.children) { // document for capability test
 
451
        return function(node, tag) {
 
452
            return (tag) ? node.children.tags(tag) : node.children || [];
 
453
        };
 
454
    } else {
 
455
        return function(node, tag) {
 
456
            if (node._children) {
 
457
                return node._children;
 
458
            }
 
459
            var children = [],
 
460
                childNodes = node.childNodes;
 
461
 
 
462
            for (var i = 0, len = childNodes.length; i < len; ++i) {
 
463
                if (childNodes[i].tagName) {
 
464
                    if (!tag || childNodes[i].tagName.toLowerCase() === tag) {
 
465
                        children[children.length] = childNodes[i];
 
466
                    }
 
467
                }
 
468
            }
 
469
            node._children = children;
 
470
            parentCache[parentCache.length] = node;
 
471
            return children;
 
472
        };
 
473
    }
 
474
}();
 
475
 
 
476
/*
 
477
    an+b = get every _a_th node starting at the _b_th
 
478
    0n+b = no repeat ("0" and "n" may both be omitted (together) , e.g. "0n+1" or "1", not "0+1"), return only the _b_th element
 
479
    1n+b =  get every element starting from b ("1" may may be omitted, e.g. "1n+0" or "n+0" or "n")
 
480
    an+0 = get every _a_th element, "0" may be omitted 
 
481
*/
 
482
var getNth = function(node, expr, tag, reverse) {
 
483
    if (tag) tag = tag.toLowerCase();
 
484
    reNth.test(expr);
 
485
    var a = parseInt(RegExp.$1, 10), // include every _a_ elements (zero means no repeat, just first _a_)
 
486
        n = RegExp.$2, // "n"
 
487
        oddeven = RegExp.$3, // "odd" or "even"
 
488
        b = parseInt(RegExp.$4, 10) || 0, // start scan from element _b_
 
489
        result = [];
 
490
 
 
491
    var siblings = getChildren(node.parentNode, tag);
 
492
 
 
493
    if (oddeven) {
 
494
        a = 2; // always every other
 
495
        op = '+';
 
496
        n = 'n';
 
497
        b = (oddeven === 'odd') ? 1 : 0;
 
498
    } else if ( isNaN(a) ) {
 
499
        a = (n) ? 1 : 0; // start from the first or no repeat
 
500
    }
 
501
 
 
502
    if (a === 0) { // just the first
 
503
        if (reverse) {
 
504
            b = siblings.length - b + 1; 
 
505
        }
 
506
 
 
507
        if (siblings[b - 1] === node) {
 
508
            return true;
 
509
        } else {
 
510
            return false;
 
511
        }
 
512
 
 
513
    } else if (a < 0) {
 
514
        reverse = !!reverse;
 
515
        a = Math.abs(a);
 
516
    }
 
517
 
 
518
    if (!reverse) {
 
519
        for (var i = b - 1, len = siblings.length; i < len; i += a) {
 
520
            if ( i >= 0 && siblings[i] === node ) {
 
521
                return true;
 
522
            }
 
523
        }
 
524
    } else {
 
525
        for (var i = siblings.length - b, len = siblings.length; i >= 0; i -= a) {
 
526
            if ( i < len && siblings[i] === node ) {
 
527
                return true;
 
528
            }
 
529
        }
 
530
    }
 
531
    return false;
 
532
};
 
533
 
 
534
var getId = function(attr) {
 
535
    for (var i = 0, len = attr.length; i < len; ++i) {
 
536
        if (attr[i][0] == 'id' && attr[i][1] === '=') {
 
537
            return attr[i][2];
 
538
        }
 
539
    }
 
540
};
 
541
 
 
542
var getIdTokenIndex = function(tokens) {
 
543
    for (var i = 0, len = tokens.length; i < len; ++i) {
 
544
        if (getId(tokens[i].attributes)) {
 
545
            return i;
 
546
        }
 
547
    }
 
548
    return -1;
 
549
};
 
550
 
 
551
var patterns = {
 
552
    tag: /^((?:-?[_a-z]+[\w-]*)|\*)/i,
 
553
    attributes: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^\]]*?)['"]?\]/i,
 
554
    //attributes: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^'"\]]*)['"]?\]*/i,
 
555
    pseudos: /^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i,
 
556
    combinator: /^\s*([>+~]|\s)\s*/
 
557
};
 
558
 
 
559
/**
 
560
    Break selector into token units per simple selector.
 
561
    Combinator is attached to left-hand selector.
 
562
 */
 
563
var tokenize = function(selector) {
 
564
    var token = {},     // one token per simple selector (left selector holds combinator)
 
565
        tokens = [],    // array of tokens
 
566
        id,             // unique id for the simple selector (if found)
 
567
        found = false,  // whether or not any matches were found this pass
 
568
        match;          // the regex match
 
569
 
 
570
    selector = replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes
 
571
 
 
572
    /*
 
573
        Search for selector patterns, store, and strip them from the selector string
 
574
        until no patterns match (invalid selector) or we run out of chars.
 
575
 
 
576
        Multiple attributes and pseudos are allowed, in any order.
 
577
        for example:
 
578
            'form:first-child[type=button]:not(button)[lang|=en]'
 
579
    */
 
580
    do {
 
581
        found = false; // reset after full pass
 
582
        for (var re in patterns) {
 
583
                if (!YAHOO.lang.hasOwnProperty(patterns, re)) {
 
584
                    continue;
 
585
                }
 
586
                if (re != 'tag' && re != 'combinator') { // only one allowed
 
587
                    token[re] = token[re] || [];
 
588
                }
 
589
            if (match = patterns[re].exec(selector)) { // note assignment
 
590
                found = true;
 
591
                if (re != 'tag' && re != 'combinator') { // only one allowed
 
592
                    //token[re] = token[re] || [];
 
593
 
 
594
                    // capture ID for fast path to element
 
595
                    if (re === 'attributes' && match[1] === 'id') {
 
596
                        token.id = match[3];
 
597
                    }
 
598
 
 
599
                    token[re].push(match.slice(1));
 
600
                } else { // single selector (tag, combinator)
 
601
                    token[re] = match[1];
 
602
                }
 
603
                selector = selector.replace(match[0], ''); // strip current match from selector
 
604
                if (re === 'combinator' || !selector.length) { // next token or done
 
605
                    token.attributes = fixAttributes(token.attributes);
 
606
                    token.pseudos = token.pseudos || [];
 
607
                    token.tag = token.tag ? token.tag.toUpperCase() : '*';
 
608
                    tokens.push(token);
 
609
 
 
610
                    token = { // prep next token
 
611
                        previous: token
 
612
                    };
 
613
                }
 
614
            }
 
615
        }
 
616
    } while (found);
 
617
 
 
618
    return tokens;
 
619
};
 
620
 
 
621
var fixAttributes = function(attr) {
 
622
    var aliases = Selector.attrAliases;
 
623
    attr = attr || [];
 
624
    for (var i = 0, len = attr.length; i < len; ++i) {
 
625
        if (aliases[attr[i][0]]) { // convert reserved words, etc
 
626
            attr[i][0] = aliases[attr[i][0]];
 
627
        }
 
628
        if (!attr[i][1]) { // use exists operator
 
629
            attr[i][1] = '';
 
630
        }
 
631
    }
 
632
    return attr;
 
633
};
 
634
 
 
635
var replaceShorthand = function(selector) {
 
636
    var shorthand = Selector.shorthand;
 
637
    var attrs = selector.match(patterns.attributes); // pull attributes to avoid false pos on "." and "#"
 
638
    if (attrs) {
 
639
        selector = selector.replace(patterns.attributes, 'REPLACED_ATTRIBUTE');
 
640
    }
 
641
    for (var re in shorthand) {
 
642
        if (!YAHOO.lang.hasOwnProperty(shorthand, re)) {
 
643
            continue;
 
644
        }
 
645
        selector = selector.replace(getRegExp(re, 'gi'), shorthand[re]);
 
646
    }
 
647
 
 
648
    if (attrs) {
 
649
        for (var i = 0, len = attrs.length; i < len; ++i) {
 
650
            selector = selector.replace('REPLACED_ATTRIBUTE', attrs[i]);
 
651
        }
 
652
    }
 
653
    return selector;
 
654
};
 
655
 
 
656
Selector = new Selector();
 
657
Selector.patterns = patterns;
 
658
Y.Selector = Selector;
 
659
 
 
660
if (YAHOO.env.ua.ie) { // rewrite class for IE (others use getAttribute('class')
 
661
    Y.Selector.attrAliases['class'] = 'className';
 
662
    Y.Selector.attrAliases['for'] = 'htmlFor';
 
663
}
 
664
 
 
665
})();
 
666
YAHOO.register("selector", YAHOO.util.Selector, {version: "2.6.0", build: "1321"});