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