summaryrefslogtreecommitdiff
path: root/frontend/beta/js/Clipperz/YUI/DomQuery.js
Unidiff
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.js710
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
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer 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 */
40Ext.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, &gt; &lt;.
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 */
710Ext.query = Ext.DomQuery.select;