/* DOM lib */ /* These should be consts, but IE doesn't like that */ var DOM_ELEMENT_NODE = 1; var DOM_ATTRIBUTE_NODE = 2; var DOM_TEXT_NODE = 3; var DOM_CDATA_SECTION_NODE = 4; var DOM_ENTITY_REFERENCE_NODE = 5; var DOM_ENTITY_NODE = 6; var DOM_PROCESSING_INSTRUCTION_NODE = 7; var DOM_COMMENT_NODE = 8; var DOM_DOCUMENT_NODE = 9; var DOM_DOCUMENT_TYPE_NODE = 10; var DOM_DOCUMENT_FRAGMENT_NODE = 11; var DOM_NOTATION_NODE = 12; /** * Attaches an event to a node * @param node Object node to attach event to * @param eventName String name of event (sans "on", eg. "click" not "onclick") * @param functionName Function pointer to function that will handle event * @return boolean true if event attached, false otherwise */ function nodeAttachEvent(node, eventName, functionName) { if (node.addEventListener) { node.addEventListener(eventName, functionName, true); return true; } else if (node.attachEvent) { node.attachEvent("on" + eventName, functionName); return true; } else { return false; } } /** * Detaches an event from a node * @param node Object node to deattach event from * @param eventName String name of event (sans "on", eg. "click" not "onclick") * @param functionName Function pointer to function that is handling event * @return boolean true if event deattached, false otherwise */ function nodeDetachEvent(node, eventName, functionName) { if (node.removeEventListener) { node.removeEventListener(eventName, functionName, true); } else if (node.detachEvent) { node.detachEvent("on" + eventName, functionName); } else { return false; } } /** * Get CSS classes applied to a node * @param object node node to get classes for * @return Array array containing a list of classes */ function nodeClasses(node) { var classes = new Array(); if (typeof(node) == "string") { node = document.getElementById(node); } if (node) { classes = String(node.className).split(" "); } return classes; } /** * Determines if a node has a specific CSS class applied * @param String className name of class * @return Boolean true if class is applied, false otherwise */ function nodeHasClass(node, className) { var hasClass = false; if (typeof(node) == "string") { node = document.getElementById(node); } if (node) { var classes = nodeClasses(node); if (classes.inArray(className)) { hasClass = true; } } return hasClass; } /** * Applies a CSS class to a node (if it is not * already applied) * @param Object node node to apply class to * @param String className name of class to apply * @return Boolean true */ function nodeAddClass(node, className) { if (!nodeHasClass(node, className)) { var classes = nodeClasses(node); classes.push(className); var newClass = classes.implode(" "); node.className = newClass; } return true; } /** * Removes a CSS class from a node * @param Object node node to remove class from * @param String className name of class to remove * @return Boolean true */ function nodeRemoveClass(node, className) { if (nodeHasClass(node, className)) { var classes = nodeClasses(node); classes.remove(className); var newClass = classes.implode(" "); node.className = newClass; } return true; } /** * Gets first ancestor node by tag name * @param Object node node to get ancestor for * @param String tagName tag name of ancestor * @param String className optional class name that must be applied to ancestor * @return Object ancestor node that meets criteria or false if none */ function nodeGetAncestorByTagName(node, tagName, className) { var ancestor = false; var parent = node.parentNode; while ((parent) && (!ancestor)) { if (parent.tagName == tagName) { if (className) { if (nodeHasClass(parent, "tree")) { ancestor = parent; } } else { ancestor = parent; } } parent = parent.parentNode; } return ancestor; } /** * Get children of node by tag name * @param node Object node to get children from * @param tagName String tag name of children to obtain * @param depth Number how far to descend into node tree, empty or zero for all * @return Array array of child nodes meeting criteria */ function nodeChildrenByTagName(node, tagName, depth) { var children = Array(); if (node) { if (depth > 0) { var childNodes = node.childNodes; for (var n=0; n < childNodes.length; n++) { if (String(childNodes[n].tagName).toUpperCase() == String(tagName).toUpperCase()) { children.push(childNodes[n]); } } } else { children = node.getElementsByTagName(tagName); } } return children; } /** * Determines if a node has a particular attribute set * Internet explorer sometimes chokes using normal DOM methods * @param node Object node to check * @param attributeName String name of attribute to check for * @return Boolean true if node has attribute defined */ function nodeHasAttribute(node, attributeName) { if (node.hasAttribute) { return node.hasAttribute(attributeName); } else if (node.attributes.length > 0) { var rc = false; for (var n=0; n < node.attributes.length; n++) { if (node.attributes[n].nodeName == attributeName) { if (node.attributes[n].nodeValue) { rc = true; } } } return rc; } else { return false; } } /* END DOM lib */