/* Evolus Commons DOM Copyright (c) Evolus Solutions. All rights reserved. $Id: evolus.common-dom.js,v 1.4 2007/06/06 08:43:42 dgthanhan Exp $ */ /* @dependencies: */ /* Reference Definition */ if (window.EVOLUS_COMMON_DOM) { window.EVOLUS_COMMON_DOM.count ++; alert("Reference Error:\n" + "Duplicated references of Evolus Common Dom found. Ref. count = " + (window.EVOLUS_COMMON_DOM.count)); } else { window.EVOLUS_COMMON_DOM = new Object(); window.EVOLUS_COMMON_DOM.count = 1; } function Dom() { } Dom.registerEvent = function (target, event, handler, capture) { var useCapture = false; if (capture) { useCapture = true; } if (target.addEventListener) { target.addEventListener(event, handler, useCapture); } else if (target.attachEvent) { target.attachEvent("on" + event, handler); } }; Dom.disableEvent = function (node, event) { Dom.registerEvent(node, event, function(ev) {Dom.cancelEvent(ev);}, true ); }; Dom.getEvent = function (e) { return window.event ? window.event : e; }; Dom.getTarget = function (e) { var event = Dom.getEvent(e); return event.srcElement ? event.srcElement : event.originalTarget; }; Dom.getWheelDelta = function (e) { var event = Dom.getEvent(e); var delta = 0; if (event.wheelDelta) { /* IE/Opera. */ delta = event.wheelDelta/120; /** In Opera 9, delta differs in sign as compared to IE. */ } else if (event.detail) { /** Mozilla case. */ /** In Mozilla, sign of delta is different than in IE. * Also, delta is multiple of 3. */ delta = -event.detail/3; } return delta; }; Dom.cancelEvent = function (e) { var event = Dom.getEvent(e); if (event.preventDefault) event.preventDefault(); else event.returnValue = false; }; Dom.addClass = function (node, className) { if ((" " + node.className + " ").indexOf(" " + className + " ") >= 0) return; node.className += " " + className; }; Dom.removeClass = function (node, className) { if (node.className == className) { node.className = ""; return; } var re = new RegExp("(^" + className + " )|( " + className + " )|( " + className + "$)", "g"); var reBlank = /(^[ ]+)|([ ]+$)/g; node.className = node.className.replace(re, " ").replace(reBlank, ""); }; Dom.getOffsetLeft = function (control) { var offset = control.offsetLeft; var parent = control.offsetParent; if (parent) if (parent != control) return offset + Dom.getOffsetLeft(parent); return offset; }; Dom.getOffsetTop = function (control) { var offset = control.offsetTop; var parent = control.offsetParent; if (parent) if (parent != control) return offset + Dom.getOffsetTop(parent); return offset; }; Dom.getOffsetHeight = function (control) { return control.offsetHeight; }; Dom.getOffsetWidth = function (control) { return control.offsetWidth; }; Dom.getWindowHeight = function () { if ( typeof( window.innerWidth ) == 'number' ) { return window.innerHeight; } else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { return document.documentElement.clientHeight; } else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { return document.body.clientHeight; } return 0; }; Dom.getWindowWidth = function () { if ( typeof( window.innerWidth ) == 'number' ) { return window.innerWidth; } else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { return document.documentElement.clientWidth; } else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { return document.body.clientWidth; } return 0; }; Dom.getScrollTop = function () { if ( typeof( window.pageYOffset ) == 'number' ) { //Netscape compliant return window.pageYOffset; } else if ( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { //DOM compliant return document.body.scrollTop; } else if ( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { //IE6 standards compliant mode return document.documentElement.scrollTop; } return 0; }; Dom.getScrollLeft = function () { if ( typeof( window.pageXOffset ) == 'number' ) { //Netscape compliant return window.pageXOffset; } else if ( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { //DOM compliant return document.body.scrollLeft; } else if ( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { //IE6 standards compliant mode return document.documentElement.scrollLeft; } return 0; }; Dom.reformHTML = function (node) { }; Dom.appendAfter = function (fragment, node) { if (!node.parentNode) { return; } if (node.nextSibling) { node.parentNode.insertBefore(fragment, node.nextSibling); } else { node.parentNode.appendChild(fragment); } //Dom.reformHTML(node.parentNode); }; Dom.insertBefore = function (fragment, node) { if (!node.parentNode) { return; } node.parentNode.insertBefore(fragment, node); Dom.reformHTML(node.parentNode); }; Dom.appendParent = function (fragment, node) { if (!node.parentNode) { return; } node.parentNode.appendChild(fragment); Dom.reformHTML(node.parentNode); }; Dom.prependParent = function (fragment, node) { if (!node.parentNode) { return; } if (node.parentNode.childNodes.length > 0) { node.parentNode.insertBefore(fragment, node.parentNode.childNodes[0]); } else { node.parentNode.appendChild(fragment); } Dom.reformHTML(node.parentNode); }; Dom.append = function (fragment, node) { node.appendChild(fragment); Dom.reformHTML(node); }; Dom.prepend = function (fragment, node) { if (node.childNodes.length > 0) { node.insertBefore(fragment, node.childNodes[0]); } else node.appendChild(fragment); Dom.reformHTML(node); }; Dom.replace = function (fragment, node) { if (!node.parentNode) { return; } node.parentNode.replaceChild(fragment, node); Dom.reformHTML(node.parentNode); }; Dom.xmlToFragment = function (xml) { var doc = null; var wrappedXml = "" + xml + ""; if (document.implementation.createDocument) { var parser = new DOMParser(); doc = parser.parseFromString(wrappedXml, "text/xml"); } else { doc = new ActiveXObject("Microsoft.XMLDOM"); doc.loadXML(wrappedXml); } var fragment = doc.createDocumentFragment(); var root = doc.documentElement; for(var i = 0; i < root.childNodes.length; i++) { fragment.appendChild(root.childNodes[i].cloneNode(true)); } return fragment; }; Dom.importNode = function (doc, node, importChildren) { if (doc.importNode) return doc.importNode(node, importChildren); var i = 0; switch (node.nodeType) { case 11: // DOCUMENT FRAGMENT var newNode = doc.createDocumentFragment(); if (importChildren) { for(i = 0; i < node.childNodes.length; i++) { var clonedChild = Dom.importNode(doc, node.childNodes[i], true); if (clonedChild) newNode.appendChild(clonedChild); } } return newNode; case 1: // ELEMENT var newNode = doc.createElement(node.nodeName); for(i = 0; i < node.attributes.length; i++){ newNode.setAttribute(node.attributes[i].name, node.attributes[i].value); } if (importChildren) { for(i = 0; i < node.childNodes.length; i++) { var clonedChild = Dom.importNode(doc, node.childNodes[i], true); if (clonedChild) newNode.appendChild(clonedChild); } } return newNode; case 3: // TEXT return doc.createTextNode(node.nodeValue); } return null; }; Dom.get = function (id, doc) { var targetDocument = doc ? doc : document; return targetDocument.getElementById(id); }; Dom.getTags = function (tag, doc) { var targetDocument = doc ? doc : document; return targetDocument.getElementsByTagName(tag); }; Dom.getTag = function (tag, doc) { var targetDocument = doc ? doc : document; return targetDocument.getElementsByTagName(tag)[0]; }; Dom.isChildOf = function (parent, child) { if (!parent || !child) { return false; } if (parent == child) { return true; } return Dom.isChildOf(parent, child.parentNode); }; Dom.findUpward = function (node, evaluator) { if (node == null) { return null; } if (evaluator.eval(node)) { return node; } try { return Dom.findUpward(node.parentNode, evaluator); } catch (e) { return null; } }; Dom.doUpward = function (node, evaluator, worker) { if (node == null) { return; } if (evaluator.eval(node)) { worker.work(node); } return Dom.doUpward(node.parentNode, evaluator, worker); }; Dom.findChild = function (node, evaluator) { if (!node || !node.childNodes) return null; for (var i = 0; i < node.childNodes.length; i++) { var child = node.childNodes[i]; if (evaluator.eval(child)) return child; } return null; }; Dom.doOnChild = function (node, evaluator, worker) { if (!node || !node.childNodes) return null; for (var i = 0; i < node.childNodes.length; i++) { var child = node.childNodes[i]; if (evaluator.eval(child)) worker(child); } }; Dom.doOnAllChildren = function (node, worker) { Dom.doOnChild(node, DomAcceptAllEvaluator, worker); }; Dom.doOnChildRecursively = function (node, evaluator, worker) { if (!node || !node.childNodes) return null; for (var i = 0; i < node.childNodes.length; i++) { var child = node.childNodes[i]; if (evaluator.eval(child)) worker(child); Dom.doOnChildRecursively(child, evaluator, worker); } }; Dom.findChildTag = function (node, tag) { return Dom.findChild(node, new DomTagNameEvaluator(tag)); }; Dom.findChildWithClass = function (node, className) { return Dom.findChild(node, {eval: function (node) { return (" " + node.className + " ").indexOf(" " + className + " ") >= 0; }}); }; function DomTagNameEvaluator(tagName) { this.tagName = tagName.toUpperCase(); } DomTagNameEvaluator.prototype.eval = function (node) { return node && node.tagName && node.tagName.toUpperCase && (node.tagName.toUpperCase() == this.tagName); }; Dom.findParentWithClass = function (node, className) { return Dom.findUpward(node, { className: className, eval: function (node) { try { return (" " + node.className + " ").indexOf(" " + this.className + " ") >= 0; } catch (e) { return false; } } }); }; Dom.findParentByTagName = function (node, tagName) { return Dom.findUpward(node, { tagName: tagName.toUpperCase(), eval: function (node) { return node.tagName && node.tagName.toUpperCase && (node.tagName.toUpperCase() == this.tagName); } }); } Dom.findParentWithProperty = function (node, property) { if (node == null) { return null; } if (typeof(node[property]) != "undefined") { return node; } return Dom.findParentWithProperty(node.parentNode, property); }; Dom.findParentWithAttribute = function (node, attName, attValue) { if (node == null) { return null; } //alert(node); if (node.getAttribute) { var value = node.getAttribute(attName); if (value) { if (!attValue) return node; if (attValue == value) return node; } } return Dom.findParentWithAttribute(node.parentNode, attName, attValue); }; Dom.findNonEditableParent = function (node) { if (node == null) { return null; } return Dom.findNonEditableParent(node.parentNode); }; Dom.isTag = function (node, tagName) { return (node.tagName && node.tagName.toUpperCase && node.tagName.toUpperCase() == tagName.toUpperCase()); }; Dom.hasClass = function (node, className) { return (" " + node.className + " ").indexOf(className) >= 0; }; Dom.findDescendant = function(node, evaluator) { for (var i = 0; i < node.childNodes.length; i ++) { var child = node.childNodes[i]; if (evaluator(child)) return child; var c = Dom.findDescendant(child, evaluator); if (c) return c; } return null; } Dom.findDescendantByTagName = function(element, tagName) { return Dom.findDescendant(element, function (node) { return node.tagName && node.tagName.toUpperCase && (node.tagName.toUpperCase() == tagName.toUpperCase()); }); }; Dom.findDescendantWithClass = function(element, className) { return Dom.findDescendant(element, function (node) { return Dom.hasClass(node, className); }); }; Dom.findFirstChild = function(node, tagName) { for (var i = 0; i < node.childNodes.length; i ++) { var child = node.childNodes[i]; if (Dom.isTag(child, tagName)) { return child; } } return null; } Dom.findFirstChildWithClass = function(node, className) { for (var i = 0; i < node.childNodes.length; i ++) { var child = node.childNodes[i]; if ((" " + child.className + " ").indexOf(" " + className + " ") >= 0) { return child; } } return null; }; Dom.findLastChild = function(node, tagName) { for (var i = node.childNodes.length - 1; i >= 0; i --) { var child = node.childNodes[i]; if (Dom.isTag(child, tagName)) { return child; } } return null; } Dom.getDocumentBody = function () { return document.getElementsByTagName("body")[0]; }; Dom.htmlEncode = function (s) { if (!Dom.htmlEncodePlaceHolder) { Dom.htmlEncodePlaceHolder = document.createElement("div"); } Dom.htmlEncodePlaceHolder.innerHTML = ""; Dom.htmlEncodePlaceHolder.appendChild(document.createTextNode(s)); return Dom.htmlEncodePlaceHolder.innerHTML; }; Dom.setInnerText = function (node, text) { node.innerHTML = ""; node.appendChild(node.ownerDocument.createTextNode(text)); }; Dom.getInnerText = function (node) { if (document.all) return node.innerText; if (node.textContent) return node.textContent; if (node.firstChild && node.firstChild.value) return node.firstChild.value; return ""; }; Dom.installBehavior = function(target, eventName, checker, handler) { Dom.registerEvent(target, eventName, function(e) { if (checker.check(e)) { handler.positive(); } else { handler.nagative(); } }); Dom.registerEvent(window, "load", function(e) { if (checker.check(null, target)) { handler.positive(); } else { handler.nagative(); } }); }; function DomSelectedChecker() { } DomSelectedChecker.prototype.check = function (event, t) { var target = t ? t : Dom.getTarget(event); return target.checked || target.selected; }; Dom.SELECTED_CHECKER = new DomSelectedChecker(); var DomAcceptAllEvaluator = { eval: function (target) { return true; } }; function DomValueIsChecker(value) { this.value = value; } DomValueIsChecker.prototype.check = function (event, t) { var target = t ? t : Dom.getTarget(event); if (target.value && target.value == this.value) { return true; } if (target.selectedIndex && target.options && target.options[target.selectedIndex]) { if (target.options[target.selectedIndex].value == this.value) { return true; } } return false; }; function DomValueInChecker(values) { this.values = values; } DomValueInChecker.prototype.check = function (event, t) { var target = t ? t : Dom.getTarget(event); var value = null; if (target.value) { value = target.value; } if (target.selectedIndex && target.options && target.options[target.selectedIndex]) { value = target.options[target.selectedIndex].value; } if (value && this.values.indexOf("|" + value + "|") >= 0) { return true; } return false; }; function DomEnableToggleHandler(control) { this.control = control; } DomEnableToggleHandler.prototype.positive = function() { var firstControl = Dom.disableControls(this.control, false); if (firstControl && firstControl.focus) { firstControl.focus(); firstControl.select(); } }; DomEnableToggleHandler.prototype.nagative = function() { Dom.disableControls(this.control, true); }; Dom.disableControls = function (element, disabled) { var nodeName = element.nodeName.toUpperCase(); if (nodeName == "INPUT" || nodeName == "TEXTAREA" || nodeName == "SELECT") { element.disabled = disabled; return element; } else if (element.childNodes) { var firstControl = null; for (var i = 0; i < element.childNodes.length; i ++) { var control = Dom.disableControls(element.childNodes[i], disabled); if (!firstControl) firstControl = control; } return firstControl; } }; function DomVisibilityToggleHandler(control) { this.control = control; } DomVisibilityToggleHandler.prototype.positive = function() { this.control.style.display = ""; }; DomVisibilityToggleHandler.prototype.nagative = function() { this.control.style.display = "none"; }; Dom.createElement = function (spec) { var tag = document.createElement(spec._name); for (var att in spec) { if (att == "_children") { var children = spec[att]; for (var i in children) { tag.appendChild(Dom.createElement(children[i])); } return; } if (att == "_text") { Dom.setInnerText(tag, spec[att]); continue; } if (att == "class") { att.className = spec[att]; } tag.setAttribute(att, "" + spec[att]); } return tag; };