5 See <http://mochikit.com/> for documentation, downloads, license, etc.
7 (c) 2005 Bob Ippolito. All rights Reserved.
11 if (typeof(dojo) != 'undefined') {
12 dojo.provide("MochiKit.DOM");
13 dojo.require("MochiKit.Base");
15 if (typeof(JSAN) != 'undefined') {
16 JSAN.use("MochiKit.Base", []);
20 if (typeof(MochiKit.Base) == 'undefined') {
24 throw "MochiKit.DOM depends on MochiKit.Base!";
27 if (typeof(MochiKit.DOM) == 'undefined') {
31 MochiKit.DOM.NAME = "MochiKit.DOM";
32 MochiKit.DOM.VERSION = "1.4";
33 MochiKit.DOM.__repr__ = function () {
34 return "[" + this.NAME + " " + this.VERSION + "]";
36 MochiKit.DOM.toString = function () {
37 return this.__repr__();
40 MochiKit.DOM.EXPORT = [
41 "removeEmptyTextNodes",
47 "registerDOMConverter",
53 "removeNodeAttribute",
55 "updateNodeAttributes",
57 "insertSiblingNodesAfter",
58 "insertSiblingNodesBefore",
98 "getElementsByTagAndClassName",
103 "toggleElementClass",
105 "removeElementClass",
113 "getFirstParentByTagAndClassName",
118 "getFirstElementByTagAndClassName"
121 MochiKit.DOM.EXPORT_OK = [
125 MochiKit.DOM.DEPRECATED = [
126 ['computedStyle', 'MochiKit.Style.getStyle', '1.4'],
127 /** @id MochiKit.DOM.elementDimensions */
128 ['elementDimensions', 'MochiKit.Style.getElementDimensions', '1.4'],
129 /** @id MochiKit.DOM.elementPosition */
130 ['elementPosition', 'MochiKit.Style.getElementPosition', '1.4'],
131 ['hideElement', 'MochiKit.Style.hideElement', '1.4'],
132 /** @id MochiKit.DOM.setElementDimensions */
133 ['setElementDimensions', 'MochiKit.Style.setElementDimensions', '1.4'],
134 /** @id MochiKit.DOM.setElementPosition */
135 ['setElementPosition', 'MochiKit.Style.setElementPosition', '1.4'],
136 ['setDisplayForElement', 'MochiKit.Style.setDisplayForElement', '1.4'],
137 /** @id MochiKit.DOM.setOpacity */
138 ['setOpacity', 'MochiKit.Style.setOpacity', '1.4'],
139 ['showElement', 'MochiKit.Style.showElement', '1.4'],
140 /** @id MochiKit.DOM.Coordinates */
141 ['Coordinates', 'MochiKit.Style.Coordinates', '1.4'], // FIXME: broken
142 /** @id MochiKit.DOM.Dimensions */
143 ['Dimensions', 'MochiKit.Style.Dimensions', '1.4'] // FIXME: broken
146 /** @id MochiKit.DOM.getViewportDimensions */
147 MochiKit.DOM.getViewportDimensions = new Function('' +
148 'if (!MochiKit["Style"]) {' +
149 ' throw new Error("This function has been deprecated and depends on MochiKit.Style.");' +
151 'return MochiKit.Style.getViewportDimensions.apply(this, arguments);');
153 MochiKit.Base.update(MochiKit.DOM, {
155 /** @id MochiKit.DOM.currentWindow */
156 currentWindow: function () {
157 return MochiKit.DOM._window;
160 /** @id MochiKit.DOM.currentDocument */
161 currentDocument: function () {
162 return MochiKit.DOM._document;
165 /** @id MochiKit.DOM.withWindow */
166 withWindow: function (win, func) {
167 var self = MochiKit.DOM;
168 var oldDoc = self._document;
169 var oldWin = self._window;
173 self._document = win.document;
176 self._window = oldWin;
177 self._document = oldDoc;
180 self._window = oldWin;
181 self._document = oldDoc;
185 /** @id MochiKit.DOM.formContents */
186 formContents: function (elem/* = document.body */) {
189 var m = MochiKit.Base;
190 var self = MochiKit.DOM;
191 if (typeof(elem) == "undefined" || elem === null) {
192 elem = self._document.body;
194 elem = self.getElement(elem);
196 m.nodeWalk(elem, function (elem) {
197 var name = elem.name;
198 if (m.isNotEmpty(name)) {
199 var tagName = elem.tagName.toUpperCase();
200 if (tagName === "INPUT"
201 && (elem.type == "radio" || elem.type == "checkbox")
206 if (tagName === "SELECT") {
207 if (elem.type == "select-one") {
208 if (elem.selectedIndex >= 0) {
209 var opt = elem.options[elem.selectedIndex];
212 var h = opt.outerHTML;
213 // internet explorer sure does suck.
214 if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
227 var opts = elem.options;
233 for (var i = 0; i < opts.length; i++) {
240 var h = opt.outerHTML;
241 // internet explorer sure does suck.
242 if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
252 if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
255 return elem.childNodes;
258 values.push(elem.value || '');
261 return elem.childNodes;
263 return [names, values];
266 /** @id MochiKit.DOM.withDocument */
267 withDocument: function (doc, func) {
268 var self = MochiKit.DOM;
269 var oldDoc = self._document;
272 self._document = doc;
275 self._document = oldDoc;
278 self._document = oldDoc;
282 /** @id MochiKit.DOM.registerDOMConverter */
283 registerDOMConverter: function (name, check, wrap, /* optional */override) {
284 MochiKit.DOM.domConverters.register(name, check, wrap, override);
287 /** @id MochiKit.DOM.coerceToDOM */
288 coerceToDOM: function (node, ctx) {
289 var m = MochiKit.Base;
290 var im = MochiKit.Iter;
291 var self = MochiKit.DOM;
294 var repeat = im.repeat;
297 var domConverters = self.domConverters;
298 var coerceToDOM = arguments.callee;
299 var NotFound = m.NotFound;
301 if (typeof(node) == 'undefined' || node === null) {
304 // this is a safari childNodes object, avoiding crashes w/ attr
306 if (typeof(node) == "function" &&
307 typeof(node.length) == "number" &&
308 !(node instanceof Function)) {
309 node = im.list(node);
311 if (typeof(node.nodeType) != 'undefined' && node.nodeType > 0) {
314 if (typeof(node) == 'number' || typeof(node) == 'boolean') {
315 node = node.toString();
318 if (typeof(node) == 'string') {
319 return self._document.createTextNode(node);
321 if (typeof(node.__dom__) == 'function') {
322 node = node.__dom__(ctx);
325 if (typeof(node.dom) == 'function') {
326 node = node.dom(ctx);
329 if (typeof(node) == 'function') {
330 node = node.apply(ctx, [ctx]);
336 var iterNodes = null;
338 iterNodes = iter(node);
343 return map(coerceToDOM, iterNodes, repeat(ctx));
349 node = domConverters.match(node, ctx);
358 return self._document.createTextNode(node.toString());
360 // mozilla warnings aren't too bright
364 /** @id MochiKit.DOM.isChildNode */
365 isChildNode: function (node, maybeparent) {
366 var self = MochiKit.DOM;
367 if (typeof(node) == "string") {
368 node = self.getElement(node);
370 if (typeof(maybeparent) == "string") {
371 maybeparent = self.getElement(maybeparent);
373 if (node === maybeparent) {
376 while (node && node.tagName.toUpperCase() != "BODY") {
377 node = node.parentNode;
378 if (node === maybeparent) {
385 /** @id MochiKit.DOM.setNodeAttribute */
386 setNodeAttribute: function (node, attr, value) {
390 return MochiKit.DOM.updateNodeAttributes(node, o);
397 /** @id MochiKit.DOM.getNodeAttribute */
398 getNodeAttribute: function (node, attr) {
399 var self = MochiKit.DOM;
400 var rename = self.attributeArray.renames[attr];
401 node = self.getElement(node);
406 return node.getAttribute(attr);
413 /** @id MochiKit.DOM.removeNodeAttribute */
414 removeNodeAttribute: function (node, attr) {
415 var self = MochiKit.DOM;
416 var rename = self.attributeArray.renames[attr];
417 node = self.getElement(node);
422 return node.removeAttribute(attr);
429 /** @id MochiKit.DOM.updateNodeAttributes */
430 updateNodeAttributes: function (node, attrs) {
432 var self = MochiKit.DOM;
433 if (typeof(node) == 'string') {
434 elem = self.getElement(node);
437 var updatetree = MochiKit.Base.updatetree;
438 if (self.attributeArray.compliant) {
440 for (var k in attrs) {
442 if (typeof(v) == 'object' && typeof(elem[k]) == 'object') {
443 if (k == "style" && MochiKit.Style) {
444 MochiKit.Style.setStyle(elem, v);
446 updatetree(elem[k], v);
448 } else if (k.substring(0, 2) == "on") {
449 if (typeof(v) == "string") {
454 elem.setAttribute(k, v);
458 // IE is insane in the membrane
459 var renames = self.attributeArray.renames;
462 var renamed = renames[k];
463 if (k == "style" && typeof(v) == "string") {
464 elem.style.cssText = v;
465 } else if (typeof(renamed) == "string") {
467 } else if (typeof(elem[k]) == 'object'
468 && typeof(v) == 'object') {
469 if (k == "style" && MochiKit.Style) {
470 MochiKit.Style.setStyle(elem, v);
472 updatetree(elem[k], v);
474 } else if (k.substring(0, 2) == "on") {
475 if (typeof(v) == "string") {
480 elem.setAttribute(k, v);
488 /** @id MochiKit.DOM.appendChildNodes */
489 appendChildNodes: function (node/*, nodes...*/) {
491 var self = MochiKit.DOM;
492 if (typeof(node) == 'string') {
493 elem = self.getElement(node);
497 MochiKit.Base.extend(null, arguments, 1),
501 var concat = MochiKit.Base.concat;
502 while (nodeStack.length) {
503 var n = nodeStack.shift();
504 if (typeof(n) == 'undefined' || n === null) {
506 } else if (typeof(n.nodeType) == 'number') {
509 nodeStack = concat(n, nodeStack);
516 /** @id MochiKit.DOM.insertSiblingNodesBefore */
517 insertSiblingNodesBefore: function (node/*, nodes...*/) {
519 var self = MochiKit.DOM;
520 if (typeof(node) == 'string') {
521 elem = self.getElement(node);
525 MochiKit.Base.extend(null, arguments, 1),
529 var parentnode = elem.parentNode;
530 var concat = MochiKit.Base.concat;
531 while (nodeStack.length) {
532 var n = nodeStack.shift();
533 if (typeof(n) == 'undefined' || n === null) {
535 } else if (typeof(n.nodeType) == 'number') {
536 parentnode.insertBefore(n, elem);
538 nodeStack = concat(n, nodeStack);
544 /** @id MochiKit.DOM.insertSiblingNodesAfter */
545 insertSiblingNodesAfter: function (node/*, nodes...*/) {
547 var self = MochiKit.DOM;
549 if (typeof(node) == 'string') {
550 elem = self.getElement(node);
554 MochiKit.Base.extend(null, arguments, 1),
559 if (elem.nextSibling) {
560 return self.insertSiblingNodesBefore(elem.nextSibling, nodeStack);
563 return self.appendChildNodes(elem.parentNode, nodeStack);
567 /** @id MochiKit.DOM.replaceChildNodes */
568 replaceChildNodes: function (node/*, nodes...*/) {
570 var self = MochiKit.DOM;
571 if (typeof(node) == 'string') {
572 elem = self.getElement(node);
576 while ((child = elem.firstChild)) {
577 elem.removeChild(child);
579 if (arguments.length < 2) {
582 return self.appendChildNodes.apply(this, arguments);
586 /** @id MochiKit.DOM.createDOM */
587 createDOM: function (name, attrs/*, nodes... */) {
589 var self = MochiKit.DOM;
590 var m = MochiKit.Base;
591 if (typeof(attrs) == "string" || typeof(attrs) == "number") {
592 var args = m.extend([name, null], arguments, 1);
593 return arguments.callee.apply(this, args);
595 if (typeof(name) == 'string') {
596 // Internet Explorer is dumb
597 var xhtml = self._xhtml;
598 if (attrs && !self.attributeArray.compliant) {
599 // http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp
601 if ('name' in attrs) {
602 contents += ' name="' + self.escapeHTML(attrs.name) + '"';
604 if (name == 'input' && 'type' in attrs) {
605 contents += ' type="' + self.escapeHTML(attrs.type) + '"';
608 name = "<" + name + contents + ">";
612 var d = self._document;
613 if (xhtml && d === document) {
614 elem = d.createElementNS("http://www.w3.org/1999/xhtml", name);
616 elem = d.createElement(name);
622 self.updateNodeAttributes(elem, attrs);
624 if (arguments.length <= 2) {
627 var args = m.extend([elem], arguments, 2);
628 return self.appendChildNodes.apply(this, args);
632 /** @id MochiKit.DOM.createDOMFunc */
633 createDOMFunc: function (/* tag, attrs, *nodes */) {
634 var m = MochiKit.Base;
635 return m.partial.apply(
637 m.extend([MochiKit.DOM.createDOM], arguments)
641 /** @id MochiKit.DOM.removeElement */
642 removeElement: function (elem) {
643 var e = MochiKit.DOM.getElement(elem);
644 e.parentNode.removeChild(e);
648 /** @id MochiKit.DOM.swapDOM */
649 swapDOM: function (dest, src) {
650 var self = MochiKit.DOM;
651 dest = self.getElement(dest);
652 var parent = dest.parentNode;
654 src = self.getElement(src);
655 parent.replaceChild(src, dest);
657 parent.removeChild(dest);
662 /** @id MochiKit.DOM.getElement */
663 getElement: function (id) {
664 var self = MochiKit.DOM;
665 if (arguments.length == 1) {
666 return ((typeof(id) == "string") ?
667 self._document.getElementById(id) : id);
669 return MochiKit.Base.map(self.getElement, arguments);
673 /** @id MochiKit.DOM.getElementsByTagAndClassName */
674 getElementsByTagAndClassName: function (tagName, className,
675 /* optional */parent) {
676 var self = MochiKit.DOM;
677 if (typeof(tagName) == 'undefined' || tagName === null) {
680 if (typeof(parent) == 'undefined' || parent === null) {
681 parent = self._document;
683 parent = self.getElement(parent);
684 var children = (parent.getElementsByTagName(tagName)
685 || self._document.all);
686 if (typeof(className) == 'undefined' || className === null) {
687 return MochiKit.Base.extend(null, children);
691 for (var i = 0; i < children.length; i++) {
692 var child = children[i];
693 var cls = child.className;
697 var classNames = cls.split(' ');
698 for (var j = 0; j < classNames.length; j++) {
699 if (classNames[j] == className) {
700 elements.push(child);
709 _newCallStack: function (path, once) {
710 var rval = function () {
711 var callStack = arguments.callee.callStack;
712 for (var i = 0; i < callStack.length; i++) {
713 if (callStack[i].apply(this, arguments) === false) {
729 /** @id MochiKit.DOM.addToCallStack */
730 addToCallStack: function (target, path, func, once) {
731 var self = MochiKit.DOM;
732 var existing = target[path];
733 var regfunc = existing;
734 if (!(typeof(existing) == 'function'
735 && typeof(existing.callStack) == "object"
736 && existing.callStack !== null)) {
737 regfunc = self._newCallStack(path, once);
738 if (typeof(existing) == 'function') {
739 regfunc.callStack.push(existing);
741 target[path] = regfunc;
743 regfunc.callStack.push(func);
746 /** @id MochiKit.DOM.addLoadEvent */
747 addLoadEvent: function (func) {
748 var self = MochiKit.DOM;
749 self.addToCallStack(self._window, "onload", func, true);
753 /** @id MochiKit.DOM.focusOnLoad */
754 focusOnLoad: function (element) {
755 var self = MochiKit.DOM;
756 self.addLoadEvent(function () {
757 element = self.getElement(element);
764 /** @id MochiKit.DOM.setElementClass */
765 setElementClass: function (element, className) {
766 var self = MochiKit.DOM;
767 var obj = self.getElement(element);
768 if (self.attributeArray.compliant) {
769 obj.setAttribute("class", className);
771 obj.setAttribute("className", className);
775 /** @id MochiKit.DOM.toggleElementClass */
776 toggleElementClass: function (className/*, element... */) {
777 var self = MochiKit.DOM;
778 for (var i = 1; i < arguments.length; i++) {
779 var obj = self.getElement(arguments[i]);
780 if (!self.addElementClass(obj, className)) {
781 self.removeElementClass(obj, className);
786 /** @id MochiKit.DOM.addElementClass */
787 addElementClass: function (element, className) {
788 var self = MochiKit.DOM;
789 var obj = self.getElement(element);
790 var cls = obj.className;
791 // trivial case, no className yet
792 if (cls == undefined || cls.length === 0) {
793 self.setElementClass(obj, className);
796 // the other trivial case, already set as the only class
797 if (cls == className) {
800 var classes = cls.split(" ");
801 for (var i = 0; i < classes.length; i++) {
803 if (classes[i] == className) {
808 self.setElementClass(obj, cls + " " + className);
812 /** @id MochiKit.DOM.removeElementClass */
813 removeElementClass: function (element, className) {
814 var self = MochiKit.DOM;
815 var obj = self.getElement(element);
816 var cls = obj.className;
817 // trivial case, no className yet
818 if (cls == undefined || cls.length === 0) {
821 // other trivial case, set only to className
822 if (cls == className) {
823 self.setElementClass(obj, "");
826 var classes = cls.split(" ");
827 for (var i = 0; i < classes.length; i++) {
829 if (classes[i] == className) {
830 // only check sane case where the class is used once
831 classes.splice(i, 1);
832 self.setElementClass(obj, classes.join(" "));
840 /** @id MochiKit.DOM.swapElementClass */
841 swapElementClass: function (element, fromClass, toClass) {
842 var obj = MochiKit.DOM.getElement(element);
843 var res = MochiKit.DOM.removeElementClass(obj, fromClass);
845 MochiKit.DOM.addElementClass(obj, toClass);
850 /** @id MochiKit.DOM.hasElementClass */
851 hasElementClass: function (element, className/*...*/) {
852 var obj = MochiKit.DOM.getElement(element);
853 var cls = obj.className;
857 var classes = cls.split(" ");
858 for (var i = 1; i < arguments.length; i++) {
860 for (var j = 0; j < classes.length; j++) {
861 if (classes[j] == arguments[i]) {
873 /** @id MochiKit.DOM.escapeHTML */
874 escapeHTML: function (s) {
875 return s.replace(/&/g, "&"
876 ).replace(/"/g, """
877 ).replace(/</g, "<"
878 ).replace(/>/g, ">");
881 /** @id MochiKit.DOM.toHTML */
882 toHTML: function (dom) {
883 return MochiKit.DOM.emitHTML(dom).join("");
886 /** @id MochiKit.DOM.emitHTML */
887 emitHTML: function (dom, /* optional */lst) {
888 if (typeof(lst) == 'undefined' || lst === null) {
891 // queue is the call stack, we're doing this non-recursively
893 var self = MochiKit.DOM;
894 var escapeHTML = self.escapeHTML;
895 var attributeArray = self.attributeArray;
896 while (queue.length) {
898 if (typeof(dom) == 'string') {
900 } else if (dom.nodeType == 1) {
901 // we're not using higher order stuff here
902 // because safari has heisenbugs.. argh.
904 // I think it might have something to do with
905 // garbage collection and function calls.
906 lst.push('<' + dom.tagName.toLowerCase());
908 var domAttr = attributeArray(dom);
909 for (var i = 0; i < domAttr.length; i++) {
920 for (i = 0; i < attributes.length; i++) {
921 var attrs = attributes[i];
922 for (var j = 0; j < attrs.length; j++) {
926 if (dom.hasChildNodes()) {
928 // queue is the FILO call stack, so we put the close tag
930 queue.push("</" + dom.tagName.toLowerCase() + ">");
931 var cnodes = dom.childNodes;
932 for (i = cnodes.length - 1; i >= 0; i--) {
933 queue.push(cnodes[i]);
938 } else if (dom.nodeType == 3) {
939 lst.push(escapeHTML(dom.nodeValue));
945 /** @id MochiKit.DOM.scrapeText */
946 scrapeText: function (node, /* optional */asArray) {
949 var cn = node.childNodes;
951 for (var i = 0; i < cn.length; i++) {
952 arguments.callee.call(this, cn[i]);
955 var nodeValue = node.nodeValue;
956 if (typeof(nodeValue) == 'string') {
957 rval.push(nodeValue);
959 })(MochiKit.DOM.getElement(node));
963 return rval.join("");
967 /** @id MochiKit.DOM.removeEmptyTextNodes */
968 removeEmptyTextNodes: function (element) {
969 element = MochiKit.DOM.getElement(element);
970 for (var i = 0; i < element.childNodes.length; i++) {
971 var node = element.childNodes[i];
972 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
973 node.parentNode.removeChild(node);
978 /** @id MochiKit.DOM.makeClipping */
979 makeClipping: function (element) {
980 element = MochiKit.DOM.getElement(element);
981 var oldOverflow = element.style.overflow;
982 if ((MochiKit.Style.getStyle(element, 'overflow') || 'visible') != 'hidden') {
983 element.style.overflow = 'hidden';
988 /** @id MochiKit.DOM.undoClipping */
989 undoClipping: function (element, overflow) {
990 element = MochiKit.DOM.getElement(element);
994 element.style.overflow = overflow;
997 /** @id MochiKit.DOM.makePositioned */
998 makePositioned: function (element) {
999 element = MochiKit.DOM.getElement(element);
1000 var pos = MochiKit.Style.getStyle(element, 'position');
1001 if (pos == 'static' || !pos) {
1002 element.style.position = 'relative';
1003 // Opera returns the offset relative to the positioning context,
1004 // when an element is position relative but top and left have
1006 if (/Opera/.test(navigator.userAgent)) {
1007 element.style.top = 0;
1008 element.style.left = 0;
1013 /** @id MochiKit.DOM.undoPositioned */
1014 undoPositioned: function (element) {
1015 element = MochiKit.DOM.getElement(element);
1016 if (element.style.position == 'relative') {
1017 element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
1021 /** @id MochiKit.DOM.getFirstElementByTagAndClassName */
1022 getFirstElementByTagAndClassName: function (tagName, className,
1023 /* optional */parent) {
1024 var self = MochiKit.DOM;
1025 if (typeof(tagName) == 'undefined' || tagName === null) {
1028 if (typeof(parent) == 'undefined' || parent === null) {
1029 parent = self._document;
1031 parent = self.getElement(parent);
1032 var children = (parent.getElementsByTagName(tagName)
1033 || self._document.all);
1034 if (typeof(className) == 'undefined' || className === null) {
1038 for (var i = 0; i < children.length; i++) {
1039 var child = children[i];
1040 var classNames = child.className.split(' ');
1041 for (var j = 0; j < classNames.length; j++) {
1042 if (classNames[j] == className) {
1049 /** @id MochiKit.DOM.getFirstParentByTagAndClassName */
1050 getFirstParentByTagAndClassName: function (elem, tagName, className) {
1051 var self = MochiKit.DOM;
1052 elem = self.getElement(elem);
1053 if (typeof(tagName) == 'undefined' || tagName === null) {
1056 tagName = tagName.toUpperCase();
1058 if (typeof(className) == 'undefined' || className === null) {
1063 var curTagName = '';
1064 while (elem && elem.tagName) {
1065 elem = elem.parentNode;
1066 if (tagName == '*' && className === null) {
1069 classList = elem.className.split(' ');
1070 curTagName = elem.tagName.toUpperCase();
1071 if (className === null && tagName == curTagName) {
1073 } else if (className !== null) {
1074 for (var i = 0; i < classList.length; i++) {
1075 if (tagName == '*' && classList[i] == className) {
1077 } else if (tagName == curTagName && classList[i] == className) {
1086 /** @id MochiKit.DOM.isParent */
1087 isParent: function (child, element) {
1088 if (!child.parentNode || child == element) {
1092 if (child.parentNode == element) {
1096 return MochiKit.DOM.isParent(child.parentNode, element);
1099 __new__: function (win) {
1101 var m = MochiKit.Base;
1102 if (typeof(document) != "undefined") {
1103 this._document = document;
1104 var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
1105 this._xhtml = (document.documentElement &&
1106 document.createElementNS &&
1107 document.documentElement.namespaceURI === kXULNSURI);
1108 } else if (MochiKit.MockDOM) {
1109 this._document = MochiKit.MockDOM.document;
1113 this.domConverters = new m.AdapterRegistry();
1115 var __tmpElement = this._document.createElement("span");
1117 if (__tmpElement && __tmpElement.attributes &&
1118 __tmpElement.attributes.length > 0) {
1119 // for braindead browsers (IE) that insert extra junk
1120 var filter = m.filter;
1121 attributeArray = function (node) {
1122 return filter(attributeArray.ignoreAttrFilter, node.attributes);
1124 attributeArray.ignoreAttr = {};
1125 var attrs = __tmpElement.attributes;
1126 var ignoreAttr = attributeArray.ignoreAttr;
1127 for (var i = 0; i < attrs.length; i++) {
1129 ignoreAttr[a.name] = a.value;
1131 attributeArray.ignoreAttrFilter = function (a) {
1132 return (attributeArray.ignoreAttr[a.name] != a.value);
1134 attributeArray.compliant = false;
1135 attributeArray.renames = {
1136 "class": "className",
1137 "checked": "defaultChecked",
1140 "readonly": "readOnly",
1141 "colspan": "colSpan",
1142 "bgcolor": "bgColor"
1145 attributeArray = function (node) {
1148 Return an array of attributes for a given node,
1149 filtering out attributes that don't belong for
1150 that are inserted by "Certain Browsers".
1153 return node.attributes;
1155 attributeArray.compliant = true;
1156 attributeArray.renames = {};
1158 this.attributeArray = attributeArray;
1160 // FIXME: this really belongs in Base, and could probably be cleaner
1161 var _deprecated = function(fromModule, arr) {
1162 var modules = arr[1].split('.');
1166 str += 'if (!MochiKit.' + modules[1] + ') { throw new Error("';
1167 str += 'This function has been deprecated and depends on MochiKit.';
1168 str += modules[1] + '.");}';
1169 str += 'return MochiKit.' + modules[1] + '.' + arr[0];
1170 str += '.apply(this, arguments);';
1172 obj[modules[2]] = new Function(str);
1173 MochiKit.Base.update(MochiKit[fromModule], obj);
1175 for (var i; i < MochiKit.DOM.DEPRECATED.length; i++) {
1176 _deprecated('DOM', MochiKit.DOM.DEPRECATED[i]);
1179 // shorthand for createDOM syntax
1180 var createDOMFunc = this.createDOMFunc;
1181 /** @id MochiKit.DOM.UL */
1182 this.UL = createDOMFunc("ul");
1183 /** @id MochiKit.DOM.OL */
1184 this.OL = createDOMFunc("ol");
1185 /** @id MochiKit.DOM.LI */
1186 this.LI = createDOMFunc("li");
1187 /** @id MochiKit.DOM.TD */
1188 this.TD = createDOMFunc("td");
1189 /** @id MochiKit.DOM.TR */
1190 this.TR = createDOMFunc("tr");
1191 /** @id MochiKit.DOM.TBODY */
1192 this.TBODY = createDOMFunc("tbody");
1193 /** @id MochiKit.DOM.THEAD */
1194 this.THEAD = createDOMFunc("thead");
1195 /** @id MochiKit.DOM.TFOOT */
1196 this.TFOOT = createDOMFunc("tfoot");
1197 /** @id MochiKit.DOM.TABLE */
1198 this.TABLE = createDOMFunc("table");
1199 /** @id MochiKit.DOM.TH */
1200 this.TH = createDOMFunc("th");
1201 /** @id MochiKit.DOM.INPUT */
1202 this.INPUT = createDOMFunc("input");
1203 /** @id MochiKit.DOM.SPAN */
1204 this.SPAN = createDOMFunc("span");
1205 /** @id MochiKit.DOM.A */
1206 this.A = createDOMFunc("a");
1207 /** @id MochiKit.DOM.DIV */
1208 this.DIV = createDOMFunc("div");
1209 /** @id MochiKit.DOM.IMG */
1210 this.IMG = createDOMFunc("img");
1211 /** @id MochiKit.DOM.BUTTON */
1212 this.BUTTON = createDOMFunc("button");
1213 /** @id MochiKit.DOM.TT */
1214 this.TT = createDOMFunc("tt");
1215 /** @id MochiKit.DOM.PRE */
1216 this.PRE = createDOMFunc("pre");
1217 /** @id MochiKit.DOM.H1 */
1218 this.H1 = createDOMFunc("h1");
1219 /** @id MochiKit.DOM.H2 */
1220 this.H2 = createDOMFunc("h2");
1221 /** @id MochiKit.DOM.H3 */
1222 this.H3 = createDOMFunc("h3");
1223 /** @id MochiKit.DOM.BR */
1224 this.BR = createDOMFunc("br");
1225 /** @id MochiKit.DOM.HR */
1226 this.HR = createDOMFunc("hr");
1227 /** @id MochiKit.DOM.LABEL */
1228 this.LABEL = createDOMFunc("label");
1229 /** @id MochiKit.DOM.TEXTAREA */
1230 this.TEXTAREA = createDOMFunc("textarea");
1231 /** @id MochiKit.DOM.FORM */
1232 this.FORM = createDOMFunc("form");
1233 /** @id MochiKit.DOM.P */
1234 this.P = createDOMFunc("p");
1235 /** @id MochiKit.DOM.SELECT */
1236 this.SELECT = createDOMFunc("select");
1237 /** @id MochiKit.DOM.OPTION */
1238 this.OPTION = createDOMFunc("option");
1239 /** @id MochiKit.DOM.OPTGROUP */
1240 this.OPTGROUP = createDOMFunc("optgroup");
1241 /** @id MochiKit.DOM.LEGEND */
1242 this.LEGEND = createDOMFunc("legend");
1243 /** @id MochiKit.DOM.FIELDSET */
1244 this.FIELDSET = createDOMFunc("fieldset");
1245 /** @id MochiKit.DOM.STRONG */
1246 this.STRONG = createDOMFunc("strong");
1247 /** @id MochiKit.DOM.CANVAS */
1248 this.CANVAS = createDOMFunc("canvas");
1250 /** @id MochiKit.DOM.$ */
1251 this.$ = this.getElement;
1253 this.EXPORT_TAGS = {
1254 ":common": this.EXPORT,
1255 ":all": m.concat(this.EXPORT, this.EXPORT_OK)
1258 m.nameFunctions(this);
1264 MochiKit.DOM.__new__(((typeof(window) == "undefined") ? this : window));
1267 // XXX: Internet Explorer blows
1269 if (MochiKit.__export__) {
1270 withWindow = MochiKit.DOM.withWindow;
1271 withDocument = MochiKit.DOM.withDocument;
1274 MochiKit.Base._exportSymbols(this, MochiKit.DOM);