/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml */ dojo.provide("dojo.dom"); dojo.require("dojo.lang.array"); dojo.dom.ELEMENT_NODE = 1; dojo.dom.ATTRIBUTE_NODE = 2; dojo.dom.TEXT_NODE = 3; dojo.dom.CDATA_SECTION_NODE = 4; dojo.dom.ENTITY_REFERENCE_NODE = 5; dojo.dom.ENTITY_NODE = 6; dojo.dom.PROCESSING_INSTRUCTION_NODE = 7; dojo.dom.COMMENT_NODE = 8; dojo.dom.DOCUMENT_NODE = 9; dojo.dom.DOCUMENT_TYPE_NODE = 10; dojo.dom.DOCUMENT_FRAGMENT_NODE = 11; dojo.dom.NOTATION_NODE = 12; dojo.dom.dojoml = "http://www.dojotoolkit.org/2004/dojoml"; /** * comprehensive list of XML namespaces **/ dojo.dom.xmlns = { svg : "http://www.w3.org/2000/svg", smil : "http://www.w3.org/2001/SMIL20/", mml : "http://www.w3.org/1998/Math/MathML", cml : "http://www.xml-cml.org", xlink : "http://www.w3.org/1999/xlink", xhtml : "http://www.w3.org/1999/xhtml", xul : "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", xbl : "http://www.mozilla.org/xbl", fo : "http://www.w3.org/1999/XSL/Format", xsl : "http://www.w3.org/1999/XSL/Transform", xslt : "http://www.w3.org/1999/XSL/Transform", xi : "http://www.w3.org/2001/XInclude", xforms : "http://www.w3.org/2002/01/xforms", saxon : "http://icl.com/saxon", xalan : "http://xml.apache.org/xslt", xsd : "http://www.w3.org/2001/XMLSchema", dt: "http://www.w3.org/2001/XMLSchema-datatypes", xsi : "http://www.w3.org/2001/XMLSchema-instance", rdf : "http://www.w3.org/1999/02/22-rdf-syntax-ns#", rdfs : "http://www.w3.org/2000/01/rdf-schema#", dc : "http://purl.org/dc/elements/1.1/", dcq: "http://purl.org/dc/qualifiers/1.0", "soap-env" : "http://schemas.xmlsoap.org/soap/envelope/", wsdl : "http://schemas.xmlsoap.org/wsdl/", AdobeExtensions : "http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" }; dojo.dom.isNode = function(wh){ if(typeof Element == "object") { try { return wh instanceof Element; } catch(E) {} } else { // best-guess return wh && !isNaN(wh.nodeType); } } dojo.dom.getTagName = function(node){ dojo.deprecated("dojo.dom.getTagName", "use node.tagName instead", "0.4"); var tagName = node.tagName; if(tagName.substr(0,5).toLowerCase()!="dojo:"){ if(tagName.substr(0,4).toLowerCase()=="dojo"){ // FIXME: this assuumes tag names are always lower case return "dojo:" + tagName.substring(4).toLowerCase(); } // allow lower-casing var djt = node.getAttribute("dojoType")||node.getAttribute("dojotype"); if(djt){ return "dojo:"+djt.toLowerCase(); } if((node.getAttributeNS)&&(node.getAttributeNS(this.dojoml,"type"))){ return "dojo:" + node.getAttributeNS(this.dojoml,"type").toLowerCase(); } try{ // FIXME: IE really really doesn't like this, so we squelch // errors for it djt = node.getAttribute("dojo:type"); }catch(e){ /* FIXME: log? */ } if(djt){ return "dojo:"+djt.toLowerCase(); } if((!dj_global["djConfig"])||(!djConfig["ignoreClassNames"])){ // FIXME: should we make this optionally enabled via djConfig? var classes = node.className||node.getAttribute("class"); // FIXME: following line, without check for existence of classes.indexOf // breaks firefox 1.5's svg widgets if((classes)&&(classes.indexOf)&&(classes.indexOf("dojo-") != -1)){ var aclasses = classes.split(" "); for(var x=0; x5)&&(aclasses[x].indexOf("dojo-")>=0)){ return "dojo:"+aclasses[x].substr(5).toLowerCase(); } } } } } return tagName.toLowerCase(); } dojo.dom.getUniqueId = function(){ do { var id = "dj_unique_" + (++arguments.callee._idIncrement); }while(document.getElementById(id)); return id; } dojo.dom.getUniqueId._idIncrement = 0; dojo.dom.firstElement = dojo.dom.getFirstChildElement = function(parentNode, tagName){ var node = parentNode.firstChild; while(node && node.nodeType != dojo.dom.ELEMENT_NODE){ node = node.nextSibling; } if(tagName && node && node.tagName && node.tagName.toLowerCase() != tagName.toLowerCase()) { node = dojo.dom.nextElement(node, tagName); } return node; } dojo.dom.lastElement = dojo.dom.getLastChildElement = function(parentNode, tagName){ var node = parentNode.lastChild; while(node && node.nodeType != dojo.dom.ELEMENT_NODE) { node = node.previousSibling; } if(tagName && node && node.tagName && node.tagName.toLowerCase() != tagName.toLowerCase()) { node = dojo.dom.prevElement(node, tagName); } return node; } dojo.dom.nextElement = dojo.dom.getNextSiblingElement = function(node, tagName){ if(!node) { return null; } do { node = node.nextSibling; } while(node && node.nodeType != dojo.dom.ELEMENT_NODE); if(node && tagName && tagName.toLowerCase() != node.tagName.toLowerCase()) { return dojo.dom.nextElement(node, tagName); } return node; } dojo.dom.prevElement = dojo.dom.getPreviousSiblingElement = function(node, tagName){ if(!node) { return null; } if(tagName) { tagName = tagName.toLowerCase(); } do { node = node.previousSibling; } while(node && node.nodeType != dojo.dom.ELEMENT_NODE); if(node && tagName && tagName.toLowerCase() != node.tagName.toLowerCase()) { return dojo.dom.prevElement(node, tagName); } return node; } // TODO: hmph /*this.forEachChildTag = function(node, unaryFunc) { var child = this.getFirstChildTag(node); while(child) { if(unaryFunc(child) == "break") { break; } child = this.getNextSiblingTag(child); } }*/ dojo.dom.moveChildren = function(srcNode, destNode, trim){ var count = 0; if(trim) { while(srcNode.hasChildNodes() && srcNode.firstChild.nodeType == dojo.dom.TEXT_NODE) { srcNode.removeChild(srcNode.firstChild); } while(srcNode.hasChildNodes() && srcNode.lastChild.nodeType == dojo.dom.TEXT_NODE) { srcNode.removeChild(srcNode.lastChild); } } while(srcNode.hasChildNodes()){ destNode.appendChild(srcNode.firstChild); count++; } return count; } dojo.dom.copyChildren = function(srcNode, destNode, trim){ var clonedNode = srcNode.cloneNode(true); return this.moveChildren(clonedNode, destNode, trim); } dojo.dom.removeChildren = function(node){ var count = node.childNodes.length; while(node.hasChildNodes()){ node.removeChild(node.firstChild); } return count; } dojo.dom.replaceChildren = function(node, newChild){ // FIXME: what if newChild is an array-like object? dojo.dom.removeChildren(node); node.appendChild(newChild); } dojo.dom.removeNode = function(node){ if(node && node.parentNode){ // return a ref to the removed child return node.parentNode.removeChild(node); } } dojo.dom.getAncestors = function(node, filterFunction, returnFirstHit) { var ancestors = []; var isFunction = dojo.lang.isFunction(filterFunction); while(node) { if (!isFunction || filterFunction(node)) { ancestors.push(node); } if (returnFirstHit && ancestors.length > 0) { return ancestors[0]; } node = node.parentNode; } if (returnFirstHit) { return null; } return ancestors; } dojo.dom.getAncestorsByTag = function(node, tag, returnFirstHit) { tag = tag.toLowerCase(); return dojo.dom.getAncestors(node, function(el){ return ((el.tagName)&&(el.tagName.toLowerCase() == tag)); }, returnFirstHit); } dojo.dom.getFirstAncestorByTag = function(node, tag) { return dojo.dom.getAncestorsByTag(node, tag, true); } dojo.dom.isDescendantOf = function(node, ancestor, guaranteeDescendant){ // guaranteeDescendant allows us to be a "true" isDescendantOf function if(guaranteeDescendant && node) { node = node.parentNode; } while(node) { if(node == ancestor){ return true; } node = node.parentNode; } return false; } dojo.dom.innerXML = function(node){ if(node.innerXML){ return node.innerXML; }else if (node.xml){ return node.xml; }else if(typeof XMLSerializer != "undefined"){ return (new XMLSerializer()).serializeToString(node); } } dojo.dom.createDocument = function(){ var doc = null; if(!dj_undef("ActiveXObject")){ var prefixes = [ "MSXML2", "Microsoft", "MSXML", "MSXML3" ]; for(var i = 0; i * isTag(myFooNode, "foo"); // returns "foo" * isTag(myFooNode, "bar"); // returns "" * isTag(myFooNode, "FOO"); // returns "" * isTag(myFooNode, "hey", "foo", "bar"); // returns "foo" **/ dojo.dom.isTag = function(node /* ... */) { if(node && node.tagName) { var arr = dojo.lang.toArray(arguments, 1); return arr[ dojo.lang.find(node.tagName, arr) ] || ""; } return ""; }