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