~michael.nelson/ubuntu-webcatalog/1267731-import-sca-apps-error

« back to all changes in this revision

Viewing changes to src/webcatalog/static/yui/3.10.3/build/selector-css2/selector-css2-debug.js

  • Committer: Tarmac
  • Author(s): Stephen Stewart
  • Date: 2013-06-26 09:19:32 UTC
  • mfrom: (184.1.4 ubuntu-global-nav)
  • Revision ID: tarmac-20130626091932-8urtuli368k8p7ds
[r=beuno,jonas-drange] add ubuntu global nav to apps.ubuntu.com

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.10.3 (build 2fb5187)
 
3
Copyright 2013 Yahoo! Inc. All rights reserved.
 
4
Licensed under the BSD License.
 
5
http://yuilibrary.com/license/
 
6
*/
 
7
 
 
8
YUI.add('selector-css2', function (Y, NAME) {
 
9
 
 
10
/**
 
11
 * The selector module provides helper methods allowing CSS2 Selectors to be used with DOM elements.
 
12
 * @module dom
 
13
 * @submodule selector-css2
 
14
 * @for Selector
 
15
 */
 
16
 
 
17
/*
 
18
 * Provides helper methods for collecting and filtering DOM elements.
 
19
 */
 
20
 
 
21
var PARENT_NODE = 'parentNode',
 
22
    TAG_NAME = 'tagName',
 
23
    ATTRIBUTES = 'attributes',
 
24
    COMBINATOR = 'combinator',
 
25
    PSEUDOS = 'pseudos',
 
26
 
 
27
    Selector = Y.Selector,
 
28
 
 
29
    SelectorCSS2 = {
 
30
        _reRegExpTokens: /([\^\$\?\[\]\*\+\-\.\(\)\|\\])/,
 
31
        SORT_RESULTS: true,
 
32
 
 
33
        // TODO: better detection, document specific
 
34
        _isXML: (function() {
 
35
            var isXML = (Y.config.doc.createElement('div').tagName !== 'DIV');
 
36
            return isXML;
 
37
        }()),
 
38
 
 
39
        /**
 
40
         * Mapping of shorthand tokens to corresponding attribute selector 
 
41
         * @property shorthand
 
42
         * @type object
 
43
         */
 
44
        shorthand: {
 
45
            '\\#(-?[_a-z0-9]+[-\\w\\uE000]*)': '[id=$1]',
 
46
            '\\.(-?[_a-z]+[-\\w\\uE000]*)': '[className~=$1]'
 
47
        },
 
48
 
 
49
        /**
 
50
         * List of operators and corresponding boolean functions. 
 
51
         * These functions are passed the attribute and the current node's value of the attribute.
 
52
         * @property operators
 
53
         * @type object
 
54
         */
 
55
        operators: {
 
56
            '': function(node, attr) { return Y.DOM.getAttribute(node, attr) !== ''; }, // Just test for existence of attribute
 
57
            '~=': '(?:^|\\s+){val}(?:\\s+|$)', // space-delimited
 
58
            '|=': '^{val}-?' // optional hyphen-delimited
 
59
        },
 
60
 
 
61
        pseudos: {
 
62
           'first-child': function(node) { 
 
63
                return Y.DOM._children(node[PARENT_NODE])[0] === node; 
 
64
            } 
 
65
        },
 
66
 
 
67
        _bruteQuery: function(selector, root, firstOnly) {
 
68
            var ret = [],
 
69
                nodes = [],
 
70
                tokens = Selector._tokenize(selector),
 
71
                token = tokens[tokens.length - 1],
 
72
                rootDoc = Y.DOM._getDoc(root),
 
73
                child,
 
74
                id,
 
75
                className,
 
76
                tagName;
 
77
 
 
78
            if (token) {
 
79
                // prefilter nodes
 
80
                id = token.id;
 
81
                className = token.className;
 
82
                tagName = token.tagName || '*';
 
83
 
 
84
                if (root.getElementsByTagName) { // non-IE lacks DOM api on doc frags
 
85
                    // try ID first, unless no root.all && root not in document
 
86
                    // (root.all works off document, but not getElementById)
 
87
                    if (id && (root.all || (root.nodeType === 9 || Y.DOM.inDoc(root)))) {
 
88
                        nodes = Y.DOM.allById(id, root);
 
89
                    // try className
 
90
                    } else if (className) {
 
91
                        nodes = root.getElementsByClassName(className);
 
92
                    } else { // default to tagName
 
93
                        nodes = root.getElementsByTagName(tagName);
 
94
                    }
 
95
 
 
96
                } else { // brute getElementsByTagName()
 
97
                    child = root.firstChild;
 
98
                    while (child) {
 
99
                        // only collect HTMLElements
 
100
                        // match tag to supplement missing getElementsByTagName
 
101
                        if (child.tagName && (tagName === '*' || child.tagName === tagName)) {
 
102
                            nodes.push(child);
 
103
                        }
 
104
                        child = child.nextSibling || child.firstChild;
 
105
                    }
 
106
                }
 
107
                if (nodes.length) {
 
108
                    ret = Selector._filterNodes(nodes, tokens, firstOnly);
 
109
                }
 
110
            }
 
111
 
 
112
            return ret;
 
113
        },
 
114
        
 
115
        _filterNodes: function(nodes, tokens, firstOnly) {
 
116
            var i = 0,
 
117
                j,
 
118
                len = tokens.length,
 
119
                n = len - 1,
 
120
                result = [],
 
121
                node = nodes[0],
 
122
                tmpNode = node,
 
123
                getters = Y.Selector.getters,
 
124
                operator,
 
125
                combinator,
 
126
                token,
 
127
                path,
 
128
                pass,
 
129
                value,
 
130
                tests,
 
131
                test;
 
132
 
 
133
            for (i = 0; (tmpNode = node = nodes[i++]);) {
 
134
                n = len - 1;
 
135
                path = null;
 
136
                
 
137
                testLoop:
 
138
                while (tmpNode && tmpNode.tagName) {
 
139
                    token = tokens[n];
 
140
                    tests = token.tests;
 
141
                    j = tests.length;
 
142
                    if (j && !pass) {
 
143
                        while ((test = tests[--j])) {
 
144
                            operator = test[1];
 
145
                            if (getters[test[0]]) {
 
146
                                value = getters[test[0]](tmpNode, test[0]);
 
147
                            } else {
 
148
                                value = tmpNode[test[0]];
 
149
                                if (test[0] === 'tagName' && !Selector._isXML) {
 
150
                                    value = value.toUpperCase();    
 
151
                                }
 
152
                                if (typeof value != 'string' && value !== undefined && value.toString) {
 
153
                                    value = value.toString(); // coerce for comparison
 
154
                                } else if (value === undefined && tmpNode.getAttribute) {
 
155
                                    // use getAttribute for non-standard attributes
 
156
                                    value = tmpNode.getAttribute(test[0], 2); // 2 === force string for IE
 
157
                                }
 
158
                            }
 
159
 
 
160
                            if ((operator === '=' && value !== test[2]) ||  // fast path for equality
 
161
                                (typeof operator !== 'string' && // protect against String.test monkey-patch (Moo)
 
162
                                operator.test && !operator.test(value)) ||  // regex test
 
163
                                (!operator.test && // protect against RegExp as function (webkit)
 
164
                                        typeof operator === 'function' && !operator(tmpNode, test[0], test[2]))) { // function test
 
165
 
 
166
                                // skip non element nodes or non-matching tags
 
167
                                if ((tmpNode = tmpNode[path])) {
 
168
                                    while (tmpNode &&
 
169
                                        (!tmpNode.tagName ||
 
170
                                            (token.tagName && token.tagName !== tmpNode.tagName))
 
171
                                    ) {
 
172
                                        tmpNode = tmpNode[path]; 
 
173
                                    }
 
174
                                }
 
175
                                continue testLoop;
 
176
                            }
 
177
                        }
 
178
                    }
 
179
 
 
180
                    n--; // move to next token
 
181
                    // now that we've passed the test, move up the tree by combinator
 
182
                    if (!pass && (combinator = token.combinator)) {
 
183
                        path = combinator.axis;
 
184
                        tmpNode = tmpNode[path];
 
185
 
 
186
                        // skip non element nodes
 
187
                        while (tmpNode && !tmpNode.tagName) {
 
188
                            tmpNode = tmpNode[path]; 
 
189
                        }
 
190
 
 
191
                        if (combinator.direct) { // one pass only
 
192
                            path = null; 
 
193
                        }
 
194
 
 
195
                    } else { // success if we made it this far
 
196
                        result.push(node);
 
197
                        if (firstOnly) {
 
198
                            return result;
 
199
                        }
 
200
                        break;
 
201
                    }
 
202
                }
 
203
            }
 
204
            node = tmpNode = null;
 
205
            return result;
 
206
        },
 
207
 
 
208
        combinators: {
 
209
            ' ': {
 
210
                axis: 'parentNode'
 
211
            },
 
212
 
 
213
            '>': {
 
214
                axis: 'parentNode',
 
215
                direct: true
 
216
            },
 
217
 
 
218
 
 
219
            '+': {
 
220
                axis: 'previousSibling',
 
221
                direct: true
 
222
            }
 
223
        },
 
224
 
 
225
        _parsers: [
 
226
            {
 
227
                name: ATTRIBUTES,
 
228
                re: /^\uE003(-?[a-z]+[\w\-]*)+([~\|\^\$\*!=]=?)?['"]?([^\uE004'"]*)['"]?\uE004/i,
 
229
                fn: function(match, token) {
 
230
                    var operator = match[2] || '',
 
231
                        operators = Selector.operators,
 
232
                        escVal = (match[3]) ? match[3].replace(/\\/g, '') : '',
 
233
                        test;
 
234
 
 
235
                    // add prefiltering for ID and CLASS
 
236
                    if ((match[1] === 'id' && operator === '=') ||
 
237
                            (match[1] === 'className' &&
 
238
                            Y.config.doc.documentElement.getElementsByClassName &&
 
239
                            (operator === '~=' || operator === '='))) {
 
240
                        token.prefilter = match[1];
 
241
 
 
242
 
 
243
                        match[3] = escVal; 
 
244
 
 
245
                        // escape all but ID for prefilter, which may run through QSA (via Dom.allById)
 
246
                        token[match[1]] = (match[1] === 'id') ? match[3] : escVal;
 
247
 
 
248
                    }
 
249
 
 
250
                    // add tests
 
251
                    if (operator in operators) {
 
252
                        test = operators[operator];
 
253
                        if (typeof test === 'string') {
 
254
                            match[3] = escVal.replace(Selector._reRegExpTokens, '\\$1');
 
255
                            test = new RegExp(test.replace('{val}', match[3]));
 
256
                        }
 
257
                        match[2] = test;
 
258
                    }
 
259
                    if (!token.last || token.prefilter !== match[1]) {
 
260
                        return match.slice(1);
 
261
                    }
 
262
                }
 
263
            },
 
264
            {
 
265
                name: TAG_NAME,
 
266
                re: /^((?:-?[_a-z]+[\w-]*)|\*)/i,
 
267
                fn: function(match, token) {
 
268
                    var tag = match[1];
 
269
 
 
270
                    if (!Selector._isXML) {
 
271
                        tag = tag.toUpperCase();
 
272
                    }
 
273
 
 
274
                    token.tagName = tag;
 
275
 
 
276
                    if (tag !== '*' && (!token.last || token.prefilter)) {
 
277
                        return [TAG_NAME, '=', tag];
 
278
                    }
 
279
                    if (!token.prefilter) {
 
280
                        token.prefilter = 'tagName';
 
281
                    }
 
282
                }
 
283
            },
 
284
            {
 
285
                name: COMBINATOR,
 
286
                re: /^\s*([>+~]|\s)\s*/,
 
287
                fn: function(match, token) {
 
288
                }
 
289
            },
 
290
            {
 
291
                name: PSEUDOS,
 
292
                re: /^:([\-\w]+)(?:\uE005['"]?([^\uE005]*)['"]?\uE006)*/i,
 
293
                fn: function(match, token) {
 
294
                    var test = Selector[PSEUDOS][match[1]];
 
295
                    if (test) { // reorder match array and unescape special chars for tests
 
296
                        if (match[2]) {
 
297
                            match[2] = match[2].replace(/\\/g, '');
 
298
                        }
 
299
                        return [match[2], test]; 
 
300
                    } else { // selector token not supported (possibly missing CSS3 module)
 
301
                        return false;
 
302
                    }
 
303
                }
 
304
            }
 
305
            ],
 
306
 
 
307
        _getToken: function(token) {
 
308
            return {
 
309
                tagName: null,
 
310
                id: null,
 
311
                className: null,
 
312
                attributes: {},
 
313
                combinator: null,
 
314
                tests: []
 
315
            };
 
316
        },
 
317
 
 
318
        /*
 
319
            Break selector into token units per simple selector.
 
320
            Combinator is attached to the previous token.
 
321
         */
 
322
        _tokenize: function(selector) {
 
323
            selector = selector || '';
 
324
            selector = Selector._parseSelector(Y.Lang.trim(selector)); 
 
325
            var token = Selector._getToken(),     // one token per simple selector (left selector holds combinator)
 
326
                query = selector, // original query for debug report
 
327
                tokens = [],    // array of tokens
 
328
                found = false,  // whether or not any matches were found this pass
 
329
                match,         // the regex match
 
330
                test,
 
331
                i, parser;
 
332
 
 
333
            /*
 
334
                Search for selector patterns, store, and strip them from the selector string
 
335
                until no patterns match (invalid selector) or we run out of chars.
 
336
 
 
337
                Multiple attributes and pseudos are allowed, in any order.
 
338
                for example:
 
339
                    'form:first-child[type=button]:not(button)[lang|=en]'
 
340
            */
 
341
            outer:
 
342
            do {
 
343
                found = false; // reset after full pass
 
344
                for (i = 0; (parser = Selector._parsers[i++]);) {
 
345
                    if ( (match = parser.re.exec(selector)) ) { // note assignment
 
346
                        if (parser.name !== COMBINATOR ) {
 
347
                            token.selector = selector;
 
348
                        }
 
349
                        selector = selector.replace(match[0], ''); // strip current match from selector
 
350
                        if (!selector.length) {
 
351
                            token.last = true;
 
352
                        }
 
353
 
 
354
                        if (Selector._attrFilters[match[1]]) { // convert class to className, etc.
 
355
                            match[1] = Selector._attrFilters[match[1]];
 
356
                        }
 
357
 
 
358
                        test = parser.fn(match, token);
 
359
                        if (test === false) { // selector not supported
 
360
                            found = false;
 
361
                            break outer;
 
362
                        } else if (test) {
 
363
                            token.tests.push(test);
 
364
                        }
 
365
 
 
366
                        if (!selector.length || parser.name === COMBINATOR) {
 
367
                            tokens.push(token);
 
368
                            token = Selector._getToken(token);
 
369
                            if (parser.name === COMBINATOR) {
 
370
                                token.combinator = Y.Selector.combinators[match[1]];
 
371
                            }
 
372
                        }
 
373
                        found = true;
 
374
                    }
 
375
                }
 
376
            } while (found && selector.length);
 
377
 
 
378
            if (!found || selector.length) { // not fully parsed
 
379
                Y.log('query: ' + query + ' contains unsupported token in: ' + selector, 'warn', 'Selector');
 
380
                tokens = [];
 
381
            }
 
382
            return tokens;
 
383
        },
 
384
 
 
385
        _replaceMarkers: function(selector) {
 
386
            selector = selector.replace(/\[/g, '\uE003');
 
387
            selector = selector.replace(/\]/g, '\uE004');
 
388
 
 
389
            selector = selector.replace(/\(/g, '\uE005');
 
390
            selector = selector.replace(/\)/g, '\uE006');
 
391
            return selector;
 
392
        },
 
393
 
 
394
        _replaceShorthand: function(selector) {
 
395
            var shorthand = Y.Selector.shorthand,
 
396
                re;
 
397
 
 
398
            for (re in shorthand) {
 
399
                if (shorthand.hasOwnProperty(re)) {
 
400
                    selector = selector.replace(new RegExp(re, 'gi'), shorthand[re]);
 
401
                }
 
402
            }
 
403
 
 
404
            return selector;
 
405
        },
 
406
 
 
407
        _parseSelector: function(selector) {
 
408
            var replaced = Y.Selector._replaceSelector(selector),
 
409
                selector = replaced.selector;
 
410
 
 
411
            // replace shorthand (".foo, #bar") after pseudos and attrs
 
412
            // to avoid replacing unescaped chars
 
413
            selector = Y.Selector._replaceShorthand(selector);
 
414
 
 
415
            selector = Y.Selector._restore('attr', selector, replaced.attrs);
 
416
            selector = Y.Selector._restore('pseudo', selector, replaced.pseudos);
 
417
 
 
418
            // replace braces and parens before restoring escaped chars
 
419
            // to avoid replacing ecaped markers
 
420
            selector = Y.Selector._replaceMarkers(selector);
 
421
            selector = Y.Selector._restore('esc', selector, replaced.esc);
 
422
 
 
423
            return selector;
 
424
        },
 
425
 
 
426
        _attrFilters: {
 
427
            'class': 'className',
 
428
            'for': 'htmlFor'
 
429
        },
 
430
 
 
431
        getters: {
 
432
            href: function(node, attr) {
 
433
                return Y.DOM.getAttribute(node, attr);
 
434
            },
 
435
 
 
436
            id: function(node, attr) {
 
437
                return Y.DOM.getId(node);
 
438
            }
 
439
        }
 
440
    };
 
441
 
 
442
Y.mix(Y.Selector, SelectorCSS2, true);
 
443
Y.Selector.getters.src = Y.Selector.getters.rel = Y.Selector.getters.href;
 
444
 
 
445
// IE wants class with native queries
 
446
if (Y.Selector.useNative && Y.config.doc.querySelector) {
 
447
    Y.Selector.shorthand['\\.(-?[_a-z]+[-\\w]*)'] = '[class~=$1]';
 
448
}
 
449
 
 
450
 
 
451
 
 
452
}, '3.10.3', {"requires": ["selector-native"]});