summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/YUI/DomHelper.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/Clipperz/YUI/DomHelper.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/YUI/DomHelper.js481
1 files changed, 481 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/YUI/DomHelper.js b/frontend/gamma/js/Clipperz/YUI/DomHelper.js
new file mode 100644
index 0000000..dbd8c93
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/YUI/DomHelper.js
@@ -0,0 +1,481 @@
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
29if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
30if (typeof(Clipperz.YUI) == 'undefined') { Clipperz.YUI = {}; }
31
32
33/**
34 * @class Clipperz.ext.DomHelper
35 * Utility class for working with DOM and/or Templates. It transparently supports using HTML fragments or DOM.
36 * 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>.
37 * @singleton
38 */
39Clipperz.YUI.DomHelper = new function(){
40 /**@private*/
41 var d = document;
42 var tempTableEl = null;
43 /** True to force the use of DOM instead of html fragments @type Boolean */
44 this.useDom = false;
45 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;
46 /**
47 * Applies a style specification to an element
48 * @param {String/HTMLElement} el The element to apply styles to
49 * @param {String/Object/Function} styles A style specification string eg "width:100px", or object in the form {width:"100px"}, or
50 * a function which returns such a specification.
51 */
52 this.applyStyles = function(el, styles){
53 if(styles){
54 var D = YAHOO.util.Dom;
55 if (typeof styles == "string"){
56 var re = /\s?([a-z\-]*)\:([^;]*);?/gi;
57 var matches;
58 while ((matches = re.exec(styles)) != null){
59 D.setStyle(el, matches[1], matches[2]);
60 }
61 }else if (typeof styles == "object"){
62 for (var style in styles){
63 D.setStyle(el, style, styles[style]);
64 }
65 }else if (typeof styles == "function"){
66 Clipperz.YUI.DomHelper.applyStyles(el, styles.call());
67 }
68 }
69 };
70
71 // build as innerHTML where available
72 /** @ignore */
73 var createHtml = function(o){
74 var b = '';
75
76 if(typeof(o['html']) != 'undefined') {
77 o['html'] = Clipperz.Base.sanitizeString(o['html']);
78 } else if (typeof(o['htmlString']) != 'undefined') {
79 o['html'] = o['htmlString'];
80 delete o.htmlString;
81 }
82
83 if (MochiKit.Base.isArrayLike(o)) {
84 for (var i = 0, l = o.length; i < l; i++) {
85 b += createHtml(o[i]);
86 }
87 return b;
88 }
89
90 b += '<' + o.tag;
91 for(var attr in o){
92 if(attr == 'tag' || attr == 'children' || attr == 'html' || typeof o[attr] == 'function') continue;
93 if(attr == 'style'){
94 var s = o['style'];
95 if(typeof s == 'function'){
96 s = s.call();
97 }
98 if(typeof s == 'string'){
99 b += ' style="' + s + '"';
100 }else if(typeof s == 'object'){
101 b += ' style="';
102 for(var key in s){
103 if(typeof s[key] != 'function'){
104 b += key + ':' + s[key] + ';';
105 }
106 }
107 b += '"';
108 }
109 }else{
110 if(attr == 'cls'){
111 b += ' class="' + o['cls'] + '"';
112 }else if(attr == 'htmlFor'){
113 b += ' for="' + o['htmlFor'] + '"';
114 }else{
115 b += ' ' + attr + '="' + o[attr] + '"';
116 }
117 }
118 }
119 if(emptyTags.test(o.tag)){
120 b += ' />';
121 }else{
122 b += '>';
123 if(o.children){
124 for(var i = 0, len = o.children.length; i < len; i++) {
125 b += createHtml(o.children[i], b);
126 }
127 }
128 if(o.html){
129 b += o.html;
130 }
131 b += '</' + o.tag + '>';
132 }
133 return b;
134 }
135
136 // build as dom
137 /** @ignore */
138 var createDom = function(o, parentNode){
139 var el = d.createElement(o.tag);
140 var useSet = el.setAttribute ? true : false; // In IE some elements don't have setAttribute
141 for(var attr in o){
142 if(attr == 'tag' || attr == 'children' || attr == 'html' || attr == 'style' || typeof o[attr] == 'function') continue;
143 if(attr=='cls'){
144 el.className = o['cls'];
145 }else{
146 if(useSet) el.setAttribute(attr, o[attr]);
147 else el[attr] = o[attr];
148 }
149 }
150 Clipperz.YUI.DomHelper.applyStyles(el, o.style);
151 if(o.children){
152 for(var i = 0, len = o.children.length; i < len; i++) {
153 createDom(o.children[i], el);
154 }
155 }
156 if(o.html){
157 el.innerHTML = o.html;
158 }
159 if(parentNode){
160 parentNode.appendChild(el);
161 }
162 return el;
163 };
164
165 /**
166 * @ignore
167 * Nasty code for IE's broken table implementation
168 */
169 var insertIntoTable = function(tag, where, el, html){
170 if(!tempTableEl){
171 tempTableEl = document.createElement('div');
172 }
173 var nodes;
174 if(tag == 'table' || tag == 'tbody'){
175 tempTableEl.innerHTML = '<table><tbody>'+html+'</tbody></table>';
176 nodes = tempTableEl.firstChild.firstChild.childNodes;
177 }else{
178 tempTableEl.innerHTML = '<table><tbody><tr>'+html+'</tr></tbody></table>';
179 nodes = tempTableEl.firstChild.firstChild.firstChild.childNodes;
180 }
181 if (where == 'beforebegin') {
182 nodes.reverse();
183 // el.parentNode.insertBefore(node, el);
184 MochiKit.Base.map(function(aNode) {el.parentNode.insertBefore(aNode, el)}, nodes);
185 } else if (where == 'afterbegin') {
186 nodes.reverse();
187 // el.insertBefore(node, el.firstChild);
188 MochiKit.Base.map(function(aNode) {el.insertBefore(aNode, el.firstChild)}, nodes);
189 } else if (where == 'beforeend') {
190 // el.appendChild(node);
191 MochiKit.Base.map(function(aNode) {el.appendChild(aNode)}, nodes);
192 } else if (where == 'afterend') {
193 // el.parentNode.insertBefore(node, el.nextSibling);
194 MochiKit.Base.map(function(aNode) {el.parentNode.insertBefore(aNode, el.nextSibling)}, nodes);
195 }
196
197 return nodes;
198 }
199
200 /**
201 * Inserts an HTML fragment into the Dom
202 * @param {String} where Where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.
203 * @param {HTMLElement} el The context element
204 * @param {String} html The HTML fragmenet
205 * @return {HTMLElement} The new node
206 */
207 this.insertHtml = function(where, el, html){
208 where = where.toLowerCase();
209 // if(el.insertAdjacentHTML){
210 if(Clipperz_IEisBroken){
211 var tag = el.tagName.toLowerCase();
212 if(tag == 'table' || tag == 'tbody' || tag == 'tr'){
213 return insertIntoTable(tag, where, el, html);
214 }
215 switch(where){
216 case 'beforebegin':
217 el.insertAdjacentHTML(where, html);
218 return el.previousSibling;
219 case 'afterbegin':
220 el.insertAdjacentHTML(where, html);
221 return el.firstChild;
222 case 'beforeend':
223 el.insertAdjacentHTML(where, html);
224 return el.lastChild;
225 case 'afterend':
226 el.insertAdjacentHTML(where, html);
227 return el.nextSibling;
228 }
229 throw 'Illegal insertion point -> "' + where + '"';
230 }
231 var range = el.ownerDocument.createRange();
232 var frag;
233 switch(where){
234 case 'beforebegin':
235 range.setStartBefore(el);
236 frag = range.createContextualFragment(html);
237 el.parentNode.insertBefore(frag, el);
238 return el.previousSibling;
239 case 'afterbegin':
240 if(el.firstChild){ // faster
241 range.setStartBefore(el.firstChild);
242 }else{
243 range.selectNodeContents(el);
244 range.collapse(true);
245 }
246 frag = range.createContextualFragment(html);
247 el.insertBefore(frag, el.firstChild);
248 return el.firstChild;
249 case 'beforeend':
250 if(el.lastChild){
251 range.setStartAfter(el.lastChild); // faster
252 }else{
253 range.selectNodeContents(el);
254 range.collapse(false);
255 }
256 frag = range.createContextualFragment(html);
257 el.appendChild(frag);
258 return el.lastChild;
259 case 'afterend':
260 range.setStartAfter(el);
261 frag = range.createContextualFragment(html);
262 el.parentNode.insertBefore(frag, el.nextSibling);
263 return el.nextSibling;
264 }
265 throw 'Illegal insertion point -> "' + where + '"';
266 };
267
268 /**
269 * Creates new Dom element(s) and inserts them before el
270 * @param {String/HTMLElement/Element} el The context element
271 * @param {Object} o The Dom object spec (and children)
272 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
273 * @return {HTMLElement} The new node
274 */
275 this.insertBefore = function(el, o, returnElement){
276 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
277 var newNode;
278 if(this.useDom){
279 newNode = createDom(o, null);
280 el.parentNode.insertBefore(newNode, el);
281 }else{
282 var html = createHtml(o);
283 newNode = this.insertHtml('beforeBegin', el, html);
284 }
285 return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
286 };
287
288 /**
289 * Creates new Dom element(s) and inserts them after el
290 * @param {String/HTMLElement/Element} el The context element
291 * @param {Object} o The Dom object spec (and children)
292 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
293 * @return {HTMLElement} The new node
294 */
295 this.insertAfter = function(el, o, returnElement){
296 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
297 var newNode;
298 if(this.useDom){
299 newNode = createDom(o, null);
300 el.parentNode.insertBefore(newNode, el.nextSibling);
301 }else{
302 var html = createHtml(o);
303 newNode = this.insertHtml('afterEnd', el, html);
304 }
305 return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
306 };
307
308 /**
309 * Creates new Dom element(s) and appends them to el
310 * @param {String/HTMLElement/Element} el The context element
311 * @param {Object} o The Dom object spec (and children)
312 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
313 * @return {HTMLElement} The new node
314 */
315 this.append = function(el, o, returnElement){
316 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
317 var newNode;
318 if(this.useDom){
319 newNode = createDom(o, null);
320 el.appendChild(newNode);
321 }else{
322 var html = createHtml(o);
323 newNode = this.insertHtml('beforeEnd', el, html);
324 }
325 return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
326 };
327
328 /**
329 * Creates new Dom element(s) and overwrites the contents of el with them
330 * @param {String/HTMLElement/Element} el The context element
331 * @param {Object} o The Dom object spec (and children)
332 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
333 * @return {HTMLElement} The new node
334 */
335 this.overwrite = function(el, o, returnElement){
336 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
337 el.innerHTML = createHtml(o);
338 return returnElement ? YAHOO.Element.get(el.firstChild, true) : el.firstChild;
339 };
340
341 /**
342 * Creates a new Clipperz.YUI.DomHelper.Template from the Dom object spec
343 * @param {Object} o The Dom object spec (and children)
344 * @return {Clipperz.YUI.DomHelper.Template} The new template
345 */
346 this.createTemplate = function(o){
347 var html = createHtml(o);
348 return new Clipperz.YUI.DomHelper.Template(html);
349 };
350}();
351
352/**
353* @class Clipperz.YUI.DomHelper.Template
354* Represents an HTML fragment template.
355* 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>.
356* <br>
357* <b>This class is also available as Clipperz.YUI.Template</b>.
358* @constructor
359* @param {String/Array} html The HTML fragment or an array of fragments to join('') or multiple arguments to join('')
360*/
361Clipperz.YUI.DomHelper.Template = function(html){
362 if(html instanceof Array){
363 html = html.join('');
364 }else if(arguments.length > 1){
365 html = Array.prototype.join.call(arguments, '');
366 }
367 /**@private*/
368 this.html = html;
369};
370Clipperz.YUI.DomHelper.Template.prototype = {
371 /**
372 * Returns an HTML fragment of this template with the specified values applied
373 * @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'})
374 * @return {String}
375 */
376 applyTemplate : function(values){
377 if(this.compiled){
378 return this.compiled(values);
379 }
380 var empty = '';
381 var fn = function(match, index){
382 if(typeof values[index] != 'undefined'){
383 return values[index];
384 }else{
385 return empty;
386 }
387 }
388 return this.html.replace(this.re, fn);
389 },
390
391 /**
392 * The regular expression used to match template variables
393 * @type RegExp
394 * @property
395 */
396 re : /\{([\w|-]+)\}/g,
397
398 /**
399 * Compiles the template into an internal function, eliminating the RegEx overhead
400 */
401 compile : function(){
402 var body = ["this.compiled = function(values){ return ['"];
403 body.push(this.html.replace(this.re, "', values['$1'], '"));
404 body.push("'].join('');};");
405 eval(body.join(''));
406 return this;
407 },
408
409 /**
410 * Applies the supplied values to the template and inserts the new node(s) before el
411 * @param {String/HTMLElement/Element} el The context element
412 * @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'})
413 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
414 * @return {HTMLElement} The new node
415 */
416 insertBefore: function(el, values, returnElement){
417 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
418 var newNode = Clipperz.YUI.DomHelper.insertHtml('beforeBegin', el, this.applyTemplate(values));
419 return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
420 },
421
422 /**
423 * Applies the supplied values to the template and inserts the new node(s) after el
424 * @param {String/HTMLElement/Element} el The context element
425 * @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'})
426 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
427 * @return {HTMLElement} The new node
428 */
429 insertAfter : function(el, values, returnElement){
430 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
431 var newNode = Clipperz.YUI.DomHelper.insertHtml('afterEnd', el, this.applyTemplate(values));
432 return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
433 },
434
435 /**
436 * Applies the supplied values to the template and append the new node(s) to el
437 * @param {String/HTMLElement/Element} el The context element
438 * @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'})
439 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
440 * @return {HTMLElement} The new node
441 */
442 append : function(el, values, returnElement){
443 var sanitizedValues;
444 var key;
445
446 // sanitizedValues = MochiKit.Base.map(sanitizedValues)
447//console.log("values", values);
448 sanitizedValues = {};
449 for (key in values) {
450 sanitizedValues[key] = Clipperz.Base.sanitizeString(values[key]);
451 }
452//console.log("sanitizedValues", sanitizedValues);
453// el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
454 el = (typeof el == 'string') ? YAHOO.util.Dom.get(el) : el;
455//Clipperz.log(this.applyTemplate(sanitizedValues));
456 var newNode = Clipperz.YUI.DomHelper.insertHtml('beforeEnd', el, this.applyTemplate(sanitizedValues));
457// return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
458 return newNode;
459 },
460
461 /**
462 * Applies the supplied values to the template and overwrites the content of el with the new node(s)
463 * @param {String/HTMLElement/Element} el The context element
464 * @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'})
465 * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
466 * @return {HTMLElement} The new node
467 */
468 overwrite : function(el, values, returnElement){
469 el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
470 el.innerHTML = '';
471 var newNode = Clipperz.YUI.DomHelper.insertHtml('beforeEnd', el, this.applyTemplate(values));
472 return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
473 }
474};
475/**
476 * Alias for applyTemplate
477 * @method
478 */
479Clipperz.YUI.DomHelper.Template.prototype.apply = Clipperz.YUI.DomHelper.Template.prototype.applyTemplate;
480
481Clipperz.YUI.Template = Clipperz.YUI.DomHelper.Template;