Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/ext/src/ext-core/src/core/DomQuery.js @ 76

Revision 76, 32.8 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
1/*!
2 * Ext JS Library 3.4.0
3 * Copyright(c) 2006-2011 Sencha Inc.
4 * licensing@sencha.com
5 * http://www.sencha.com/license
6 */
7/*
8 * This is code is also distributed under MIT license for use
9 * with jQuery and prototype JavaScript libraries.
10 */
11/**
12 * @class Ext.DomQuery
13Provides high performance selector/xpath processing by compiling queries into reusable functions. New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in).
14<p>
15DomQuery supports most of the <a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215/#selectors">CSS3 selectors spec</a>, along with some custom selectors and basic XPath.</p>
16
17<p>
18All selectors, attribute filters and pseudos below can be combined infinitely in any order. For example "div.foo:nth-child(odd)[@foo=bar].bar:first" would be a perfectly valid selector. Node filters are processed in the order in which they appear, which allows you to optimize your queries for your document structure.
19</p>
20<h4>Element Selectors:</h4>
21<ul class="list">
22    <li> <b>*</b> any element</li>
23    <li> <b>E</b> an element with the tag E</li>
24    <li> <b>E F</b> All descendent elements of E that have the tag F</li>
25    <li> <b>E > F</b> or <b>E/F</b> all direct children elements of E that have the tag F</li>
26    <li> <b>E + F</b> all elements with the tag F that are immediately preceded by an element with the tag E</li>
27    <li> <b>E ~ F</b> all elements with the tag F that are preceded by a sibling element with the tag E</li>
28</ul>
29<h4>Attribute Selectors:</h4>
30<p>The use of &#64; and quotes are optional. For example, div[&#64;foo='bar'] is also a valid attribute selector.</p>
31<ul class="list">
32    <li> <b>E[foo]</b> has an attribute "foo"</li>
33    <li> <b>E[foo=bar]</b> has an attribute "foo" that equals "bar"</li>
34    <li> <b>E[foo^=bar]</b> has an attribute "foo" that starts with "bar"</li>
35    <li> <b>E[foo$=bar]</b> has an attribute "foo" that ends with "bar"</li>
36    <li> <b>E[foo*=bar]</b> has an attribute "foo" that contains the substring "bar"</li>
37    <li> <b>E[foo%=2]</b> has an attribute "foo" that is evenly divisible by 2</li>
38    <li> <b>E[foo!=bar]</b> attribute "foo" does not equal "bar"</li>
39</ul>
40<h4>Pseudo Classes:</h4>
41<ul class="list">
42    <li> <b>E:first-child</b> E is the first child of its parent</li>
43    <li> <b>E:last-child</b> E is the last child of its parent</li>
44    <li> <b>E:nth-child(<i>n</i>)</b> E is the <i>n</i>th child of its parent (1 based as per the spec)</li>
45    <li> <b>E:nth-child(odd)</b> E is an odd child of its parent</li>
46    <li> <b>E:nth-child(even)</b> E is an even child of its parent</li>
47    <li> <b>E:only-child</b> E is the only child of its parent</li>
48    <li> <b>E:checked</b> E is an element that is has a checked attribute that is true (e.g. a radio or checkbox) </li>
49    <li> <b>E:first</b> the first E in the resultset</li>
50    <li> <b>E:last</b> the last E in the resultset</li>
51    <li> <b>E:nth(<i>n</i>)</b> the <i>n</i>th E in the resultset (1 based)</li>
52    <li> <b>E:odd</b> shortcut for :nth-child(odd)</li>
53    <li> <b>E:even</b> shortcut for :nth-child(even)</li>
54    <li> <b>E:contains(foo)</b> E's innerHTML contains the substring "foo"</li>
55    <li> <b>E:nodeValue(foo)</b> E contains a textNode with a nodeValue that equals "foo"</li>
56    <li> <b>E:not(S)</b> an E element that does not match simple selector S</li>
57    <li> <b>E:has(S)</b> an E element that has a descendent that matches simple selector S</li>
58    <li> <b>E:next(S)</b> an E element whose next sibling matches simple selector S</li>
59    <li> <b>E:prev(S)</b> an E element whose previous sibling matches simple selector S</li>
60    <li> <b>E:any(S1|S2|S2)</b> an E element which matches any of the simple selectors S1, S2 or S3//\\</li>
61</ul>
62<h4>CSS Value Selectors:</h4>
63<ul class="list">
64    <li> <b>E{display=none}</b> css value "display" that equals "none"</li>
65    <li> <b>E{display^=none}</b> css value "display" that starts with "none"</li>
66    <li> <b>E{display$=none}</b> css value "display" that ends with "none"</li>
67    <li> <b>E{display*=none}</b> css value "display" that contains the substring "none"</li>
68    <li> <b>E{display%=2}</b> css value "display" that is evenly divisible by 2</li>
69    <li> <b>E{display!=none}</b> css value "display" that does not equal "none"</li>
70</ul>
71 * @singleton
72 */
73Ext.DomQuery = function(){
74    var cache = {}, 
75        simpleCache = {}, 
76        valueCache = {},
77        nonSpace = /\S/,
78        trimRe = /^\s+|\s+$/g,
79        tplRe = /\{(\d+)\}/g,
80        modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
81        tagTokenRe = /^(#)?([\w\-\*]+)/,
82        nthRe = /(\d*)n\+?(\d*)/, 
83        nthRe2 = /\D/,
84        // This is for IE MSXML which does not support expandos.
85        // IE runs the same speed using setAttribute, however FF slows way down
86        // and Safari completely fails so they need to continue to use expandos.
87        isIE = window.ActiveXObject ? true : false,
88        key = 30803;
89   
90    // this eval is stop the compressor from
91    // renaming the variable to something shorter
92    eval("var batch = 30803;");         
93
94    // Retrieve the child node from a particular
95    // parent at the specified index.
96    function child(parent, index){
97        var i = 0,
98            n = parent.firstChild;
99        while(n){
100            if(n.nodeType == 1){
101               if(++i == index){
102                   return n;
103               }
104            }
105            n = n.nextSibling;
106        }
107        return null;
108    }
109
110    // retrieve the next element node
111    function next(n){   
112        while((n = n.nextSibling) && n.nodeType != 1);
113        return n;
114    }
115
116    // retrieve the previous element node
117    function prev(n){
118        while((n = n.previousSibling) && n.nodeType != 1);
119        return n;
120    }
121
122    // Mark each child node with a nodeIndex skipping and
123    // removing empty text nodes.
124    function children(parent){
125        var n = parent.firstChild,
126            nodeIndex = -1,
127            nextNode;
128        while(n){
129            nextNode = n.nextSibling;
130            // clean worthless empty nodes.
131            if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
132                parent.removeChild(n);
133            }else{
134                // add an expando nodeIndex
135                n.nodeIndex = ++nodeIndex;
136            }
137            n = nextNode;
138        }
139        return this;
140    }
141
142
143    // nodeSet - array of nodes
144    // cls - CSS Class
145    function byClassName(nodeSet, cls){
146        if(!cls){
147            return nodeSet;
148        }
149        var result = [], ri = -1;
150        for(var i = 0, ci; ci = nodeSet[i]; i++){
151            if((' '+ci.className+' ').indexOf(cls) != -1){
152                result[++ri] = ci;
153            }
154        }
155        return result;
156    };
157
158    function attrValue(n, attr){
159        // if its an array, use the first node.
160        if(!n.tagName && typeof n.length != "undefined"){
161            n = n[0];
162        }
163        if(!n){
164            return null;
165        }
166
167        if(attr == "for"){
168            return n.htmlFor;
169        }
170        if(attr == "class" || attr == "className"){
171            return n.className;
172        }
173        return n.getAttribute(attr) || n[attr];
174
175    };
176
177
178    // ns - nodes
179    // mode - false, /, >, +, ~
180    // tagName - defaults to "*"
181    function getNodes(ns, mode, tagName){
182        var result = [], ri = -1, cs;
183        if(!ns){
184            return result;
185        }
186        tagName = tagName || "*";
187        // convert to array
188        if(typeof ns.getElementsByTagName != "undefined"){
189            ns = [ns];
190        }
191       
192        // no mode specified, grab all elements by tagName
193        // at any depth
194        if(!mode){
195            for(var i = 0, ni; ni = ns[i]; i++){
196                cs = ni.getElementsByTagName(tagName);
197                for(var j = 0, ci; ci = cs[j]; j++){
198                    result[++ri] = ci;
199                }
200            }
201        // Direct Child mode (/ or >)
202        // E > F or E/F all direct children elements of E that have the tag     
203        } else if(mode == "/" || mode == ">"){
204            var utag = tagName.toUpperCase();
205            for(var i = 0, ni, cn; ni = ns[i]; i++){
206                cn = ni.childNodes;
207                for(var j = 0, cj; cj = cn[j]; j++){
208                    if(cj.nodeName == utag || cj.nodeName == tagName  || tagName == '*'){
209                        result[++ri] = cj;
210                    }
211                }
212            }
213        // Immediately Preceding mode (+)
214        // E + F all elements with the tag F that are immediately preceded by an element with the tag E
215        }else if(mode == "+"){
216            var utag = tagName.toUpperCase();
217            for(var i = 0, n; n = ns[i]; i++){
218                while((n = n.nextSibling) && n.nodeType != 1);
219                if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
220                    result[++ri] = n;
221                }
222            }
223        // Sibling mode (~)
224        // E ~ F all elements with the tag F that are preceded by a sibling element with the tag E
225        }else if(mode == "~"){
226            var utag = tagName.toUpperCase();
227            for(var i = 0, n; n = ns[i]; i++){
228                while((n = n.nextSibling)){
229                    if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
230                        result[++ri] = n;
231                    }
232                }
233            }
234        }
235        return result;
236    }
237
238    function concat(a, b){
239        if(b.slice){
240            return a.concat(b);
241        }
242        for(var i = 0, l = b.length; i < l; i++){
243            a[a.length] = b[i];
244        }
245        return a;
246    }
247
248    function byTag(cs, tagName){
249        if(cs.tagName || cs == document){
250            cs = [cs];
251        }
252        if(!tagName){
253            return cs;
254        }
255        var result = [], ri = -1;
256        tagName = tagName.toLowerCase();
257        for(var i = 0, ci; ci = cs[i]; i++){
258            if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
259                result[++ri] = ci;
260            }
261        }
262        return result;
263    }
264
265    function byId(cs, id){
266        if(cs.tagName || cs == document){
267            cs = [cs];
268        }
269        if(!id){
270            return cs;
271        }
272        var result = [], ri = -1;
273        for(var i = 0, ci; ci = cs[i]; i++){
274            if(ci && ci.id == id){
275                result[++ri] = ci;
276                return result;
277            }
278        }
279        return result;
280    }
281
282    // operators are =, !=, ^=, $=, *=, %=, |= and ~=
283    // custom can be "{"
284    function byAttribute(cs, attr, value, op, custom){
285        var result = [], 
286            ri = -1, 
287            useGetStyle = custom == "{",           
288            fn = Ext.DomQuery.operators[op],       
289            a,
290            xml,
291            hasXml;
292           
293        for(var i = 0, ci; ci = cs[i]; i++){
294            // skip non-element nodes.
295            if(ci.nodeType != 1){
296                continue;
297            }
298            // only need to do this for the first node
299            if(!hasXml){
300                xml = Ext.DomQuery.isXml(ci);
301                hasXml = true;
302            }
303           
304            // we only need to change the property names if we're dealing with html nodes, not XML
305            if(!xml){
306                if(useGetStyle){
307                    a = Ext.DomQuery.getStyle(ci, attr);
308                } else if (attr == "class" || attr == "className"){
309                    a = ci.className;
310                } else if (attr == "for"){
311                    a = ci.htmlFor;
312                } else if (attr == "href"){
313                    // getAttribute href bug
314                    // http://www.glennjones.net/Post/809/getAttributehrefbug.htm
315                    a = ci.getAttribute("href", 2);
316                } else{
317                    a = ci.getAttribute(attr);
318                }
319            }else{
320                a = ci.getAttribute(attr);
321            }
322            if((fn && fn(a, value)) || (!fn && a)){
323                result[++ri] = ci;
324            }
325        }
326        return result;
327    }
328
329    function byPseudo(cs, name, value){
330        return Ext.DomQuery.pseudos[name](cs, value);
331    }
332
333    function nodupIEXml(cs){
334        var d = ++key, 
335            r;
336        cs[0].setAttribute("_nodup", d);
337        r = [cs[0]];
338        for(var i = 1, len = cs.length; i < len; i++){
339            var c = cs[i];
340            if(!c.getAttribute("_nodup") != d){
341                c.setAttribute("_nodup", d);
342                r[r.length] = c;
343            }
344        }
345        for(var i = 0, len = cs.length; i < len; i++){
346            cs[i].removeAttribute("_nodup");
347        }
348        return r;
349    }
350
351    function nodup(cs){
352        if(!cs){
353            return [];
354        }
355        var len = cs.length, c, i, r = cs, cj, ri = -1;
356        if(!len || typeof cs.nodeType != "undefined" || len == 1){
357            return cs;
358        }
359        if(isIE && typeof cs[0].selectSingleNode != "undefined"){
360            return nodupIEXml(cs);
361        }
362        var d = ++key;
363        cs[0]._nodup = d;
364        for(i = 1; c = cs[i]; i++){
365            if(c._nodup != d){
366                c._nodup = d;
367            }else{
368                r = [];
369                for(var j = 0; j < i; j++){
370                    r[++ri] = cs[j];
371                }
372                for(j = i+1; cj = cs[j]; j++){
373                    if(cj._nodup != d){
374                        cj._nodup = d;
375                        r[++ri] = cj;
376                    }
377                }
378                return r;
379            }
380        }
381        return r;
382    }
383
384    function quickDiffIEXml(c1, c2){
385        var d = ++key,
386            r = [];
387        for(var i = 0, len = c1.length; i < len; i++){
388            c1[i].setAttribute("_qdiff", d);
389        }       
390        for(var i = 0, len = c2.length; i < len; i++){
391            if(c2[i].getAttribute("_qdiff") != d){
392                r[r.length] = c2[i];
393            }
394        }
395        for(var i = 0, len = c1.length; i < len; i++){
396           c1[i].removeAttribute("_qdiff");
397        }
398        return r;
399    }
400
401    function quickDiff(c1, c2){
402        var len1 = c1.length,
403                d = ++key,
404                r = [];
405        if(!len1){
406            return c2;
407        }
408        if(isIE && typeof c1[0].selectSingleNode != "undefined"){
409            return quickDiffIEXml(c1, c2);
410        }       
411        for(var i = 0; i < len1; i++){
412            c1[i]._qdiff = d;
413        }       
414        for(var i = 0, len = c2.length; i < len; i++){
415            if(c2[i]._qdiff != d){
416                r[r.length] = c2[i];
417            }
418        }
419        return r;
420    }
421
422    function quickId(ns, mode, root, id){
423        if(ns == root){
424           var d = root.ownerDocument || root;
425           return d.getElementById(id);
426        }
427        ns = getNodes(ns, mode, "*");
428        return byId(ns, id);
429    }
430
431    return {
432        getStyle : function(el, name){
433            return Ext.fly(el).getStyle(name);
434        },
435        /**
436         * Compiles a selector/xpath query into a reusable function. The returned function
437         * takes one parameter "root" (optional), which is the context node from where the query should start.
438         * @param {String} selector The selector/xpath query
439         * @param {String} type (optional) Either "select" (the default) or "simple" for a simple selector match
440         * @return {Function}
441         */
442        compile : function(path, type){
443            type = type || "select";
444
445            // setup fn preamble
446            var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
447                        mode,           
448                        lastPath,
449                matchers = Ext.DomQuery.matchers,
450                matchersLn = matchers.length,
451                modeMatch,
452                // accept leading mode switch
453                lmode = path.match(modeRe);
454           
455            if(lmode && lmode[1]){
456                fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
457                path = path.replace(lmode[1], "");
458            }
459           
460            // strip leading slashes
461            while(path.substr(0, 1)=="/"){
462                path = path.substr(1);
463            }
464
465            while(path && lastPath != path){
466                lastPath = path;
467                var tokenMatch = path.match(tagTokenRe);
468                if(type == "select"){
469                    if(tokenMatch){
470                        // ID Selector
471                        if(tokenMatch[1] == "#"){
472                            fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';                 
473                        }else{
474                            fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
475                        }
476                        path = path.replace(tokenMatch[0], "");
477                    }else if(path.substr(0, 1) != '@'){
478                        fn[fn.length] = 'n = getNodes(n, mode, "*");';
479                    }
480                // type of "simple"
481                }else{
482                    if(tokenMatch){
483                        if(tokenMatch[1] == "#"){
484                            fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
485                        }else{
486                            fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
487                        }
488                        path = path.replace(tokenMatch[0], "");
489                    }
490                }
491                while(!(modeMatch = path.match(modeRe))){
492                    var matched = false;
493                    for(var j = 0; j < matchersLn; j++){
494                        var t = matchers[j];
495                        var m = path.match(t.re);
496                        if(m){
497                            fn[fn.length] = t.select.replace(tplRe, function(x, i){
498                                return m[i];
499                            });
500                            path = path.replace(m[0], "");
501                            matched = true;
502                            break;
503                        }
504                    }
505                    // prevent infinite loop on bad selector
506                    if(!matched){
507                        throw 'Error parsing selector, parsing failed at "' + path + '"';
508                    }
509                }
510                if(modeMatch[1]){
511                    fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
512                    path = path.replace(modeMatch[1], "");
513                }
514            }
515            // close fn out
516            fn[fn.length] = "return nodup(n);\n}";
517           
518            // eval fn and return it
519            eval(fn.join(""));
520            return f;
521        },
522
523        /**
524         * Selects a group of elements.
525         * @param {String} selector The selector/xpath query (can be a comma separated list of selectors)
526         * @param {Node/String} root (optional) The start of the query (defaults to document).
527         * @return {Array} An Array of DOM elements which match the selector. If there are
528         * no matches, and empty Array is returned.
529         */
530        jsSelect: function(path, root, type){
531            // set root to doc if not specified.
532            root = root || document;
533           
534            if(typeof root == "string"){
535                root = document.getElementById(root);
536            }
537            var paths = path.split(","),
538                results = [];
539               
540            // loop over each selector
541            for(var i = 0, len = paths.length; i < len; i++){           
542                var subPath = paths[i].replace(trimRe, "");
543                // compile and place in cache
544                if(!cache[subPath]){
545                    cache[subPath] = Ext.DomQuery.compile(subPath);
546                    if(!cache[subPath]){
547                        throw subPath + " is not a valid selector";
548                    }
549                }
550                var result = cache[subPath](root);
551                if(result && result != document){
552                    results = results.concat(result);
553                }
554            }
555           
556            // if there were multiple selectors, make sure dups
557            // are eliminated
558            if(paths.length > 1){
559                return nodup(results);
560            }
561            return results;
562        },
563        isXml: function(el) {
564            var docEl = (el ? el.ownerDocument || el : 0).documentElement;
565            return docEl ? docEl.nodeName !== "HTML" : false;
566        },
567        select : document.querySelectorAll ? function(path, root, type) {
568            root = root || document;
569            if (!Ext.DomQuery.isXml(root)) {
570                try {
571                    var cs = root.querySelectorAll(path);
572                    return Ext.toArray(cs);
573                }
574                catch (ex) {}           
575            }       
576            return Ext.DomQuery.jsSelect.call(this, path, root, type);
577        } : function(path, root, type) {
578            return Ext.DomQuery.jsSelect.call(this, path, root, type);
579        },
580
581        /**
582         * Selects a single element.
583         * @param {String} selector The selector/xpath query
584         * @param {Node} root (optional) The start of the query (defaults to document).
585         * @return {Element} The DOM element which matched the selector.
586         */
587        selectNode : function(path, root){
588            return Ext.DomQuery.select(path, root)[0];
589        },
590
591        /**
592         * Selects the value of a node, optionally replacing null with the defaultValue.
593         * @param {String} selector The selector/xpath query
594         * @param {Node} root (optional) The start of the query (defaults to document).
595         * @param {String} defaultValue
596         * @return {String}
597         */
598        selectValue : function(path, root, defaultValue){
599            path = path.replace(trimRe, "");
600            if(!valueCache[path]){
601                valueCache[path] = Ext.DomQuery.compile(path, "select");
602            }
603            var n = valueCache[path](root), v;
604            n = n[0] ? n[0] : n;
605                   
606            // overcome a limitation of maximum textnode size
607            // Rumored to potentially crash IE6 but has not been confirmed.
608            // http://reference.sitepoint.com/javascript/Node/normalize
609            // https://developer.mozilla.org/En/DOM/Node.normalize         
610            if (typeof n.normalize == 'function') n.normalize();
611           
612            v = (n && n.firstChild ? n.firstChild.nodeValue : null);
613            return ((v === null||v === undefined||v==='') ? defaultValue : v);
614        },
615
616        /**
617         * Selects the value of a node, parsing integers and floats. Returns the defaultValue, or 0 if none is specified.
618         * @param {String} selector The selector/xpath query
619         * @param {Node} root (optional) The start of the query (defaults to document).
620         * @param {Number} defaultValue
621         * @return {Number}
622         */
623        selectNumber : function(path, root, defaultValue){
624            var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
625            return parseFloat(v);
626        },
627
628        /**
629         * Returns true if the passed element(s) match the passed simple selector (e.g. div.some-class or span:first-child)
630         * @param {String/HTMLElement/Array} el An element id, element or array of elements
631         * @param {String} selector The simple selector to test
632         * @return {Boolean}
633         */
634        is : function(el, ss){
635            if(typeof el == "string"){
636                el = document.getElementById(el);
637            }
638            var isArray = Ext.isArray(el),
639                result = Ext.DomQuery.filter(isArray ? el : [el], ss);
640            return isArray ? (result.length == el.length) : (result.length > 0);
641        },
642
643        /**
644         * Filters an array of elements to only include matches of a simple selector (e.g. div.some-class or span:first-child)
645         * @param {Array} el An array of elements to filter
646         * @param {String} selector The simple selector to test
647         * @param {Boolean} nonMatches If true, it returns the elements that DON'T match
648         * the selector instead of the ones that match
649         * @return {Array} An Array of DOM elements which match the selector. If there are
650         * no matches, and empty Array is returned.
651         */
652        filter : function(els, ss, nonMatches){
653            ss = ss.replace(trimRe, "");
654            if(!simpleCache[ss]){
655                simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
656            }
657            var result = simpleCache[ss](els);
658            return nonMatches ? quickDiff(result, els) : result;
659        },
660
661        /**
662         * Collection of matching regular expressions and code snippets.
663         * Each capture group within () will be replace the {} in the select
664         * statement as specified by their index.
665         */
666        matchers : [{
667                re: /^\.([\w\-]+)/,
668                select: 'n = byClassName(n, " {1} ");'
669            }, {
670                re: /^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
671                select: 'n = byPseudo(n, "{1}", "{2}");'
672            },{
673                re: /^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,
674                select: 'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'
675            }, {
676                re: /^#([\w\-]+)/,
677                select: 'n = byId(n, "{1}");'
678            },{
679                re: /^@([\w\-]+)/,
680                select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
681            }
682        ],
683
684        /**
685         * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=.
686         * New operators can be added as long as the match the format <i>c</i>= where <i>c</i> is any character other than space, &gt; &lt;.
687         */
688        operators : {
689            "=" : function(a, v){
690                return a == v;
691            },
692            "!=" : function(a, v){
693                return a != v;
694            },
695            "^=" : function(a, v){
696                return a && a.substr(0, v.length) == v;
697            },
698            "$=" : function(a, v){
699                return a && a.substr(a.length-v.length) == v;
700            },
701            "*=" : function(a, v){
702                return a && a.indexOf(v) !== -1;
703            },
704            "%=" : function(a, v){
705                return (a % v) == 0;
706            },
707            "|=" : function(a, v){
708                return a && (a == v || a.substr(0, v.length+1) == v+'-');
709            },
710            "~=" : function(a, v){
711                return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
712            }
713        },
714
715        /**
716         * <p>Object hash of "pseudo class" filter functions which are used when filtering selections. Each function is passed
717         * two parameters:</p><div class="mdetail-params"><ul>
718         * <li><b>c</b> : Array<div class="sub-desc">An Array of DOM elements to filter.</div></li>
719         * <li><b>v</b> : String<div class="sub-desc">The argument (if any) supplied in the selector.</div></li>
720         * </ul></div>
721         * <p>A filter function returns an Array of DOM elements which conform to the pseudo class.</p>
722         * <p>In addition to the provided pseudo classes listed above such as <code>first-child</code> and <code>nth-child</code>,
723         * developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.</p>
724         * <p>For example, to filter <code>&lt;a></code> elements to only return links to <i>external</i> resources:</p>
725         * <code><pre>
726Ext.DomQuery.pseudos.external = function(c, v){
727    var r = [], ri = -1;
728    for(var i = 0, ci; ci = c[i]; i++){
729//      Include in result set only if it's a link to an external resource
730        if(ci.hostname != location.hostname){
731            r[++ri] = ci;
732        }
733    }
734    return r;
735};</pre></code>
736         * Then external links could be gathered with the following statement:<code><pre>
737var externalLinks = Ext.select("a:external");
738</code></pre>
739         */
740        pseudos : {
741            "first-child" : function(c){
742                var r = [], ri = -1, n;
743                for(var i = 0, ci; ci = n = c[i]; i++){
744                    while((n = n.previousSibling) && n.nodeType != 1);
745                    if(!n){
746                        r[++ri] = ci;
747                    }
748                }
749                return r;
750            },
751
752            "last-child" : function(c){
753                var r = [], ri = -1, n;
754                for(var i = 0, ci; ci = n = c[i]; i++){
755                    while((n = n.nextSibling) && n.nodeType != 1);
756                    if(!n){
757                        r[++ri] = ci;
758                    }
759                }
760                return r;
761            },
762
763            "nth-child" : function(c, a) {
764                var r = [], ri = -1,
765                        m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
766                        f = (m[1] || 1) - 0, l = m[2] - 0;
767                for(var i = 0, n; n = c[i]; i++){
768                    var pn = n.parentNode;
769                    if (batch != pn._batch) {
770                        var j = 0;
771                        for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
772                            if(cn.nodeType == 1){
773                               cn.nodeIndex = ++j;
774                            }
775                        }
776                        pn._batch = batch;
777                    }
778                    if (f == 1) {
779                        if (l == 0 || n.nodeIndex == l){
780                            r[++ri] = n;
781                        }
782                    } else if ((n.nodeIndex + l) % f == 0){
783                        r[++ri] = n;
784                    }
785                }
786
787                return r;
788            },
789
790            "only-child" : function(c){
791                var r = [], ri = -1;;
792                for(var i = 0, ci; ci = c[i]; i++){
793                    if(!prev(ci) && !next(ci)){
794                        r[++ri] = ci;
795                    }
796                }
797                return r;
798            },
799
800            "empty" : function(c){
801                var r = [], ri = -1;
802                for(var i = 0, ci; ci = c[i]; i++){
803                    var cns = ci.childNodes, j = 0, cn, empty = true;
804                    while(cn = cns[j]){
805                        ++j;
806                        if(cn.nodeType == 1 || cn.nodeType == 3){
807                            empty = false;
808                            break;
809                        }
810                    }
811                    if(empty){
812                        r[++ri] = ci;
813                    }
814                }
815                return r;
816            },
817
818            "contains" : function(c, v){
819                var r = [], ri = -1;
820                for(var i = 0, ci; ci = c[i]; i++){
821                    if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
822                        r[++ri] = ci;
823                    }
824                }
825                return r;
826            },
827
828            "nodeValue" : function(c, v){
829                var r = [], ri = -1;
830                for(var i = 0, ci; ci = c[i]; i++){
831                    if(ci.firstChild && ci.firstChild.nodeValue == v){
832                        r[++ri] = ci;
833                    }
834                }
835                return r;
836            },
837
838            "checked" : function(c){
839                var r = [], ri = -1;
840                for(var i = 0, ci; ci = c[i]; i++){
841                    if(ci.checked == true){
842                        r[++ri] = ci;
843                    }
844                }
845                return r;
846            },
847
848            "not" : function(c, ss){
849                return Ext.DomQuery.filter(c, ss, true);
850            },
851
852            "any" : function(c, selectors){
853                var ss = selectors.split('|'),
854                        r = [], ri = -1, s;
855                for(var i = 0, ci; ci = c[i]; i++){
856                    for(var j = 0; s = ss[j]; j++){
857                        if(Ext.DomQuery.is(ci, s)){
858                            r[++ri] = ci;
859                            break;
860                        }
861                    }
862                }
863                return r;
864            },
865
866            "odd" : function(c){
867                return this["nth-child"](c, "odd");
868            },
869
870            "even" : function(c){
871                return this["nth-child"](c, "even");
872            },
873
874            "nth" : function(c, a){
875                return c[a-1] || [];
876            },
877
878            "first" : function(c){
879                return c[0] || [];
880            },
881
882            "last" : function(c){
883                return c[c.length-1] || [];
884            },
885
886            "has" : function(c, ss){
887                var s = Ext.DomQuery.select,
888                        r = [], ri = -1;
889                for(var i = 0, ci; ci = c[i]; i++){
890                    if(s(ss, ci).length > 0){
891                        r[++ri] = ci;
892                    }
893                }
894                return r;
895            },
896
897            "next" : function(c, ss){
898                var is = Ext.DomQuery.is,
899                        r = [], ri = -1;
900                for(var i = 0, ci; ci = c[i]; i++){
901                    var n = next(ci);
902                    if(n && is(n, ss)){
903                        r[++ri] = ci;
904                    }
905                }
906                return r;
907            },
908
909            "prev" : function(c, ss){
910                var is = Ext.DomQuery.is,
911                        r = [], ri = -1;
912                for(var i = 0, ci; ci = c[i]; i++){
913                    var n = prev(ci);
914                    if(n && is(n, ss)){
915                        r[++ri] = ci;
916                    }
917                }
918                return r;
919            }
920        }
921    };
922}();
923
924/**
925 * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select}
926 * @param {String} path The selector/xpath query
927 * @param {Node} root (optional) The start of the query (defaults to document).
928 * @return {Array}
929 * @member Ext
930 * @method query
931 */
932Ext.query = Ext.DomQuery.select;
Note: See TracBrowser for help on using the repository browser.