Diffstat (limited to 'frontend/beta/js/Clipperz/YUI/DomQuery.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/Clipperz/YUI/DomQuery.js | 710 |
1 files changed, 710 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/YUI/DomQuery.js b/frontend/beta/js/Clipperz/YUI/DomQuery.js new file mode 100644 index 0000000..84aac08 --- a/dev/null +++ b/frontend/beta/js/Clipperz/YUI/DomQuery.js | |||
@@ -0,0 +1,710 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz's Javascript Crypto Library. | ||
6 | Javascript Crypto Library provides web developers with an extensive | ||
7 | and efficient set of cryptographic functions. The library aims to | ||
8 | obtain maximum execution speed while preserving modularity and | ||
9 | reusability. | ||
10 | For further information about its features and functionalities please | ||
11 | refer to http://www.clipperz.com | ||
12 | |||
13 | * Javascript Crypto Library is free software: you can redistribute | ||
14 | it and/or modify it under the terms of the GNU Affero General Public | ||
15 | License as published by the Free Software Foundation, either version | ||
16 | 3 of the License, or (at your option) any later version. | ||
17 | |||
18 | * Javascript Crypto Library is distributed in the hope that it will | ||
19 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | See the GNU Affero General Public License for more details. | ||
22 | |||
23 | * You should have received a copy of the GNU Affero General Public | ||
24 | License along with Javascript Crypto Library. If not, see | ||
25 | <http://www.gnu.org/licenses/>. | ||
26 | |||
27 | */ | ||
28 | |||
29 | /* | ||
30 | * yui-ext 0.40 | ||
31 | * Copyright(c) 2006, Jack Slocum. | ||
32 | */ | ||
33 | |||
34 | /** | ||
35 | * @class Ext.DomQuery | ||
36 | * Provides high performance selector/xpath processing by compiling queries into reusable functions. | ||
37 | * New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in). | ||
38 | * @singleton | ||
39 | */ | ||
40 | Ext.DomQuery = function(){ | ||
41 | var cache = {}, simpleCache = {}, valueCache = {}; | ||
42 | var nonSpace = /\S/; | ||
43 | var trimRe = /^\s*(.*?)\s*$/; | ||
44 | var tplRe = /\{(\d+)\}/g; | ||
45 | var modeRe = /^(\s?[\/>]\s?|\s|$)/; | ||
46 | var clsRes = {}; | ||
47 | |||
48 | function child(p, index){ | ||
49 | var i = 0; | ||
50 | var n = p.firstChild; | ||
51 | while(n){ | ||
52 | if(n.nodeType == 1){ | ||
53 | i++; | ||
54 | if(i == index){ | ||
55 | return n; | ||
56 | } | ||
57 | } | ||
58 | n = n.nextSibling; | ||
59 | } | ||
60 | return null; | ||
61 | }; | ||
62 | |||
63 | function next(d){ | ||
64 | var n = d.nextSibling; | ||
65 | while(n && n.nodeType != 1){ | ||
66 | n = n.nextSibling; | ||
67 | } | ||
68 | return n; | ||
69 | }; | ||
70 | |||
71 | function prev(d){ | ||
72 | var n = d.previousSibling; | ||
73 | while(n && n.nodeType != 1){ | ||
74 | n = n.previousSibling; | ||
75 | } | ||
76 | return n; | ||
77 | }; | ||
78 | |||
79 | function clean(d){ | ||
80 | var n = d.firstChild, ni = -1; | ||
81 | while(n){ | ||
82 | var nx = n.nextSibling; | ||
83 | if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ | ||
84 | d.removeChild(n); | ||
85 | }else{ | ||
86 | n.nodeIndex = ++ni; | ||
87 | } | ||
88 | n = nx; | ||
89 | } | ||
90 | return this; | ||
91 | }; | ||
92 | |||
93 | function byClassName(c, a, v){ | ||
94 | if(!v){ | ||
95 | return c; | ||
96 | } | ||
97 | var re = clsRes[v]; | ||
98 | if(!re){ | ||
99 | re = new RegExp('(?:^|\\s)(?:' + v + ')(?:\\s|$)'); | ||
100 | clsRes[v] = re; | ||
101 | } | ||
102 | var r = []; | ||
103 | for(var i = 0, ci; ci = c[i]; i++){ | ||
104 | if(re.test(ci.className)){ | ||
105 | r[r.length] = ci; | ||
106 | } | ||
107 | } | ||
108 | return r; | ||
109 | }; | ||
110 | |||
111 | function convert(c){ | ||
112 | if(c.slice){ | ||
113 | return c; | ||
114 | } | ||
115 | var r = []; | ||
116 | for(var i = 0, l = c.length; i < l; i++){ | ||
117 | r[r.length] = c[i]; | ||
118 | } | ||
119 | return r; | ||
120 | }; | ||
121 | |||
122 | function attrValue(n, attr){ | ||
123 | if(!n.tagName && typeof n.length != 'undefined'){ | ||
124 | n = n[0]; | ||
125 | } | ||
126 | if(!n){ | ||
127 | return null; | ||
128 | } | ||
129 | if(attr == 'for'){ | ||
130 | return n.htmlFor; | ||
131 | } | ||
132 | if(attr == 'class' || attr == 'className'){ | ||
133 | return n.className; | ||
134 | } | ||
135 | return n.getAttribute(attr) || n[attr]; | ||
136 | |||
137 | }; | ||
138 | |||
139 | function getNodes(ns, mode, tagName){ | ||
140 | var result = [], cs; | ||
141 | if(!ns){ | ||
142 | return result; | ||
143 | } | ||
144 | mode = mode ? mode.replace(trimRe, '$1') : ''; | ||
145 | tagName = tagName || '*'; | ||
146 | if(ns.tagName || ns == document){ | ||
147 | ns = [ns]; | ||
148 | } | ||
149 | if(mode != '/' && mode != '>'){ | ||
150 | for(var i = 0, ni; ni = ns[i]; i++){ | ||
151 | cs = ni.getElementsByTagName(tagName); | ||
152 | result = concat(result, cs); | ||
153 | } | ||
154 | }else{ | ||
155 | for(var i = 0, ni; ni = ns[i]; i++){ | ||
156 | var cn = ni.getElementsByTagName(tagName); | ||
157 | for(var j = 0, cj; cj = cn[j]; j++){ | ||
158 | if(cj.parentNode == ni){ | ||
159 | result[result.length] = cj; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | } | ||
165 | return result; | ||
166 | }; | ||
167 | |||
168 | function concat(a, b){ | ||
169 | if(b.slice){ | ||
170 | return a.concat(b); | ||
171 | } | ||
172 | for(var i = 0, l = b.length; i < l; i++){ | ||
173 | a[a.length] = b[i]; | ||
174 | } | ||
175 | return a; | ||
176 | } | ||
177 | |||
178 | function byTag(cs, tagName){ | ||
179 | if(cs.tagName || cs == document){ | ||
180 | cs = [cs]; | ||
181 | } | ||
182 | if(!tagName){ | ||
183 | return cs; | ||
184 | } | ||
185 | var r = []; tagName = tagName.toLowerCase(); | ||
186 | for(var i = 0, ci; ci = cs[i]; i++){ | ||
187 | if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){ | ||
188 | r[r.length] = ci; | ||
189 | } | ||
190 | } | ||
191 | return r; | ||
192 | }; | ||
193 | |||
194 | function byId(cs, attr, id){ | ||
195 | if(cs.tagName || cs == document){ | ||
196 | cs = [cs]; | ||
197 | } | ||
198 | if(!id){ | ||
199 | return cs; | ||
200 | } | ||
201 | var r = []; | ||
202 | for(var i = 0, l = cs.length; i < l; i++){ | ||
203 | var ci = cs[i]; | ||
204 | if(ci && ci.id == id){ | ||
205 | r[r.length] = ci; | ||
206 | } | ||
207 | } | ||
208 | return r; | ||
209 | }; | ||
210 | |||
211 | function byAttribute(cs, attr, value, op, custom){ | ||
212 | var r = [], st = custom=='{'; | ||
213 | var f = Ext.DomQuery.operators[op]; | ||
214 | for(var i = 0, l = cs.length; i < l; i++){ | ||
215 | var a; | ||
216 | if(st){ | ||
217 | a = Ext.DomQuery.getStyle(cs[i], attr); | ||
218 | } | ||
219 | else if(attr == 'class' || attr == 'className'){ | ||
220 | a = cs[i].className; | ||
221 | }else if(attr == 'for'){ | ||
222 | a = cs[i].htmlFor; | ||
223 | }else{ | ||
224 | a = cs[i].getAttribute(attr); | ||
225 | } | ||
226 | if((f && f(a, value)) || (!f && a)){ | ||
227 | r[r.length] = cs[i]; | ||
228 | } | ||
229 | } | ||
230 | return r; | ||
231 | }; | ||
232 | |||
233 | function byPseudo(cs, name, value){ | ||
234 | return Ext.DomQuery.pseudos[name](cs, value); | ||
235 | }; | ||
236 | |||
237 | // This is for IE MSXML which does not support expandos. | ||
238 | // IE runs the same speed using setAttribute, however FF slows way down | ||
239 | // and Safari completely fails so they need to continue to use expandos. | ||
240 | // Branched at load time for faster execution. | ||
241 | var isIE = window.ActiveXObject; | ||
242 | var addAttr = isIE ? | ||
243 | function(n, a, v){ | ||
244 | n.setAttribute(a, v); | ||
245 | } : | ||
246 | function(n, a, v){ | ||
247 | n[a] = v; | ||
248 | }; | ||
249 | var getAttr = isIE ? | ||
250 | function(n, a){ | ||
251 | return n.getAttribute(a); | ||
252 | } : | ||
253 | function(n, a){ | ||
254 | return n[a]; | ||
255 | }; | ||
256 | var clearAttr = isIE ? | ||
257 | function(n, a){ | ||
258 | n.removeAttribute(a); | ||
259 | } : | ||
260 | function(n, a, v){ | ||
261 | delete n[a]; | ||
262 | }; | ||
263 | |||
264 | function nodup(cs){ | ||
265 | if(!cs.length){ | ||
266 | return cs; | ||
267 | } | ||
268 | addAttr(cs[0], '_nodup', true); | ||
269 | var r = [cs[0]]; | ||
270 | for(var i = 1, len = cs.length; i < len; i++){ | ||
271 | var c = cs[i]; | ||
272 | if(!getAttr(c, '_nodup')){ | ||
273 | addAttr(c, '_nodup', true); | ||
274 | r[r.length] = c; | ||
275 | } | ||
276 | } | ||
277 | for(var i = 0, len = cs.length; i < len; i++){ | ||
278 | clearAttr(cs[i], '_nodup'); | ||
279 | } | ||
280 | return r; | ||
281 | } | ||
282 | |||
283 | function quickDiff(c1, c2){ | ||
284 | if(!c1.length){ | ||
285 | return c2; | ||
286 | } | ||
287 | for(var i = 0, len = c1.length; i < len; i++){ | ||
288 | addAttr(c1[i], '_qdiff', true); | ||
289 | } | ||
290 | var r = []; | ||
291 | for(var i = 0, len = c2.length; i < len; i++){ | ||
292 | if(!getAttr(c2[i], '_qdiff')){ | ||
293 | r[r.length] = c2[i]; | ||
294 | } | ||
295 | } | ||
296 | for(var i = 0, len = c1.length; i < len; i++){ | ||
297 | clearAttr(c1[i], '_qdiff'); | ||
298 | } | ||
299 | return r; | ||
300 | } | ||
301 | |||
302 | function quickId(ns, mode, root, id){ | ||
303 | if(ns == root){ | ||
304 | var d = root.ownerDocument || root; | ||
305 | return d.getElementById(id); | ||
306 | } | ||
307 | ns = getNodes(ns, mode, '*'); | ||
308 | return byId(ns, null, id); | ||
309 | } | ||
310 | |||
311 | return { | ||
312 | getStyle : function(el, name){ | ||
313 | return YAHOO.util.Dom.getStyle(el, name); | ||
314 | }, | ||
315 | /** | ||
316 | * Compiles a selector/xpath query into a reusable function. The returned function | ||
317 | * takes one parameter "root" (optional), which is the context node from where the query should start. | ||
318 | * @param {String} selector The selector/xpath query | ||
319 | * @param {String} type (optional) Either 'select' (the default) or 'simple' for a simple selector match | ||
320 | * @return {Function} | ||
321 | */ | ||
322 | compile : function(path, type){ | ||
323 | // strip leading slashes | ||
324 | while(path.substr(0, 1)=='/'){ | ||
325 | path = path.substr(1); | ||
326 | } | ||
327 | type = type || 'select'; | ||
328 | |||
329 | var fn = ['var f = function(root){\n var mode; var n = root || document;\n']; | ||
330 | var q = path, mode, lq; | ||
331 | var tk = Ext.DomQuery.matchers; | ||
332 | var tklen = tk.length; | ||
333 | var mm; | ||
334 | while(q && lq != q){ | ||
335 | lq = q; | ||
336 | var tm = q.match(/^(#)?([\w-\*]+)/); | ||
337 | if(type == 'select'){ | ||
338 | if(tm){ | ||
339 | if(tm[1] == '#'){ | ||
340 | fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");'; | ||
341 | }else{ | ||
342 | fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");'; | ||
343 | } | ||
344 | q = q.replace(tm[0], ''); | ||
345 | }else{ | ||
346 | fn[fn.length] = 'n = getNodes(n, mode, "*");'; | ||
347 | } | ||
348 | }else{ | ||
349 | if(tm){ | ||
350 | if(tm[1] == '#'){ | ||
351 | fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");'; | ||
352 | }else{ | ||
353 | fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");'; | ||
354 | } | ||
355 | q = q.replace(tm[0], ''); | ||
356 | } | ||
357 | } | ||
358 | while(!(mm = q.match(modeRe))){ | ||
359 | var matched = false; | ||
360 | for(var j = 0; j < tklen; j++){ | ||
361 | var t = tk[j]; | ||
362 | var m = q.match(t.re); | ||
363 | if(m){ | ||
364 | fn[fn.length] = t.select.replace(tplRe, function(x, i){ | ||
365 | return m[i]; | ||
366 | }); | ||
367 | q = q.replace(m[0], ''); | ||
368 | matched = true; | ||
369 | break; | ||
370 | } | ||
371 | } | ||
372 | // prevent infinite loop on bad selector | ||
373 | if(!matched){ | ||
374 | throw 'Error parsing selector, parsing failed at "' + q + '"'; | ||
375 | } | ||
376 | } | ||
377 | if(mm[1]){ | ||
378 | fn[fn.length] = 'mode="'+mm[1]+'";'; | ||
379 | q = q.replace(mm[1], ''); | ||
380 | } | ||
381 | } | ||
382 | fn[fn.length] = 'return nodup(n);\n}'; | ||
383 | eval(fn.join('')); | ||
384 | return f; | ||
385 | }, | ||
386 | |||
387 | /** | ||
388 | * Selects a group of elements. | ||
389 | * @param {String} selector The selector/xpath query | ||
390 | * @param {Node} root (optional) The start of the query (defaults to document). | ||
391 | * @return {Array} | ||
392 | */ | ||
393 | select : function(path, root, type){ | ||
394 | if(!root || root == document){ | ||
395 | root = document; | ||
396 | } | ||
397 | if(typeof root == 'string'){ | ||
398 | root = document.getElementById(root); | ||
399 | } | ||
400 | var paths = path.split(','); | ||
401 | var results = []; | ||
402 | for(var i = 0, len = paths.length; i < len; i++){ | ||
403 | var p = paths[i].replace(trimRe, '$1'); | ||
404 | if(!cache[p]){ | ||
405 | cache[p] = Ext.DomQuery.compile(p); | ||
406 | if(!cache[p]){ | ||
407 | throw p + ' is not a valid selector'; | ||
408 | } | ||
409 | } | ||
410 | var result = cache[p](root); | ||
411 | if(result && result != document){ | ||
412 | results = results.concat(result); | ||
413 | } | ||
414 | } | ||
415 | return results; | ||
416 | }, | ||
417 | |||
418 | /** | ||
419 | * Selects a single element. | ||
420 | * @param {String} selector The selector/xpath query | ||
421 | * @param {Node} root (optional) The start of the query (defaults to document). | ||
422 | * @return {Element} | ||
423 | */ | ||
424 | selectNode : function(path, root){ | ||
425 | return Ext.DomQuery.select(path, root)[0]; | ||
426 | }, | ||
427 | |||
428 | /** | ||
429 | * Selects the value of a node, optionally replacing null with the defaultValue. | ||
430 | * @param {String} selector The selector/xpath query | ||
431 | * @param {Node} root (optional) The start of the query (defaults to document). | ||
432 | * @param {String} defaultValue | ||
433 | */ | ||
434 | selectValue : function(path, root, defaultValue){ | ||
435 | path = path.replace(trimRe, '$1'); | ||
436 | if(!valueCache[path]){ | ||
437 | valueCache[path] = Ext.DomQuery.compile(path, 'simple'); | ||
438 | } | ||
439 | var n = valueCache[path](root); | ||
440 | n = n[0] ? n[0] : n; | ||
441 | var v = (n && n.firstChild ? n.firstChild.nodeValue : null); | ||
442 | return (v === null ? defaultValue : v); | ||
443 | }, | ||
444 | |||
445 | /** | ||
446 | * Selects the value of a node, parsing integers and floats. | ||
447 | * @param {String} selector The selector/xpath query | ||
448 | * @param {Node} root (optional) The start of the query (defaults to document). | ||
449 | * @param {Number} defaultValue | ||
450 | * @return {Number} | ||
451 | */ | ||
452 | selectNumber : function(path, root, defaultValue){ | ||
453 | var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0); | ||
454 | return parseFloat(v); | ||
455 | }, | ||
456 | |||
457 | /** | ||
458 | * Returns true if the passed element(s) match the passed simple selector (e.g. div.some-class or span:first-child) | ||
459 | * @param {String/HTMLElement/Array} el An element id, element or array of elements | ||
460 | * @param {String} selector The simple selector to test | ||
461 | * @return {Boolean} | ||
462 | */ | ||
463 | is : function(el, ss){ | ||
464 | if(typeof el == 'string'){ | ||
465 | el = document.getElementById(el); | ||
466 | } | ||
467 | var isArray = (el instanceof Array); | ||
468 | var result = Ext.DomQuery.filter(isArray ? el : [el], ss); | ||
469 | return isArray ? (result.length == el.length) : (result.length > 0); | ||
470 | }, | ||
471 | |||
472 | /** | ||
473 | * Filters an array of elements to only include matches of a simple selector (e.g. div.some-class or span:first-child) | ||
474 | * @param {Array} el An array of elements to filter | ||
475 | * @param {String} selector The simple selector to test | ||
476 | * @param {Boolean} nonMatches If true, it returns the elements that DON'T match | ||
477 | * the selector instead of the ones that match | ||
478 | * @return {Array} | ||
479 | */ | ||
480 | filter : function(els, ss, nonMatches){ | ||
481 | ss = ss.replace(trimRe, '$1'); | ||
482 | if(!simpleCache[ss]){ | ||
483 | simpleCache[ss] = Ext.DomQuery.compile(ss, 'simple'); | ||
484 | } | ||
485 | var result = simpleCache[ss](els); | ||
486 | return nonMatches ? quickDiff(result, els) : result; | ||
487 | }, | ||
488 | |||
489 | /** | ||
490 | * Collection of matching regular expressions and code snippets. | ||
491 | */ | ||
492 | matchers : [{ | ||
493 | re: /^\.([\w-]+)/, | ||
494 | select: 'n = byClassName(n, null, "{1}");' | ||
495 | }, { | ||
496 | re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/, | ||
497 | select: 'n = byPseudo(n, "{1}", "{2}");' | ||
498 | },{ | ||
499 | re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/, | ||
500 | select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");' | ||
501 | }, { | ||
502 | re: /^#([\w-]+)/, | ||
503 | select: 'n = byId(n, null, "{1}");' | ||
504 | },{ | ||
505 | re: /^@([\w-]+)/, | ||
506 | select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};' | ||
507 | } | ||
508 | ], | ||
509 | |||
510 | /** | ||
511 | * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *= and %=. | ||
512 | * 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, > <. | ||
513 | */ | ||
514 | operators : { | ||
515 | '=' : function(a, v){ | ||
516 | return a == v; | ||
517 | }, | ||
518 | '!=' : function(a, v){ | ||
519 | return a != v; | ||
520 | }, | ||
521 | '^=' : function(a, v){ | ||
522 | return a && a.substr(0, v.length) == v; | ||
523 | }, | ||
524 | '$=' : function(a, v){ | ||
525 | return a && a.substr(a.length-v.length) == v; | ||
526 | }, | ||
527 | '*=' : function(a, v){ | ||
528 | return a && a.indexOf(v) !== -1; | ||
529 | }, | ||
530 | '%=' : function(a, v){ | ||
531 | return (a % v) == 0; | ||
532 | } | ||
533 | }, | ||
534 | |||
535 | /** | ||
536 | * Collection of "pseudo class" processors. Each processor is passed the current nodeset (array) | ||
537 | * and the argument (if any) supplied in the selector. | ||
538 | */ | ||
539 | pseudos : { | ||
540 | 'first-child' : function(c){ | ||
541 | var r = []; | ||
542 | for(var i = 0, l = c.length; i < l; i++){ | ||
543 | var ci = c[i]; | ||
544 | if(!prev(ci)){ | ||
545 | r[r.length] = ci; | ||
546 | } | ||
547 | } | ||
548 | return r; | ||
549 | }, | ||
550 | |||
551 | 'last-child' : function(c){ | ||
552 | var r = []; | ||
553 | for(var i = 0, l = c.length; i < l; i++){ | ||
554 | var ci = c[i]; | ||
555 | if(!next(ci)){ | ||
556 | r[r.length] = ci; | ||
557 | } | ||
558 | } | ||
559 | return r; | ||
560 | }, | ||
561 | |||
562 | 'nth-child' : function(c, a){ | ||
563 | var r = []; | ||
564 | if(a != 'odd' && a != 'even'){ | ||
565 | for(var i = 0, ci; ci = c[i]; i++){ | ||
566 | var m = child(ci.parentNode, a); | ||
567 | if(m == ci){ | ||
568 | r[r.length] = m; | ||
569 | } | ||
570 | } | ||
571 | return r; | ||
572 | } | ||
573 | var p; | ||
574 | // first let's clean up the parent nodes | ||
575 | for(var i = 0, l = c.length; i < l; i++){ | ||
576 | var cp = c[i].parentNode; | ||
577 | if(cp != p){ | ||
578 | clean(cp); | ||
579 | p = cp; | ||
580 | } | ||
581 | } | ||
582 | // then lets see if we match | ||
583 | for(var i = 0, l = c.length; i < l; i++){ | ||
584 | var ci = c[i], m = false; | ||
585 | if(a == 'odd'){ | ||
586 | m = ((ci.nodeIndex+1) % 2 == 1); | ||
587 | }else if(a == 'even'){ | ||
588 | m = ((ci.nodeIndex+1) % 2 == 0); | ||
589 | } | ||
590 | if(m){ | ||
591 | r[r.length] = ci; | ||
592 | } | ||
593 | } | ||
594 | return r; | ||
595 | }, | ||
596 | |||
597 | 'only-child' : function(c){ | ||
598 | var r = []; | ||
599 | for(var i = 0, l = c.length; i < l; i++){ | ||
600 | var ci = c[i]; | ||
601 | if(!prev(ci) && !next(ci)){ | ||
602 | r[r.length] = ci; | ||
603 | } | ||
604 | } | ||
605 | return r; | ||
606 | }, | ||
607 | |||
608 | 'empty' : function(c){ | ||
609 | var r = []; | ||
610 | for(var i = 0, l = c.length; i < l; i++){ | ||
611 | var ci = c[i]; | ||
612 | if(!ci.firstChild){ | ||
613 | r[r.length] = ci; | ||
614 | } | ||
615 | } | ||
616 | return r; | ||
617 | }, | ||
618 | |||
619 | 'contains' : function(c, v){ | ||
620 | var r = []; | ||
621 | for(var i = 0, l = c.length; i < l; i++){ | ||
622 | var ci = c[i]; | ||
623 | if(ci.innerHTML.indexOf(v) !== -1){ | ||
624 | r[r.length] = ci; | ||
625 | } | ||
626 | } | ||
627 | return r; | ||
628 | }, | ||
629 | |||
630 | 'checked' : function(c){ | ||
631 | var r = []; | ||
632 | for(var i = 0, l = c.length; i < l; i++){ | ||
633 | if(c[i].checked == 'checked'){ | ||
634 | r[r.length] = c[i]; | ||
635 | } | ||
636 | } | ||
637 | return r; | ||
638 | }, | ||
639 | |||
640 | 'not' : function(c, ss){ | ||
641 | return Ext.DomQuery.filter(c, ss, true); | ||
642 | }, | ||
643 | |||
644 | 'odd' : function(c){ | ||
645 | return this['nth-child'](c, 'odd'); | ||
646 | }, | ||
647 | |||
648 | 'even' : function(c){ | ||
649 | return this['nth-child'](c, 'even'); | ||
650 | }, | ||
651 | |||
652 | 'nth' : function(c, a){ | ||
653 | return c[a-1]; | ||
654 | }, | ||
655 | |||
656 | 'first' : function(c){ | ||
657 | return c[0]; | ||
658 | }, | ||
659 | |||
660 | 'last' : function(c){ | ||
661 | return c[c.length-1]; | ||
662 | }, | ||
663 | |||
664 | 'has' : function(c, ss){ | ||
665 | var s = Ext.DomQuery.select; | ||
666 | var r = []; | ||
667 | for(var i = 0, ci; ci = c[i]; i++){ | ||
668 | if(s(ss, ci).length > 0){ | ||
669 | r[r.length] = ci; | ||
670 | } | ||
671 | } | ||
672 | return r; | ||
673 | }, | ||
674 | |||
675 | 'next' : function(c, ss){ | ||
676 | var is = Ext.DomQuery.is; | ||
677 | var r = []; | ||
678 | for(var i = 0, ci; ci = c[i]; i++){ | ||
679 | var n = next(ci); | ||
680 | if(n && is(n, ss)){ | ||
681 | r[r.length] = ci; | ||
682 | } | ||
683 | } | ||
684 | return r; | ||
685 | }, | ||
686 | |||
687 | 'prev' : function(c, ss){ | ||
688 | var is = Ext.DomQuery.is; | ||
689 | var r = []; | ||
690 | for(var i = 0, ci; ci = c[i]; i++){ | ||
691 | var n = prev(ci); | ||
692 | if(n && is(n, ss)){ | ||
693 | r[r.length] = ci; | ||
694 | } | ||
695 | } | ||
696 | return r; | ||
697 | } | ||
698 | } | ||
699 | }; | ||
700 | }(); | ||
701 | |||
702 | /** | ||
703 | * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select} | ||
704 | * @param {String} path The selector/xpath query | ||
705 | * @param {Node} root (optional) The start of the query (defaults to document). | ||
706 | * @return {Array} | ||
707 | * @member Ext | ||
708 | * @method query | ||
709 | */ | ||
710 | Ext.query = Ext.DomQuery.select; | ||