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