summaryrefslogtreecommitdiff
path: root/frontend/delta/js/MochiKit/DOM.js
Unidiff
Diffstat (limited to 'frontend/delta/js/MochiKit/DOM.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/MochiKit/DOM.js1202
1 files changed, 1202 insertions, 0 deletions
diff --git a/frontend/delta/js/MochiKit/DOM.js b/frontend/delta/js/MochiKit/DOM.js
new file mode 100644
index 0000000..23d996b
--- a/dev/null
+++ b/frontend/delta/js/MochiKit/DOM.js
@@ -0,0 +1,1202 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer 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/***
25
26MochiKit.DOM 1.5
27
28See <http://mochikit.com/> for documentation, downloads, license, etc.
29
30(c) 2005 Bob Ippolito. All rights Reserved.
31
32***/
33
34MochiKit.Base.module(MochiKit, 'DOM', '1.5', ['Base']);
35
36MochiKit.Base.update(MochiKit.DOM, {
37
38 /** @id MochiKit.DOM.currentWindow */
39 currentWindow: function () {
40 return MochiKit.DOM._window;
41 },
42
43 /** @id MochiKit.DOM.currentDocument */
44 currentDocument: function () {
45 return MochiKit.DOM._document;
46 },
47
48 /** @id MochiKit.DOM.withWindow */
49 withWindow: function (win, func) {
50 var self = MochiKit.DOM;
51 var oldDoc = self._document;
52 var oldWin = self._window;
53 var rval;
54 try {
55 self._window = win;
56 self._document = win.document;
57 rval = func();
58 } catch (e) {
59 self._window = oldWin;
60 self._document = oldDoc;
61 throw e;
62 }
63 self._window = oldWin;
64 self._document = oldDoc;
65 return rval;
66 },
67
68 /** @id MochiKit.DOM.formContents */
69 formContents: function (elem/* = document.body */) {
70 var names = [];
71 var values = [];
72 var m = MochiKit.Base;
73 var self = MochiKit.DOM;
74 if (typeof(elem) == "undefined" || elem === null) {
75 elem = self._document.body;
76 } else {
77 elem = self.getElement(elem);
78 }
79 m.nodeWalk(elem, function (elem) {
80 var name = elem.name;
81 if (m.isNotEmpty(name)) {
82 var tagName = elem.tagName.toUpperCase();
83 if (tagName === "INPUT"
84 && (elem.type == "radio" || elem.type == "checkbox")
85 && !elem.checked
86 ) {
87 return null;
88 }
89 if (tagName === "SELECT") {
90 if (elem.type == "select-one") {
91 if (elem.selectedIndex >= 0) {
92 var opt = elem.options[elem.selectedIndex];
93 var v = opt.value;
94 if (!v) {
95 var h = opt.outerHTML;
96 // internet explorer sure does suck.
97 if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
98 v = opt.text;
99 }
100 }
101 names.push(name);
102 values.push(v);
103 return null;
104 }
105 // no form elements?
106 names.push(name);
107 values.push("");
108 return null;
109 } else {
110 var opts = elem.options;
111 if (!opts.length) {
112 names.push(name);
113 values.push("");
114 return null;
115 }
116 for (var i = 0; i < opts.length; i++) {
117 var opt = opts[i];
118 if (!opt.selected) {
119 continue;
120 }
121 var v = opt.value;
122 if (!v) {
123 var h = opt.outerHTML;
124 // internet explorer sure does suck.
125 if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
126 v = opt.text;
127 }
128 }
129 names.push(name);
130 values.push(v);
131 }
132 return null;
133 }
134 }
135 if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
136 || tagName === "DIV"
137 ) {
138 return elem.childNodes;
139 }
140 names.push(name);
141 values.push(elem.value || '');
142 return null;
143 }
144 return elem.childNodes;
145 });
146 return [names, values];
147 },
148
149 /** @id MochiKit.DOM.withDocument */
150 withDocument: function (doc, func) {
151 var self = MochiKit.DOM;
152 var oldDoc = self._document;
153 var rval;
154 try {
155 self._document = doc;
156 rval = func();
157 } catch (e) {
158 self._document = oldDoc;
159 throw e;
160 }
161 self._document = oldDoc;
162 return rval;
163 },
164
165 /** @id MochiKit.DOM.registerDOMConverter */
166 registerDOMConverter: function (name, check, wrap, /* optional */override) {
167 MochiKit.DOM.domConverters.register(name, check, wrap, override);
168 },
169
170 /** @id MochiKit.DOM.coerceToDOM */
171 coerceToDOM: function (node, ctx) {
172 var m = MochiKit.Base;
173 var im = MochiKit.Iter;
174 var self = MochiKit.DOM;
175 if (im) {
176 var iter = im.iter;
177 var repeat = im.repeat;
178 }
179 var map = m.map;
180 var domConverters = self.domConverters;
181 var coerceToDOM = arguments.callee;
182 var NotFound = m.NotFound;
183 while (true) {
184 if (typeof(node) == 'undefined' || node === null) {
185 return null;
186 }
187 // this is a safari childNodes object, avoiding crashes w/ attr
188 // lookup
189 if (typeof(node) == "function" &&
190 typeof(node.length) == "number" &&
191 !(node instanceof Function)) {
192 node = im ? im.list(node) : m.extend(null, node);
193 }
194 if (typeof(node.nodeType) != 'undefined' && node.nodeType > 0) {
195 return node;
196 }
197 if (typeof(node) == 'number' || typeof(node) == 'boolean') {
198 node = node.toString();
199 // FALL THROUGH
200 }
201 if (typeof(node) == 'string') {
202 return self._document.createTextNode(node);
203 }
204 if (typeof(node.__dom__) == 'function') {
205 node = node.__dom__(ctx);
206 continue;
207 }
208 if (typeof(node.dom) == 'function') {
209 node = node.dom(ctx);
210 continue;
211 }
212 if (typeof(node) == 'function') {
213 node = node.apply(ctx, [ctx]);
214 continue;
215 }
216
217 if (im) {
218 // iterable
219 var iterNodes = null;
220 try {
221 iterNodes = iter(node);
222 } catch (e) {
223 // pass
224 }
225 if (iterNodes) {
226 return map(coerceToDOM, iterNodes, repeat(ctx));
227 }
228 } else if (m.isArrayLike(node)) {
229 var func = function (n) { return coerceToDOM(n, ctx); };
230 return map(func, node);
231 }
232
233 // adapter
234 try {
235 node = domConverters.match(node, ctx);
236 continue;
237 } catch (e) {
238 if (e != NotFound) {
239 throw e;
240 }
241 }
242
243 // fallback
244 return self._document.createTextNode(node.toString());
245 }
246 // mozilla warnings aren't too bright
247 return undefined;
248 },
249
250 /** @id MochiKit.DOM.isChildNode */
251 isChildNode: function (node, maybeparent) {
252 var self = MochiKit.DOM;
253 if (typeof(node) == "string") {
254 node = self.getElement(node);
255 }
256 if (typeof(maybeparent) == "string") {
257 maybeparent = self.getElement(maybeparent);
258 }
259 if (typeof(node) == 'undefined' || node === null) {
260 return false;
261 }
262 while (node != null && node !== self._document) {
263 if (node === maybeparent) {
264 return true;
265 }
266 node = node.parentNode;
267 }
268 return false;
269 },
270
271 /** @id MochiKit.DOM.setNodeAttribute */
272 setNodeAttribute: function (node, attr, value) {
273 var o = {};
274 o[attr] = value;
275 try {
276 return MochiKit.DOM.updateNodeAttributes(node, o);
277 } catch (e) {
278 // pass
279 }
280 return null;
281 },
282
283 /** @id MochiKit.DOM.getNodeAttribute */
284 getNodeAttribute: function (node, attr) {
285 var self = MochiKit.DOM;
286 var rename = self.attributeArray.renames[attr];
287 var ignoreValue = self.attributeArray.ignoreAttr[attr];
288 node = self.getElement(node);
289 try {
290 if (rename) {
291 return node[rename];
292 }
293 var value = node.getAttribute(attr);
294 if (value != ignoreValue) {
295 return value;
296 }
297 } catch (e) {
298 // pass
299 }
300 return null;
301 },
302
303 /** @id MochiKit.DOM.removeNodeAttribute */
304 removeNodeAttribute: function (node, attr) {
305 var self = MochiKit.DOM;
306 var rename = self.attributeArray.renames[attr];
307 node = self.getElement(node);
308 try {
309 if (rename) {
310 return node[rename];
311 }
312 return node.removeAttribute(attr);
313 } catch (e) {
314 // pass
315 }
316 return null;
317 },
318
319 /** @id MochiKit.DOM.updateNodeAttributes */
320 updateNodeAttributes: function (node, attrs) {
321 var elem = node;
322 var self = MochiKit.DOM;
323 var base = MochiKit.Base;
324 if (typeof(node) == 'string') {
325 elem = self.getElement(node);
326 }
327 if (attrs) {
328 if (self.attributeArray.compliant) {
329 // not IE, good.
330 for (var k in attrs) {
331 var v = attrs[k];
332 if (typeof(v) == 'object' && typeof(elem[k]) == 'object') {
333 if (k == "style" && MochiKit.Style) {
334 MochiKit.Style.setStyle(elem, v);
335 } else {
336 base.updatetree(elem[k], v);
337 }
338 } else if (k.substring(0, 2) == "on") {
339 if (typeof(v) == "string") {
340 v = new Function(v);
341 }
342 elem[k] = v;
343 } else {
344 elem.setAttribute(k, v);
345 }
346 if (base.isValue(elem[k]) && elem[k] != v) {
347 // Also set property for weird attributes (see #302 & #335)
348 elem[k] = v;
349 }
350 }
351 } else {
352 // IE is insane in the membrane
353 var renames = self.attributeArray.renames;
354 for (var k in attrs) {
355 v = attrs[k];
356 var renamed = renames[k];
357 if (k == "style" && typeof(v) == "string") {
358 elem.style.cssText = v;
359 } else if (typeof(renamed) == "string") {
360 elem[renamed] = v;
361 } else if (typeof(elem[k]) == 'object'
362 && typeof(v) == 'object') {
363 if (k == "style" && MochiKit.Style) {
364 MochiKit.Style.setStyle(elem, v);
365 } else {
366 base.updatetree(elem[k], v);
367 }
368 } else if (k.substring(0, 2) == "on") {
369 if (typeof(v) == "string") {
370 v = new Function(v);
371 }
372 elem[k] = v;
373 } else {
374 elem.setAttribute(k, v);
375 }
376 if (base.isValue(elem[k]) && elem[k] != v) {
377 // Also set property for weird attributes (see #302 & #335)
378 elem[k] = v;
379 }
380 }
381 }
382 }
383 return elem;
384 },
385
386 /** @id MochiKit.DOM.appendChildNodes */
387 appendChildNodes: function (node/*, nodes...*/) {
388 var elem = node;
389 var self = MochiKit.DOM;
390 if (typeof(node) == 'string') {
391 elem = self.getElement(node);
392 }
393 var nodeStack = [
394 self.coerceToDOM(
395 MochiKit.Base.extend(null, arguments, 1),
396 elem
397 )
398 ];
399 var concat = MochiKit.Base.concat;
400 while (nodeStack.length) {
401 var n = nodeStack.shift();
402 if (typeof(n) == 'undefined' || n === null) {
403 // pass
404 } else if (typeof(n.nodeType) == 'number') {
405 elem.appendChild(n);
406 } else {
407 nodeStack = concat(n, nodeStack);
408 }
409 }
410 return elem;
411 },
412
413
414 /** @id MochiKit.DOM.insertSiblingNodesBefore */
415 insertSiblingNodesBefore: function (node/*, nodes...*/) {
416 var elem = node;
417 var self = MochiKit.DOM;
418 if (typeof(node) == 'string') {
419 elem = self.getElement(node);
420 }
421 var nodeStack = [
422 self.coerceToDOM(
423 MochiKit.Base.extend(null, arguments, 1),
424 elem
425 )
426 ];
427 var parentnode = elem.parentNode;
428 var concat = MochiKit.Base.concat;
429 while (nodeStack.length) {
430 var n = nodeStack.shift();
431 if (typeof(n) == 'undefined' || n === null) {
432 // pass
433 } else if (typeof(n.nodeType) == 'number') {
434 parentnode.insertBefore(n, elem);
435 } else {
436 nodeStack = concat(n, nodeStack);
437 }
438 }
439 return parentnode;
440 },
441
442 /** @id MochiKit.DOM.insertSiblingNodesAfter */
443 insertSiblingNodesAfter: function (node/*, nodes...*/) {
444 var elem = node;
445 var self = MochiKit.DOM;
446
447 if (typeof(node) == 'string') {
448 elem = self.getElement(node);
449 }
450 var nodeStack = [
451 self.coerceToDOM(
452 MochiKit.Base.extend(null, arguments, 1),
453 elem
454 )
455 ];
456
457 if (elem.nextSibling) {
458 return self.insertSiblingNodesBefore(elem.nextSibling, nodeStack);
459 }
460 else {
461 return self.appendChildNodes(elem.parentNode, nodeStack);
462 }
463 },
464
465 /** @id MochiKit.DOM.replaceChildNodes */
466 replaceChildNodes: function (node/*, nodes...*/) {
467 var elem = node;
468 var self = MochiKit.DOM;
469 if (typeof(node) == 'string') {
470 elem = self.getElement(node);
471 arguments[0] = elem;
472 }
473 var child;
474 while ((child = elem.firstChild)) {
475 elem.removeChild(child);
476 }
477 if (arguments.length < 2) {
478 return elem;
479 } else {
480 return self.appendChildNodes.apply(this, arguments);
481 }
482 },
483
484 /** @id MochiKit.DOM.createDOM */
485 createDOM: function (name, attrs/*, nodes... */) {
486 var elem;
487 var self = MochiKit.DOM;
488 var m = MochiKit.Base;
489 if (typeof(attrs) == "string" || typeof(attrs) == "number") {
490 var args = m.extend([name, null], arguments, 1);
491 return arguments.callee.apply(this, args);
492 }
493 if (typeof(name) == 'string') {
494 // Internet Explorer is dumb
495 var xhtml = self._xhtml;
496 if (attrs && !self.attributeArray.compliant) {
497 // http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp
498 var contents = "";
499 if ('name' in attrs) {
500 contents += ' name="' + self.escapeHTML(attrs.name) + '"';
501 }
502 if (name == 'input' && 'type' in attrs) {
503 contents += ' type="' + self.escapeHTML(attrs.type) + '"';
504 }
505 if (contents) {
506 name = "<" + name + contents + ">";
507 xhtml = false;
508 }
509 }
510 var d = self._document;
511 if (xhtml && d === document) {
512 elem = d.createElementNS("http://www.w3.org/1999/xhtml", name);
513 } else {
514 elem = d.createElement(name);
515 }
516 } else {
517 elem = name;
518 }
519 if (attrs) {
520 self.updateNodeAttributes(elem, attrs);
521 }
522 if (arguments.length <= 2) {
523 return elem;
524 } else {
525 var args = m.extend([elem], arguments, 2);
526 return self.appendChildNodes.apply(this, args);
527 }
528 },
529
530 /** @id MochiKit.DOM.createDOMFunc */
531 createDOMFunc: function (/* tag, attrs, *nodes */) {
532 var m = MochiKit.Base;
533 return m.partial.apply(
534 this,
535 m.extend([MochiKit.DOM.createDOM], arguments)
536 );
537 },
538
539 /** @id MochiKit.DOM.removeElement */
540 removeElement: function (elem) {
541 var self = MochiKit.DOM;
542 if (typeof(elem) == "string") {
543 elem = self.getElement(elem);
544 }
545 var e = self.coerceToDOM(elem);
546 e.parentNode.removeChild(e);
547 return e;
548 },
549
550 /** @id MochiKit.DOM.swapDOM */
551 swapDOM: function (dest, src) {
552 var self = MochiKit.DOM;
553 dest = self.getElement(dest);
554 var parent = dest.parentNode;
555 if (src) {
556 if (typeof(src) == "string") {
557 src = self.getElement(src);
558 }
559 src = self.coerceToDOM(src, parent);
560 parent.replaceChild(src, dest);
561 } else {
562 parent.removeChild(dest);
563 }
564 return src;
565 },
566
567 /** @id MochiKit.DOM.getElement */
568 getElement: function (id) {
569 var self = MochiKit.DOM;
570 if (arguments.length == 1) {
571 return ((typeof(id) == "string") ?
572 self._document.getElementById(id) : id);
573 } else {
574 return MochiKit.Base.map(self.getElement, arguments);
575 }
576 },
577
578 /** @id MochiKit.DOM.getElementsByTagAndClassName */
579 getElementsByTagAndClassName: function (tagName, className,
580 /* optional */parent) {
581 var self = MochiKit.DOM;
582 if (typeof(tagName) == 'undefined' || tagName === null) {
583 tagName = '*';
584 }
585 if (typeof(parent) == 'undefined' || parent === null) {
586 parent = self._document;
587 }
588 parent = self.getElement(parent);
589 if (parent == null) {
590 return [];
591 }
592 var children = (parent.getElementsByTagName(tagName)
593 || self._document.all);
594 if (typeof(className) == 'undefined' || className === null) {
595 return MochiKit.Base.extend(null, children);
596 }
597
598 var elements = [];
599 for (var i = 0; i < children.length; i++) {
600 var child = children[i];
601 var cls = child.className;
602 if (typeof(cls) != "string") {
603 cls = child.getAttribute("class");
604 }
605 if (typeof(cls) == "string") {
606 var classNames = cls.split(' ');
607 for (var j = 0; j < classNames.length; j++) {
608 if (classNames[j] == className) {
609 elements.push(child);
610 break;
611 }
612 }
613 }
614 }
615
616 return elements;
617 },
618
619 _newCallStack: function (path, once) {
620 var rval = function () {
621 var callStack = arguments.callee.callStack;
622 for (var i = 0; i < callStack.length; i++) {
623 if (callStack[i].apply(this, arguments) === false) {
624 break;
625 }
626 }
627 if (once) {
628 try {
629 this[path] = null;
630 } catch (e) {
631 // pass
632 }
633 }
634 };
635 rval.callStack = [];
636 return rval;
637 },
638
639 /** @id MochiKit.DOM.addToCallStack */
640 addToCallStack: function (target, path, func, once) {
641 var self = MochiKit.DOM;
642 var existing = target[path];
643 var regfunc = existing;
644 if (!(typeof(existing) == 'function'
645 && typeof(existing.callStack) == "object"
646 && existing.callStack !== null)) {
647 regfunc = self._newCallStack(path, once);
648 if (typeof(existing) == 'function') {
649 regfunc.callStack.push(existing);
650 }
651 target[path] = regfunc;
652 }
653 regfunc.callStack.push(func);
654 },
655
656 /** @id MochiKit.DOM.addLoadEvent */
657 addLoadEvent: function (func) {
658 var self = MochiKit.DOM;
659 self.addToCallStack(self._window, "onload", func, true);
660
661 },
662
663 /** @id MochiKit.DOM.focusOnLoad */
664 focusOnLoad: function (element) {
665 var self = MochiKit.DOM;
666 self.addLoadEvent(function () {
667 element = self.getElement(element);
668 if (element) {
669 element.focus();
670 }
671 });
672 },
673
674 /** @id MochiKit.DOM.setElementClass */
675 setElementClass: function (element, className) {
676 var self = MochiKit.DOM;
677 var obj = self.getElement(element);
678 if (self.attributeArray.compliant) {
679 obj.setAttribute("class", className);
680 } else {
681 obj.setAttribute("className", className);
682 }
683 },
684
685 /** @id MochiKit.DOM.toggleElementClass */
686 toggleElementClass: function (className/*, element... */) {
687 var self = MochiKit.DOM;
688 for (var i = 1; i < arguments.length; i++) {
689 var obj = self.getElement(arguments[i]);
690 if (!self.addElementClass(obj, className)) {
691 self.removeElementClass(obj, className);
692 }
693 }
694 },
695
696 /** @id MochiKit.DOM.addElementClass */
697 addElementClass: function (element, className) {
698 var self = MochiKit.DOM;
699 var obj = self.getElement(element);
700 var cls = obj.className;
701 if (typeof(cls) != "string") {
702 cls = obj.getAttribute("class");
703 }
704 // trivial case, no className yet
705 if (typeof(cls) != "string" || cls.length === 0) {
706 self.setElementClass(obj, className);
707 return true;
708 }
709 // the other trivial case, already set as the only class
710 if (cls == className) {
711 return false;
712 }
713 var classes = cls.split(" ");
714 for (var i = 0; i < classes.length; i++) {
715 // already present
716 if (classes[i] == className) {
717 return false;
718 }
719 }
720 // append class
721 self.setElementClass(obj, cls + " " + className);
722 return true;
723 },
724
725 /** @id MochiKit.DOM.removeElementClass */
726 removeElementClass: function (element, className) {
727 var self = MochiKit.DOM;
728 var obj = self.getElement(element);
729 var cls = obj.className;
730 if (typeof(cls) != "string") {
731 cls = obj.getAttribute("class");
732 }
733 // trivial case, no className yet
734 if (typeof(cls) != "string" || cls.length === 0) {
735 return false;
736 }
737 // other trivial case, set only to className
738 if (cls == className) {
739 self.setElementClass(obj, "");
740 return true;
741 }
742 var classes = cls.split(" ");
743 for (var i = 0; i < classes.length; i++) {
744 // already present
745 if (classes[i] == className) {
746 // only check sane case where the class is used once
747 classes.splice(i, 1);
748 self.setElementClass(obj, classes.join(" "));
749 return true;
750 }
751 }
752 // not found
753 return false;
754 },
755
756 /** @id MochiKit.DOM.swapElementClass */
757 swapElementClass: function (element, fromClass, toClass) {
758 var obj = MochiKit.DOM.getElement(element);
759 var res = MochiKit.DOM.removeElementClass(obj, fromClass);
760 if (res) {
761 MochiKit.DOM.addElementClass(obj, toClass);
762 }
763 return res;
764 },
765
766 /** @id MochiKit.DOM.hasElementClass */
767 hasElementClass: function (element, className/*...*/) {
768 var obj = MochiKit.DOM.getElement(element);
769 if (obj == null) {
770 return false;
771 }
772 var cls = obj.className;
773 if (typeof(cls) != "string" && typeof(obj.getAttribute) == "function") {
774 cls = obj.getAttribute("class");
775 }
776 if (typeof(cls) != "string") {
777 return false;
778 }
779 var classes = cls.split(" ");
780 for (var i = 1; i < arguments.length; i++) {
781 var good = false;
782 for (var j = 0; j < classes.length; j++) {
783 if (classes[j] == arguments[i]) {
784 good = true;
785 break;
786 }
787 }
788 if (!good) {
789 return false;
790 }
791 }
792 return true;
793 },
794
795 /** @id MochiKit.DOM.escapeHTML */
796 escapeHTML: function (s) {
797 return s.replace(/&/g, "&amp;"
798 ).replace(/"/g, "&quot;"
799 ).replace(/</g, "&lt;"
800 ).replace(/>/g, "&gt;");
801 },
802
803 /** @id MochiKit.DOM.toHTML */
804 toHTML: function (dom) {
805 return MochiKit.DOM.emitHTML(dom).join("");
806 },
807
808 /** @id MochiKit.DOM.emitHTML */
809 emitHTML: function (dom, /* optional */lst) {
810 if (typeof(lst) == 'undefined' || lst === null) {
811 lst = [];
812 }
813 // queue is the call stack, we're doing this non-recursively
814 var queue = [dom];
815 var self = MochiKit.DOM;
816 var escapeHTML = self.escapeHTML;
817 var attributeArray = self.attributeArray;
818 while (queue.length) {
819 dom = queue.pop();
820 if (typeof(dom) == 'string') {
821 lst.push(dom);
822 } else if (dom.nodeType == 1) {
823 // we're not using higher order stuff here
824 // because safari has heisenbugs.. argh.
825 //
826 // I think it might have something to do with
827 // garbage collection and function calls.
828 lst.push('<' + dom.tagName.toLowerCase());
829 var attributes = [];
830 var domAttr = attributeArray(dom);
831 for (var i = 0; i < domAttr.length; i++) {
832 var a = domAttr[i];
833 attributes.push([
834 " ",
835 a.name,
836 '="',
837 escapeHTML(a.value),
838 '"'
839 ]);
840 }
841 attributes.sort();
842 for (i = 0; i < attributes.length; i++) {
843 var attrs = attributes[i];
844 for (var j = 0; j < attrs.length; j++) {
845 lst.push(attrs[j]);
846 }
847 }
848 if (dom.hasChildNodes()) {
849 lst.push(">");
850 // queue is the FILO call stack, so we put the close tag
851 // on first
852 queue.push("</" + dom.tagName.toLowerCase() + ">");
853 var cnodes = dom.childNodes;
854 for (i = cnodes.length - 1; i >= 0; i--) {
855 queue.push(cnodes[i]);
856 }
857 } else {
858 lst.push('/>');
859 }
860 } else if (dom.nodeType == 3) {
861 lst.push(escapeHTML(dom.nodeValue));
862 }
863 }
864 return lst;
865 },
866
867 /** @id MochiKit.DOM.scrapeText */
868 scrapeText: function (node, /* optional */asArray) {
869 var rval = [];
870 (function (node) {
871 var cn = node.childNodes;
872 if (cn) {
873 for (var i = 0; i < cn.length; i++) {
874 arguments.callee.call(this, cn[i]);
875 }
876 }
877 var nodeValue = node.nodeValue;
878 if (typeof(nodeValue) == 'string') {
879 rval.push(nodeValue);
880 }
881 })(MochiKit.DOM.getElement(node));
882 if (asArray) {
883 return rval;
884 } else {
885 return rval.join("");
886 }
887 },
888
889 /** @id MochiKit.DOM.removeEmptyTextNodes */
890 removeEmptyTextNodes: function (element) {
891 element = MochiKit.DOM.getElement(element);
892 for (var i = 0; i < element.childNodes.length; i++) {
893 var node = element.childNodes[i];
894 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
895 node.parentNode.removeChild(node);
896 }
897 }
898 },
899
900 /** @id MochiKit.DOM.getFirstElementByTagAndClassName */
901 getFirstElementByTagAndClassName: function (tagName, className,
902 /* optional */parent) {
903 var self = MochiKit.DOM;
904 if (typeof(tagName) == 'undefined' || tagName === null) {
905 tagName = '*';
906 }
907 if (typeof(parent) == 'undefined' || parent === null) {
908 parent = self._document;
909 }
910 parent = self.getElement(parent);
911 if (parent == null) {
912 return null;
913 }
914 var children = (parent.getElementsByTagName(tagName)
915 || self._document.all);
916 if (children.length <= 0) {
917 return null;
918 } else if (typeof(className) == 'undefined' || className === null) {
919 return children[0];
920 }
921
922 for (var i = 0; i < children.length; i++) {
923 var child = children[i];
924 var cls = child.className;
925 if (typeof(cls) != "string") {
926 cls = child.getAttribute("class");
927 }
928 if (typeof(cls) == "string") {
929 var classNames = cls.split(' ');
930 for (var j = 0; j < classNames.length; j++) {
931 if (classNames[j] == className) {
932 return child;
933 }
934 }
935 }
936 }
937 return null;
938 },
939
940 /** @id MochiKit.DOM.getFirstParentByTagAndClassName */
941 getFirstParentByTagAndClassName: function (elem, tagName, className) {
942 var self = MochiKit.DOM;
943 elem = self.getElement(elem);
944 if (typeof(tagName) == 'undefined' || tagName === null) {
945 tagName = '*';
946 } else {
947 tagName = tagName.toUpperCase();
948 }
949 if (typeof(className) == 'undefined' || className === null) {
950 className = null;
951 }
952 if (elem) {
953 elem = elem.parentNode;
954 }
955 while (elem && elem.tagName) {
956 var curTagName = elem.tagName.toUpperCase();
957 if ((tagName === '*' || tagName == curTagName) &&
958 (className === null || self.hasElementClass(elem, className))) {
959 return elem;
960 }
961 elem = elem.parentNode;
962 }
963 return null;
964 },
965
966 __new__: function (win) {
967
968 var m = MochiKit.Base;
969 if (typeof(document) != "undefined") {
970 this._document = document;
971 var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
972 this._xhtml = (document.documentElement &&
973 document.createElementNS &&
974 document.documentElement.namespaceURI === kXULNSURI);
975 } else if (MochiKit.MockDOM) {
976 this._document = MochiKit.MockDOM.document;
977 }
978 this._window = win;
979
980 this.domConverters = new m.AdapterRegistry();
981
982 var __tmpElement = this._document.createElement("span");
983 var attributeArray;
984 if (__tmpElement && __tmpElement.attributes &&
985 __tmpElement.attributes.length > 0) {
986 // for braindead browsers (IE) that insert extra junk
987 var filter = m.filter;
988 attributeArray = function (node) {
989 /***
990
991 Return an array of attributes for a given node,
992 filtering out attributes that don't belong for
993 that are inserted by "Certain Browsers".
994
995 ***/
996 return filter(attributeArray.ignoreAttrFilter, node.attributes);
997 };
998 attributeArray.ignoreAttr = {};
999 var attrs = __tmpElement.attributes;
1000 var ignoreAttr = attributeArray.ignoreAttr;
1001 for (var i = 0; i < attrs.length; i++) {
1002 var a = attrs[i];
1003 ignoreAttr[a.name] = a.value;
1004 }
1005 attributeArray.ignoreAttrFilter = function (a) {
1006 return (attributeArray.ignoreAttr[a.name] != a.value);
1007 };
1008 attributeArray.compliant = false;
1009 attributeArray.renames = {
1010 "class": "className",
1011 "checked": "defaultChecked",
1012 "usemap": "useMap",
1013 "for": "htmlFor",
1014 "readonly": "readOnly",
1015 "colspan": "colSpan",
1016 "rowspan": "rowSpan",
1017 "bgcolor": "bgColor",
1018 "cellspacing": "cellSpacing",
1019 "cellpadding": "cellPadding"
1020 };
1021 } else {
1022 attributeArray = function (node) {
1023 return node.attributes;
1024 };
1025 attributeArray.compliant = true;
1026 attributeArray.ignoreAttr = {};
1027 attributeArray.renames = {};
1028 }
1029 attributeArray.__export__ = false;
1030 this.attributeArray = attributeArray;
1031
1032 // Backwards compatibility aliases
1033 /** @id MochiKit.DOM.computedStyle */
1034 m._deprecated(this, 'computedStyle', 'MochiKit.Style.getStyle', '1.4', true);
1035 /** @id MochiKit.DOM.elementDimensions */
1036 m._deprecated(this, 'elementDimensions', 'MochiKit.Style.getElementDimensions', '1.4');
1037 /** @id MochiKit.DOM.elementPosition */
1038 m._deprecated(this, 'elementPosition', 'MochiKit.Style.getElementPosition', '1.4');
1039 /** @id MochiKit.DOM.getViewportDimensions */
1040 m._deprecated(this, 'getViewportDimensions', 'MochiKit.Style.getViewportDimensions', '1.4');
1041 /** @id MochiKit.DOM.hideElement */
1042 m._deprecated(this, 'hideElement', 'MochiKit.Style.hideElement', '1.4');
1043 /** @id MochiKit.DOM.makeClipping */
1044 m._deprecated(this, 'makeClipping', 'MochiKit.Style.makeClipping', '1.4.1');
1045 /** @id MochiKit.DOM.makePositioned */
1046 m._deprecated(this, 'makePositioned', 'MochiKit.Style.makePositioned', '1.4.1');
1047 /** @id MochiKit.DOM.setElementDimensions */
1048 m._deprecated(this, 'setElementDimensions', 'MochiKit.Style.setElementDimensions', '1.4');
1049 /** @id MochiKit.DOM.setElementPosition */
1050 m._deprecated(this, 'setElementPosition', 'MochiKit.Style.setElementPosition', '1.4');
1051 /** @id MochiKit.DOM.setDisplayForElement */
1052 m._deprecated(this, 'setDisplayForElement', 'MochiKit.Style.setDisplayForElement', '1.4');
1053 /** @id MochiKit.DOM.setOpacity */
1054 m._deprecated(this, 'setOpacity', 'MochiKit.Style.setOpacity', '1.4');
1055 /** @id MochiKit.DOM.showElement */
1056 m._deprecated(this, 'showElement', 'MochiKit.Style.showElement', '1.4');
1057 /** @id MochiKit.DOM.undoClipping */
1058 m._deprecated(this, 'undoClipping', 'MochiKit.Style.undoClipping', '1.4.1');
1059 /** @id MochiKit.DOM.undoPositioned */
1060 m._deprecated(this, 'undoPositioned', 'MochiKit.Style.undoPositioned', '1.4.1');
1061 /** @id MochiKit.DOM.Coordinates */
1062 m._deprecated(this, 'Coordinates', 'MochiKit.Style.Coordinates', '1.4');
1063 /** @id MochiKit.DOM.Dimensions */
1064 m._deprecated(this, 'Dimensions', 'MochiKit.Style.Dimensions', '1.4');
1065
1066 // shorthand for createDOM syntax
1067 var createDOMFunc = this.createDOMFunc;
1068 /** @id MochiKit.DOM.A */
1069 this.A = createDOMFunc("a");
1070 /** @id MochiKit.DOM.ARTICLE */
1071 this.ARTICLE = createDOMFunc("article");
1072 /** @id MochiKit.DOM.ASIDE */
1073 this.ASIDE = createDOMFunc("aside");
1074 /** @id MochiKit.DOM.BR */
1075 this.BR = createDOMFunc("br");
1076 /** @id MochiKit.DOM.BUTTON */
1077 this.BUTTON = createDOMFunc("button");
1078 /** @id MochiKit.DOM.CANVAS */
1079 this.CANVAS = createDOMFunc("canvas");
1080 /** @id MochiKit.DOM.CAPTION */
1081 this.CAPTION = createDOMFunc("caption");
1082 /** @id MochiKit.DOM.DD */
1083 this.DD = createDOMFunc("dd");
1084 /** @id MochiKit.DOM.DIV */
1085 this.DIV = createDOMFunc("div");
1086 /** @id MochiKit.DOM.DL */
1087 this.DL = createDOMFunc("dl");
1088 /** @id MochiKit.DOM.DT */
1089 this.DT = createDOMFunc("dt");
1090 /** @id MochiKit.DOM.FIELDSET */
1091 this.FIELDSET = createDOMFunc("fieldset");
1092 /** @id MochiKit.DOM.FIGURE */
1093 this.FIGURE = createDOMFunc("figure");
1094 /** @id MochiKit.DOM.FIGCAPTION */
1095 this.FIGCAPTION = createDOMFunc("figcaption");
1096 /** @id MochiKit.DOM.FOOTER */
1097 this.FOOTER = createDOMFunc("footer");
1098 /** @id MochiKit.DOM.FORM */
1099 this.FORM = createDOMFunc("form");
1100 /** @id MochiKit.DOM.H1 */
1101 this.H1 = createDOMFunc("h1");
1102 /** @id MochiKit.DOM.H2 */
1103 this.H2 = createDOMFunc("h2");
1104 /** @id MochiKit.DOM.H3 */
1105 this.H3 = createDOMFunc("h3");
1106 /** @id MochiKit.DOM.H4 */
1107 this.H4 = createDOMFunc("h4");
1108 /** @id MochiKit.DOM.H5 */
1109 this.H5 = createDOMFunc("h5");
1110 /** @id MochiKit.DOM.H6 */
1111 this.H6 = createDOMFunc("h6");
1112 /** @id MochiKit.DOM.HEADER */
1113 this.HEADER = createDOMFunc("header");
1114 /** @id MochiKit.DOM.HGROUP */
1115 this.HGROUP = createDOMFunc("hgroup");
1116 /** @id MochiKit.DOM.HR */
1117 this.HR = createDOMFunc("hr");
1118 /** @id MochiKit.DOM.IFRAME */
1119 this.IFRAME = createDOMFunc("iframe");
1120 /** @id MochiKit.DOM.IMG */
1121 this.IMG = createDOMFunc("img");
1122 /** @id MochiKit.DOM.INPUT */
1123 this.INPUT = createDOMFunc("input");
1124 /** @id MochiKit.DOM.LABEL */
1125 this.LABEL = createDOMFunc("label");
1126 /** @id MochiKit.DOM.LEGEND */
1127 this.LEGEND = createDOMFunc("legend");
1128 /** @id MochiKit.DOM.LI */
1129 this.LI = createDOMFunc("li");
1130 /** @id MochiKit.DOM.LINK */
1131 this.LINK = createDOMFunc("link");
1132 /** @id MochiKit.DOM.MARK */
1133 this.MARK = createDOMFunc("mark");
1134 /** @id MochiKit.DOM.METER */
1135 this.METER = createDOMFunc("meter");
1136 /** @id MochiKit.DOM.NAV */
1137 this.NAV = createDOMFunc("nav");
1138 /** @id MochiKit.DOM.OL */
1139 this.OL = createDOMFunc("ol");
1140 /** @id MochiKit.DOM.OPTGROUP */
1141 this.OPTGROUP = createDOMFunc("optgroup");
1142 /** @id MochiKit.DOM.OPTION */
1143 this.OPTION = createDOMFunc("option");
1144 /** @id MochiKit.DOM.P */
1145 this.P = createDOMFunc("p");
1146 /** @id MochiKit.DOM.PRE */
1147 this.PRE = createDOMFunc("pre");
1148 /** @id MochiKit.DOM.PROGRESS */
1149 this.PROGRESS = createDOMFunc("progress");
1150 /** @id MochiKit.DOM.SCRIPT */
1151 this.SCRIPT = createDOMFunc("script");
1152 /** @id MochiKit.DOM.SECTION */
1153 this.SECTION = createDOMFunc("section");
1154 /** @id MochiKit.DOM.SELECT */
1155 this.SELECT = createDOMFunc("select");
1156 /** @id MochiKit.DOM.SPAN */
1157 this.SPAN = createDOMFunc("span");
1158 /** @id MochiKit.DOM.STRONG */
1159 this.STRONG = createDOMFunc("strong");
1160 /** @id MochiKit.DOM.STYLE */
1161 this.STYLE = createDOMFunc("style");
1162 /** @id MochiKit.DOM.TABLE */
1163 this.TABLE = createDOMFunc("table");
1164 /** @id MochiKit.DOM.TBODY */
1165 this.TBODY = createDOMFunc("tbody");
1166 /** @id MochiKit.DOM.TD */
1167 this.TD = createDOMFunc("td");
1168 /** @id MochiKit.DOM.TEXTAREA */
1169 this.TEXTAREA = createDOMFunc("textarea");
1170 /** @id MochiKit.DOM.TFOOT */
1171 this.TFOOT = createDOMFunc("tfoot");
1172 /** @id MochiKit.DOM.TH */
1173 this.TH = createDOMFunc("th");
1174 /** @id MochiKit.DOM.THEAD */
1175 this.THEAD = createDOMFunc("thead");
1176 /** @id MochiKit.DOM.TR */
1177 this.TR = createDOMFunc("tr");
1178 /** @id MochiKit.DOM.TT */
1179 this.TT = createDOMFunc("tt");
1180 /** @id MochiKit.DOM.UL */
1181 this.UL = createDOMFunc("ul");
1182 /** @id MochiKit.DOM.NBSP */
1183 this.NBSP = "\u00a0";
1184 /** @id MochiKit.DOM.$ */
1185 this.$ = this.getElement;
1186
1187 m.nameFunctions(this);
1188 }
1189});
1190
1191
1192MochiKit.DOM.__new__(((typeof(window) == "undefined") ? this : window));
1193
1194//
1195// XXX: Internet Explorer blows
1196//
1197if (MochiKit.__export__) {
1198 withWindow = MochiKit.DOM.withWindow;
1199 withDocument = MochiKit.DOM.withDocument;
1200}
1201
1202MochiKit.Base._exportSymbols(this, MochiKit.DOM);