// Developed by Robert Nyman, code/licensing: http://code.google.com/p/domassistant/, documentation: http://www.robertnyman.com/domassistant var DOMAssistant = function () { var HTMLArray = function () { // Constructor }; var isIE = document.all && !/Opera/i.test(navigator.userAgent); return { allMethods : [], publicMethods : [ "elmsByClass", "elmsByAttribute", "elmsByTag" ], initCore : function () { this.applyMethod.call(window, "$", this.$); this.applyMethod.call(window, "$$", this.$$); window.DOMAssistant = this; if (isIE) { HTMLArray = Array; } HTMLArray.prototype = []; HTMLArray.prototype.each = function (functionCall) { for (var i=0, il=this.length; i|\+|~)?/; for (var i=0, il=cssRules.length; i 0) { identical = false; for (var x=0, xl=i; x": xPathExpression += "/child::"; break; case "+": xPathExpression += "/following-sibling::*[1]/self::"; break; case "~": xPathExpression += "/following-sibling::"; break; } } else { xPathExpression += (j > 0 && /(>|\+|~)/.test(cssSelectors[j-1]))? splitRule.tag : ("/descendant::" + splitRule.tag); } if (splitRule.id) { xPathExpression += "[@id = '" + splitRule.id.replace(/^#/, "") + "']"; } if (splitRule.allClasses) { xPathExpression += splitRule.allClasses.replace(/\.([\w\-_]+)/g, "[contains(concat(' ', @class, ' '), ' $1 ')]"); } if (splitRule.allAttr) { xPathExpression += splitRule.allAttr.replace(/(\w+)(\^|\$|\*)?=?([\w\-_]+)?/g, function (match, p1, p2, p3, p4) { var regExpReturn = match; switch (p2) { case "^": regExpReturn = "starts-with(@" + p1 + ", '" + p3 + "')"; break; case "$": regExpReturn = "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p3.length - 1) + "), 6) = '" + p3 + "'"; break; case "*": regExpReturn = "contains(concat(' ', @" + p1 + ", ' '), '" + p3 + "')"; break; default : regExpReturn = "@" + p1 + ((p3)? "='" + p3 + "'" : ""); } return regExpReturn; }); } if (splitRule.pseudoClass) { var pseudoValue = splitRule.pseudoValue; switch (splitRule.pseudoClass.replace(/^:/, "")) { case "first-child": xPathExpression += "[count(preceding-sibling::*) = 0]"; break; case "first-of-type": xPathExpression += "[count(preceding-sibling::" + splitRule.tag + ") = 0]"; break; case "last-child": xPathExpression += "[count(following-sibling::*) = 0]"; break; case "last-of-type": xPathExpression += "[count(following-sibling::" + splitRule.tag + ") = 0]"; break; case "only-child": xPathExpression += "[count(preceding-sibling::*) = 0 and count(following-sibling::*) = 0]"; break; case "only-of-type": xPathExpression += "[count(preceding-sibling::" + splitRule.tag + ") = 0 and count(following-sibling::" + splitRule.tag + ") = 0]"; break; case "nth-of-type": xPathExpression += "[" + pseudoValue + "]"; break; case "empty": xPathExpression += "[count(child::*) = 0 and string-length(text()) = 0]"; break; case "contains": xPathExpression += "[contains(., '" + pseudoValue + "')]"; break; case "enabled": xPathExpression += "[not(@disabled)]"; break; case "disabled": xPathExpression += "[@disabled]"; break; case "checked": xPathExpression += "[@checked='checked']"; // Doesn't work in Opera 9.24 break; case "nth-child": var pseudoSelection = "["; if (/^\d+$/.test(pseudoValue)) { pseudoSelection += "position() = " + pseudoValue; } else if (/^n$/.test(pseudoValue)) { pseudoSelection = ""; } else{ if (/^odd$/.test(pseudoValue)) { pseudoValue = "2n+1"; } else if (/^even$/.test(pseudoValue)) { pseudoValue = "2n+0"; } var pseudoSelector = /^(\d+)n((\+|\-)(\d+))?$/.exec(pseudoValue); var nthSelector = parseInt(pseudoSelector[1], 10); var nOperatorVal = 0; if (pseudoSelector[3] && pseudoSelector[4]) { nOperatorVal = parseInt((pseudoSelector[3] + pseudoSelector[4]), 10); if (nOperatorVal < 0) { nOperatorVal = nthSelector + nOperatorVal; } } pseudoSelection += "(count(./preceding-sibling::*) + 1)"; if (nthSelector < nOperatorVal) { var nOperatorDiff = ((nOperatorVal - nthSelector) % 2 === 0)? 0 : 1; pseudoSelection += " mod " + nthSelector + " = " + nOperatorDiff + " and position() > " + nOperatorVal; } else if (nOperatorVal === nthSelector) { pseudoSelection += " mod " + nthSelector + " = 0"; } else { pseudoSelection += " mod " + nthSelector + " = " + nOperatorVal; } } if (!/^n$/.test(pseudoValue)) { pseudoSelection += "]"; } xPathExpression += pseudoSelection; break; case "not": pseudoValue = pseudoValue.replace(/^\[#([\w\-\_]+)\]$/, "[id=$1]"); var notSelector = pseudoValue.replace(/^(\w+)/, "self::$1"); notSelector = notSelector.replace(/\.([\w\-_]+)/g, "contains(concat(' ', @class, ' '), ' $1 ')"); notSelector = notSelector.replace(/\[(\w+)(\^|\$|\*)?=?([\w\-_]+)?\]/g, function (match, p1, p2, p3, p4) { var regExpReturn = match; switch (p2) { case "^": regExpReturn = "starts-with(@" + p1 + ", '" + p3 + "')"; break; case "$": regExpReturn = "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p3.length - 1) + "), 6) = '" + p3 + "'"; break; case "*": regExpReturn = "contains(concat(' ', @" + p1 + ", ' '), '" + p3 + "')"; break; default : regExpReturn = "@" + p1 + ((p3)? "='" + p3 + "'" : ""); } return regExpReturn; }); xPathExpression += "[not(" + notSelector + ")]"; break; } } } var xPathNodes = document.evaluate(xPathExpression, document, null, 0, null); var node = xPathNodes.iterateNext(); while(node) { elm.push(node); node = xPathNodes.iterateNext(); } } return elm; }; } else { DOMAssistant.cssSelection = function (cssRule) { var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(","); var elm = new HTMLArray(); var prevElm = new HTMLArray(); var matchingElms = new HTMLArray(); var prevParents, currentRule, identical, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, refSeparator, refPrevElm, nextSib, refPrevElmFound, current, previous, prevParent, addElm, firstChild, lastChild, parentTagsByType, matchingChild, childrenNodes, childNodes; var childOrSiblingRefRegExp = /^(>|\+|~)$/; var cssSelectorRegExp = /^(\w+)?(#[\w\-_]+|\*)?((\.[\w\-_]+)*)?((\[\w+(\^|\$|\*)?=?[\w\-\_]+\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\d*n?((\+|\-)\d+)?|\w+|((\w*\.[\w\-_]+)*)?|(\[#?\w+(\^|\$|\*)?=?[\w\-\_]+\]+))\))?)*)?/; var matchedObjects; function clearAdded() { for (var n=0, nl=prevElm.length; n 0) { identical = false; for (var b=0, bl=a; b 0 && childOrSiblingRefRegExp.test(rule)) { childOrSiblingRef = childOrSiblingRefRegExp.exec(rule); if (childOrSiblingRef) { nextTag = /^\w+/.exec(cssSelectors[i+1]); if (nextTag) { nextRegExp = new RegExp("(^|\\s)" + nextTag + "(\\s|$)", "i"); refSeparator = childOrSiblingRef[0]; if (refSeparator === ">") { for (var j=0, jl=prevElm.length, children; j 0) { if (!attributeRegExp || typeof attributeRegExp === "undefined" || (attributeRegExp && attributeRegExp.test(currentAttr))) { addElm = true; } } if (!addElm) { break; } } if (addElm) { current.added = true; matchingAttributeElms.push(current); } } } clearAdded(); matchingElms = matchingAttributeElms; prevElm = matchingElms; } if (splitRule.pseudoClass) { var pseudoClass = splitRule.pseudoClass; var pseudoValue = splitRule.pseudoValue; var previousMatch = matchingElms; matchingElms = []; prevParents = []; if (/^:not$/.test(pseudoClass)) { pseudoValue = pseudoValue.replace(/^\[#([\w\-\_]+)\]$/, "[id=$1]"); var notTag = /^(\w+)/.exec(pseudoValue); var notClass = /\.([\w\-_]+)/.exec(pseudoValue); var notAttr = /\[(\w+)(\^|\$|\*)?=?([\w\-_]+)?\]/.exec(pseudoValue); var notRegExp = new RegExp("(^|\\s)" + ((notTag)? notTag[1] : (notClass)? notClass[1] : "") + "(\\s|$)", "i"); if (notAttr) { var notAttribute = notAttr[3]; var notMatchingAttrVal = "^" + notAttr[3] + "$"; var substrNoMatchSelector = notAttr[2]; if (typeof substrNoMatchSelector === "string") { switch (substrNoMatchSelector) { case "^": notMatchingAttrVal = ("^" + notAttribute); break; case "$": notMatchingAttrVal = (notAttribute + "$"); break; case "*": notMatchingAttrVal = (notAttribute); break; } } notRegExp = new RegExp(notMatchingAttrVal, "i"); } for (var t=0, tl=previousMatch.length, notElm; t 0) { iteratorAdd = nRepeat; var nOperatorVal = (pseudoSelector[4])? parseInt((pseudoSelector[4] + pseudoSelector[5]), 10) : 0; iteratorStart = nOperatorVal - 1; } for (var z=0, zl=previousMatch.length; z= nthIndex) { for (var zInnerNth=0, zInnerNthL=parentTagsByType.length, childNode; zInnerNth 0) { if (!attributeRegExp || typeof attributeRegExp === "undefined" || (attributeRegExp && attributeRegExp.test(currentAttr))) { returnElms.push(current); } } } return returnElms; }; } return DOMAssistant.elmsByAttribute.call(this, attr, attrVal, tag, substrMatchSelector); }, elmsByTag : function (tag) { if (document.evaluate) { DOMAssistant.elmsByTag = function (tag) { var returnElms = new HTMLArray(); var xPathNodes = document.evaluate(".//" + ((typeof tag === "string")? tag : "*"), this, null, 0, null); var node = xPathNodes.iterateNext(); while(node) { returnElms.push(node); node = xPathNodes.iterateNext(); } return returnElms; }; } else { DOMAssistant.elmsByTag = function (tag) { var returnElms = new HTMLArray(); var elmsWithTag = this.getElementsByTagName(tag); for (var i=0, il=elmsWithTag.length; i 0)? " " : "") + className; } return this; }, removeClass : function (className) { var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i"); this.className = this.className.replace(classToRemove, function (match) { var retVal = ""; if (new RegExp("^\\s+.*\\s+$").test(match)) { retVal = match.replace(/(\s+).+/, "$1"); } return retVal; }).replace(/^\s+|\s+$/g, ""); return this; }, replaceClass : function (className, newClass) { var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i"); this.className = this.className.replace(classToRemove, function (match, p1, p2) { var retVal = p1 + newClass + p2; if (new RegExp("^\\s+.*\\s+$").test(match)) { retVal = match.replace(/(\s+).+/, "$1"); } return retVal; }).replace(/^\s+|\s+$/g, ""); return this; }, hasClass : function (className) { return new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i").test(this.className); }, getStyle : function (cssRule) { var cssVal = ""; if (document.defaultView && document.defaultView.getComputedStyle) { cssVal = document.defaultView.getComputedStyle(this, "").getPropertyValue(cssRule); } else if (this.currentStyle) { cssVal = cssRule.replace(/\-(\w)/g, function (match, p1) { return p1.toUpperCase(); }); cssVal = this.currentStyle[cssVal]; } return cssVal; } }; }(); DOMAssistant.attach(DOMAssistant.CSS);// Developed by Robert Nyman, code/licensing: http://code.google.com/p/domassistant/, documentation: http://www.robertnyman.com/domassistant /*extern DOMAssistant */ DOMAssistant.Content = function () { return { prev : function () { var prevSib = this.previousSibling; while(prevSib && prevSib.nodeType !== 1) { prevSib = prevSib.previousSibling; } return prevSib; }, next : function () { var nextSib = this.nextSibling; while(nextSib && nextSib.nodeType !== 1) { nextSib = nextSib.nextSibling; } return nextSib; }, create : function (name, attr, append, content) { var elm = DOMAssistant.$(document.createElement(name)); if (attr) { elm.setAttributes(attr); } if (typeof content !== "undefined") { elm.addContent(content); } if (append) { DOMAssistant.Content.addContent.call(this, elm); } return elm; }, setAttributes : function (attr) { for (var i in attr) { if (/class/i.test(i)) { this.className = attr[i]; } else{ this.setAttribute(i, attr[i]); } } return this; }, addContent : function (content) { if (typeof content === "string") { this.innerHTML += content; } else{ this.appendChild(content); } return this; }, replaceContent : function (newContent) { for (var i=(this.childNodes.length - 1), child, attr; i>=0; i--) { child = this.childNodes[i]; attr = child.attributes; if (attr) { for (var j=0, jl=attr.length; j<\/script>"); document.getElementById("ieScriptLoad").onreadystatechange = function() { if (this.readyState === "complete") { DOMHasLoaded(); } }; } /*@end @*/ /* Mozilla/Opera 9 */ if (document.addEventListener) { document.addEventListener("DOMContentLoaded", DOMHasLoaded, false); } /* Safari */ if (navigator.userAgent.search(/WebKit/i) !== -1) { DOMLoadTimer = setInterval(function () { if (document.readyState.search(/loaded|complete/i) !== -1) { var loaded = new DOMHasLoaded(); } }, 10); } /* Other web browsers */ window.onload = DOMHasLoaded; return { DOMReady : function () { for (var i=0, il=arguments.length, func, callFunc; i