Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated the performance testing frameworks.

  • Loading branch information...
commit 31e56542e0d3e04a9271fbb0009279ead29d9f1e 1 parent 846174c
@jeresig jeresig authored
View
8 speed/config.ini
@@ -6,19 +6,19 @@
file = "jquery.js"
function = "jQuery"
-[Dojo 1.1.1]
+[Dojo 1.2.0]
file = "dojo.js"
function = "dojo.query"
-[MooTools 1.2]
+[MooTools 1.2.1]
file = "mootools.js"
function = "$$"
-[Prototype 1.6.0.2]
+[Prototype 1.6.0.3]
file = "prototype.js"
function = "$$"
-[DOMAss 2.7.1.1]
+[DOMAss 2.7.2]
file = "domass.js"
function = "$"
View
1  speed/frameworks/blah.js
View
1,841 speed/frameworks/dojo.js
1,067 additions, 774 deletions not shown
View
1,204 speed/frameworks/domass.js
@@ -1,4 +1,4 @@
-// Developed by Robert Nyman/DOMAssistant team, code/licensing: http://code.google.com/p/domassistant/, documentation: http://www.domassistant.com/documentation, version 2.7.1.1
+// Developed by Robert Nyman/DOMAssistant team, code/licensing: http://code.google.com/p/domassistant/, documentation: http://www.domassistant.com/documentation, version 2.7.2
var DOMAssistant = function () {
var HTMLArray = function () {
// Constructor
@@ -122,16 +122,19 @@ var DOMAssistant = function () {
}
else {
elmsToReturn.push(elms);
- }
+ }
}
return elmsToReturn;
};
},
$ : function () {
+ var obj = arguments[0];
+ if (arguments.length === 1 && (typeof obj === "object" || (typeof obj === "function" && typeof obj.nodeName !== "undefined"))) {
+ return DOMAssistant.$$(obj);
+ }
var elm = new HTMLArray();
- if (document.getElementById) {
- var arg = arguments[0];
+ for (var i=0, arg; (arg=arguments[i]); i++) {
if (typeof arg === "string") {
arg = arg.replace(/^[^#]*(#)/, "$1");
if (/^#[\w\u00C0-\uFFFF\-\_]+$/.test(arg)) {
@@ -141,18 +144,15 @@ var DOMAssistant = function () {
}
}
else {
- elm = DOMAssistant.cssSelection.call(document, arg);
+ elm = pushAll(elm, DOMAssistant.cssSelection.call(document, arg));
}
}
- else if ((typeof arg === "object") || (typeof arg === "function" && typeof arg.nodeName !== "undefined")) {
- elm = (arguments.length === 1)? DOMAssistant.$$(arg) : pushAll(elm, arguments);
- }
}
return elm;
},
-
+
$$ : function (id, addMethods) {
- var elm = ((typeof id === "object") || (typeof id === "function" && typeof id.nodeName !== "undefined"))? id : document.getElementById(id);
+ var elm = (typeof id === "object" || (typeof id === "function" && typeof id.nodeName !== "undefined"))? id : document.getElementById(id);
var applyMethods = addMethods || true;
if (typeof id === "string" && elm && elm.id !== id) {
elm = null;
@@ -168,620 +168,623 @@ var DOMAssistant = function () {
}
return elm;
},
-
- cssSelection : function (cssRule) {
- var getSequence = function (expression) {
- var start, add = 2, max = -1, modVal = -1;
- var expressionRegExp = /^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n([\+\-]\d+)?)|(\-(([1-9]\d*)?)n\+(\d+)))$/;
- var pseudoValue = expressionRegExp.exec(expression);
- if (!pseudoValue) {
- return null;
+
+ getSequence : function (expression) {
+ var start, add = 2, max = -1, modVal = -1;
+ var expressionRegExp = /^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n([\+\-]\d+)?)|(\-(([1-9]\d*)?)n\+(\d+)))$/;
+ var pseudoValue = expressionRegExp.exec(expression);
+ if (!pseudoValue) {
+ return null;
+ }
+ else {
+ if (pseudoValue[2]) { // odd or even
+ start = (pseudoValue[2] === "odd")? 1 : 2;
+ modVal = (start === 1)? 1 : 0;
}
- else {
- if (pseudoValue[2]) { // odd or even
- start = (pseudoValue[2] === "odd")? 1 : 2;
- modVal = (start === 1)? 1 : 0;
+ else if (pseudoValue[3]) { // single digit
+ start = parseInt(pseudoValue[3], 10);
+ add = 0;
+ max = start;
+ }
+ else if (pseudoValue[4]) { // an+b
+ add = pseudoValue[6]? parseInt(pseudoValue[6], 10) : 1;
+ start = pseudoValue[7]? parseInt(pseudoValue[7], 10) : 0;
+ while (start < 1) {
+ start += add;
}
- else if (pseudoValue[3]) { // single digit
- start = parseInt(pseudoValue[3], 10);
- add = 0;
- max = start;
+ modVal = (start > add)? (start - add) % add : ((start === add)? 0 : start);
+ }
+ else if (pseudoValue[8]) { // -an+b
+ add = pseudoValue[10]? parseInt(pseudoValue[10], 10) : 1;
+ start = max = parseInt(pseudoValue[11], 10);
+ while (start > add) {
+ start -= add;
}
- else if (pseudoValue[4]) { // an+b
- add = pseudoValue[6]? parseInt(pseudoValue[6], 10) : 1;
- start = pseudoValue[7]? parseInt(pseudoValue[7], 10) : 0;
- while (start < 1) {
- start += add;
+ modVal = (max > add)? (max - add) % add : ((max === add)? 0 : max);
+ }
+ }
+ return { start: start, add: add, max: max, modVal: modVal };
+ },
+
+ cssByDOM : function (cssRule) {
+ var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(",");
+ var elm = new HTMLArray();
+ var prevElm = [], matchingElms = [];
+ var prevParents, currentRule, identical, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, regExpClassNames, matchingClassElms, regExpAttributes, matchingAttributeElms, attributeMatchRegExp, current, previous, prevParent, addElm, iteratorNext, childCount, childElm, sequence;
+ var childOrSiblingRefRegExp = /^(>|\+|~)$/;
+ var cssSelectorRegExp = /^(\w+)?(#[\w\u00C0-\uFFFF\-\_]+|(\*))?((\.[\w\u00C0-\uFFFF\-_]+)*)?((\[\w+(\^|\$|\*|\||~)?(=([\w\u00C0-\uFFFF\s\-\_\.]+|"[^"]*"|'[^']*'))?\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\-?\d*n?((\+|\-)\d+)?|[\w\u00C0-\uFFFF\-_]+|"[^"]*"|'[^']*'|((\w*\.[\w\u00C0-\uFFFF\-_]+)*)?|(\[#?\w+(\^|\$|\*|\||~)?=?[\w\u00C0-\uFFFF\s\-\_\.]+\]+)|(:\w+[\w\-]*))\))?)*)?/;
+ var selectorSplitRegExp;
+ try {
+ selectorSplitRegExp = new RegExp("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]", "g");
+ }
+ catch (e) {
+ selectorSplitRegExp = /[^\s]+/g;
+ }
+ function clearAdded (elm) {
+ elm = elm || prevElm;
+ for (var n=0, nl=elm.length; n<nl; n++) {
+ elm[n].added = null;
+ }
+ }
+ function clearChildElms () {
+ for (var n=0, nl=prevParents.length; n<nl; n++) {
+ prevParents[n].childElms = null;
+ }
+ }
+ function subtractArray (arr1, arr2) {
+ for (var i=0, src1; (src1=arr1[i]); i++) {
+ var found = false;
+ for (var j=0, src2; (src2=arr2[j]); j++) {
+ if (src2 === src1) {
+ found = true;
+ break;
}
- modVal = (start > add)? (start - add) % add : ((start === add)? 0 : start);
}
- else if (pseudoValue[8]) { // -an+b
- add = pseudoValue[10]? parseInt(pseudoValue[10], 10) : 1;
- start = max = parseInt(pseudoValue[11], 10);
- while (start > add) {
- start -= add;
- }
- modVal = (max > add)? (max - add) % add : ((max === add)? 0 : max);
+ if (found) {
+ arr1.splice(i--, 1);
}
}
- return { start: start, add: add, max: max, modVal: modVal };
- };
- if (document.evaluate) {
- var ns = { xhtml: "http://www.w3.org/1999/xhtml" };
- var prefix = (document.documentElement.namespaceURI === ns.xhtml)? "xhtml:" : "";
- var nsResolver = function lookupNamespaceURI (prefix) {
- return ns[prefix] || null;
- };
- DOMAssistant.cssSelection = function (cssRule) {
- var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(",");
- var elm = new HTMLArray();
- var currentRule, identical, cssSelectors, xPathExpression, cssSelector, splitRule, sequence;
- var cssSelectorRegExp = /^(\w+)?(#[\w\u00C0-\uFFFF\-\_]+|(\*))?((\.[\w\u00C0-\uFFFF\-_]+)*)?((\[\w+(\^|\$|\*|\||~)?(=([\w\u00C0-\uFFFF\s\-\_\.]+|"[^"]*"|'[^']*'))?\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\-?\d*n?((\+|\-)\d+)?|[\w\u00C0-\uFFFF\-_\.]+|"[^"]*"|'[^']*'|((\w*\.[\w\u00C0-\uFFFF\-_]+)*)?|(\[#?\w+(\^|\$|\*|\||~)?=?[\w\u00C0-\uFFFF\s\-\_\.]+\]+)|(:\w+[\w\-]*))\))?)*)?(>|\+|~)?/;
- var selectorSplitRegExp = new RegExp("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]", "g");
- function attrToXPath (match, p1, p2, p3) {
- p3 = p3.replace(/^["'](.*)["']$/, "$1");
- switch (p2) {
- case "^": return "starts-with(@" + p1 + ", \"" + p3 + "\")";
- case "$": return "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p3.length - 1) + "), " + p3.length + ") = \"" + p3 + "\"";
- case "*": return "contains(concat(\" \", @" + p1 + ", \" \"), \"" + p3 + "\")";
- case "|": return "(@" + p1 + "=\"" + p3 + "\" or starts-with(@" + p1 + ", \"" + p3 + "-\"))";
- case "~": return "contains(concat(\" \", @" + p1 + ", \" \"), \" " + p3 + " \")";
- default: return "@" + p1 + (p3? "=\"" + p3 + "\"" : "");
- }
+ return arr1;
+ }
+ function getAttr (elm, attr) {
+ return isIE? elm[camel[attr.toLowerCase()] || attr] : elm.getAttribute(attr, 2);
+ }
+ function attrToRegExp (attrVal, substrOperator) {
+ attrVal = attrVal? attrVal.replace(/^["'](.*)["']$/, "$1").replace(/\./g, "\\.") : null;
+ switch (substrOperator) {
+ case "^": return "^" + attrVal;
+ case "$": return attrVal + "$";
+ case "*": return attrVal;
+ case "|": return "(^" + attrVal + "(\\-\\w+)*$)";
+ case "~": return "\\b" + attrVal + "\\b";
+ default: return attrVal? "^" + attrVal + "$" : null;
+ }
+ }
+ function getElementsByTagName (tag, parent) {
+ tag = tag || "*";
+ parent = parent || document;
+ if (parent === document || parent.lastModified) {
+ if (!cachedElms[tag]) {
+ cachedElms[tag] = isIE? ((tag === "*")? document.all : document.all.tags(tag)) : document.getElementsByTagName(tag);
}
- function pseudoToXPath (tag, pseudoClass, pseudoValue) {
- tag = (/\-child$/.test(pseudoClass))? "*" : tag;
- var xpath = "", pseudo = pseudoClass.split("-");
- switch (pseudo[0]) {
- case "first":
- xpath = "not(preceding-sibling::" + tag + ")";
- break;
- case "last":
- xpath = "not(following-sibling::" + tag + ")";
- break;
- case "only":
- xpath = "not(preceding-sibling::" + tag + " or following-sibling::" + tag + ")";
- break;
- case "nth":
- if (!/^n$/.test(pseudoValue)) {
- var position = ((pseudo[1] === "last")? "(count(following-sibling::" : "(count(preceding-sibling::") + tag + ") + 1)";
- sequence = getSequence(pseudoValue);
- if (sequence) {
- if (sequence.start === sequence.max) {
- xpath = position + " = " + sequence.start;
- }
- else {
- xpath = position + " mod " + sequence.add + " = " + sequence.modVal + ((sequence.start > 1)? " and " + position + " >= " + sequence.start : "") + ((sequence.max > 0)? " and " + position + " <= " + sequence.max: "");
+ return cachedElms[tag];
+ }
+ return isIE? ((tag === "*")? parent.all : parent.all.tags(tag)) : parent.getElementsByTagName(tag);
+ }
+ function getElementsByPseudo (previousMatch, pseudoClass, pseudoValue) {
+ prevParents = [];
+ var pseudo = pseudoClass.split("-"), matchingElms = [], checkNodeName;
+ var prop = (checkNodeName = /\-of\-type$/.test(pseudoClass))? "nodeName" : "nodeType";
+ function getPrevElm(elm) {
+ var val = checkNodeName? elm.nodeName : 1;
+ while ((elm = elm.previousSibling) && elm[prop] !== val) {}
+ return elm;
+ }
+ function getNextElm(elm) {
+ var val = checkNodeName? elm.nodeName : 1;
+ while ((elm = elm.nextSibling) && elm[prop] !== val) {}
+ return elm;
+ }
+ switch (pseudo[0]) {
+ case "first":
+ for (var i=0; (previous=previousMatch[i]); i++) {
+ if (!getPrevElm(previous)) {
+ matchingElms[matchingElms.length] = previous;
+ }
+ }
+ break;
+ case "last":
+ for (var j=0; (previous=previousMatch[j]); j++) {
+ if (!getNextElm(previous)) {
+ matchingElms[matchingElms.length] = previous;
+ }
+ }
+ break;
+ case "only":
+ for (var k=0, kParent; (previous=previousMatch[k]); k++) {
+ prevParent = previous.parentNode;
+ if (prevParent !== kParent) {
+ if (!getPrevElm(previous) && !getNextElm(previous)) {
+ matchingElms[matchingElms.length] = previous;
+ }
+ kParent = prevParent;
+ }
+ }
+ break;
+ case "nth":
+ if (/^n$/.test(pseudoValue)) {
+ matchingElms = previousMatch;
+ }
+ else {
+ var direction = (pseudo[1] === "last")? ["lastChild", "previousSibling"] : ["firstChild", "nextSibling"];
+ sequence = DOMAssistant.getSequence.call(this, pseudoValue);
+ if (sequence) {
+ for (var l=0; (previous=previousMatch[l]); l++) {
+ prevParent = previous.parentNode;
+ if (!prevParent.childElms) {
+ iteratorNext = sequence.start;
+ childCount = 0;
+ childElm = prevParent[direction[0]];
+ while (childElm && (sequence.max < 0 || iteratorNext <= sequence.max)) {
+ if (checkNodeName) {
+ if (childElm.nodeName === previous.nodeName) {
+ if (++childCount === iteratorNext) {
+ matchingElms[matchingElms.length] = childElm;
+ iteratorNext += sequence.add;
+ }
+ }
+ }
+ else {
+ if (childElm.nodeType === 1) {
+ if (++childCount === iteratorNext) {
+ if (childElm.nodeName === previous.nodeName) {
+ matchingElms[matchingElms.length] = childElm;
+ }
+ iteratorNext += sequence.add;
+ }
+ }
+ }
+ childElm = childElm[direction[1]];
}
+ prevParent.childElms = true;
+ prevParents[prevParents.length] = prevParent;
}
}
- break;
- case "empty":
- xpath = "count(child::*) = 0 and string-length(text()) = 0";
- break;
- case "contains":
- xpath = "contains(., \"" + pseudoValue.replace(/^["'](.*)["']$/, "$1") + "\")";
- break;
- case "enabled":
- xpath = "not(@disabled)";
- break;
- case "disabled":
- xpath = "@disabled";
- break;
- case "checked":
- xpath = "@checked=\"checked\""; // Doesn't work in Opera 9.24
- break;
- case "target":
- var hash = document.location.hash.slice(1);
- xpath = "@name=\"" + hash + "\" or @id=\"" + hash + "\"";
- break;
- case "not":
- if (/^(:\w+[\w\-]*)$/.test(pseudoValue)) {
- xpath = "not(" + pseudoToXPath(tag, pseudoValue.slice(1)) + ")";
- }
- else {
- pseudoValue = pseudoValue.replace(/^\[#([\w\u00C0-\uFFFF\-\_]+)\]$/, "[id=$1]");
- var notSelector = pseudoValue.replace(/^(\w+)/, "self::$1");
- notSelector = notSelector.replace(/^\.([\w\u00C0-\uFFFF\-_]+)/g, "contains(concat(\" \", @class, \" \"), \" $1 \")");
- notSelector = notSelector.replace(/\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/g, attrToXPath);
- xpath = "not(" + notSelector + ")";
- }
- break;
- default:
- xpath = "@" + pseudoClass + "=\"" + pseudoValue + "\"";
- break;
+ clearChildElms();
+ }
}
- return xpath;
- }
- for (var i=0; (currentRule=cssRules[i]); i++) {
- if (i > 0) {
- identical = false;
- for (var x=0, xl=i; x<xl; x++) {
- if (cssRules[i] === cssRules[x]) {
- identical = true;
- break;
- }
+ break;
+ case "empty":
+ for (var m=0; (previous=previousMatch[m]); m++) {
+ if (!previous.childNodes.length) {
+ matchingElms[matchingElms.length] = previous;
}
- if (identical) {
- continue;
+ }
+ break;
+ case "enabled":
+ for (var n=0; (previous=previousMatch[n]); n++) {
+ if (!previous.disabled) {
+ matchingElms[matchingElms.length] = previous;
}
}
- cssSelectors = currentRule.match(selectorSplitRegExp);
- xPathExpression = ".";
- for (var j=0, jl=cssSelectors.length; j<jl; j++) {
- cssSelector = cssSelectorRegExp.exec(cssSelectors[j]);
- splitRule = {
- tag : prefix + ((!cssSelector[1] || cssSelector[3] === "*")? "*" : cssSelector[1]),
- id : (cssSelector[3] !== "*")? cssSelector[2] : null,
- allClasses : cssSelector[4],
- allAttr : cssSelector[6],
- allPseudos : cssSelector[11],
- tagRelation : cssSelector[23]
- };
- if (splitRule.tagRelation) {
- switch (splitRule.tagRelation) {
- case ">":
- xPathExpression += "/child::";
- break;
- case "+":
- xPathExpression += "/following-sibling::*[1]/self::";
- break;
- case "~":
- xPathExpression += "/following-sibling::";
- break;
- }
+ break;
+ case "disabled":
+ for (var o=0; (previous=previousMatch[o]); o++) {
+ if (previous.disabled) {
+ matchingElms[matchingElms.length] = previous;
}
- else {
- xPathExpression += (j > 0 && /(>|\+|~)/.test(cssSelectors[j-1]))? splitRule.tag : ("/descendant::" + splitRule.tag);
+ }
+ break;
+ case "checked":
+ for (var p=0; (previous=previousMatch[p]); p++) {
+ if (previous.checked) {
+ matchingElms[matchingElms.length] = previous;
}
- if (splitRule.id) {
- xPathExpression += "[@id = \"" + splitRule.id.replace(/^#/, "") + "\"]";
+ }
+ break;
+ case "contains":
+ pseudoValue = pseudoValue.replace(/^["'](.*)["']$/, "$1");
+ for (var q=0; (previous=previousMatch[q]); q++) {
+ if (!previous.added) {
+ if (previous.innerText.indexOf(pseudoValue) !== -1) {
+ previous.added = true;
+ matchingElms[matchingElms.length] = previous;
+ }
}
- if (splitRule.allClasses) {
- xPathExpression += splitRule.allClasses.replace(/\.([\w\u00C0-\uFFFF\-_]+)/g, "[contains(concat(\" \", @class, \" \"), \" $1 \")]");
+ }
+ break;
+ case "target":
+ var hash = document.location.hash.slice(1);
+ if (hash) {
+ for (var r=0; (previous=previousMatch[r]); r++) {
+ if (getAttr(previous, "name") === hash || getAttr(previous, "id") === hash) {
+ matchingElms[matchingElms.length] = previous;
+ break;
+ }
}
- if (splitRule.allAttr) {
- xPathExpression += splitRule.allAttr.replace(/(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+|"[^"]*"|'[^']*')?/g, attrToXPath);
+ }
+ break;
+ case "not":
+ if (/^(:\w+[\w\-]*)$/.test(pseudoValue)) {
+ matchingElms = subtractArray(previousMatch, getElementsByPseudo(previousMatch, pseudoValue.slice(1)));
+ }
+ else {
+ pseudoValue = pseudoValue.replace(/^\[#([\w\u00C0-\uFFFF\-\_]+)\]$/, "[id=$1]");
+ var notTag = /^(\w+)/.exec(pseudoValue);
+ var notClass = /^\.([\w\u00C0-\uFFFF\-_]+)/.exec(pseudoValue);
+ var notAttr = /\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/.exec(pseudoValue);
+ var notRegExp = new RegExp("(^|\\s)" + (notTag? notTag[1] : notClass? notClass[1] : "") + "(\\s|$)", "i");
+ if (notAttr) {
+ var notMatchingAttrVal = attrToRegExp(notAttr[3], notAttr[2]);
+ notRegExp = new RegExp(notMatchingAttrVal, "i");
}
- if (splitRule.allPseudos) {
- var pseudoSplitRegExp = /:(\w[\w\-]*)(\(([^\)]+)\))?/;
- splitRule.allPseudos = splitRule.allPseudos.match(/(:\w+[\w\-]*)(\([^\)]+\))?/g);
- for (var k=0, kl=splitRule.allPseudos.length; k<kl; k++) {
- var pseudo = splitRule.allPseudos[k].match(pseudoSplitRegExp);
- var pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null;
- var pseudoValue = pseudo[3]? pseudo[3] : null;
- var xpath = pseudoToXPath(splitRule.tag, pseudoClass, pseudoValue);
- if (xpath.length) {
- xPathExpression += "[" + xpath + "]";
+ for (var s=0, notElm; (notElm=previousMatch[s]); s++) {
+ addElm = null;
+ if (notTag && !notRegExp.test(notElm.nodeName)) {
+ addElm = notElm;
+ }
+ else if (notClass && !notRegExp.test(notElm.className)) {
+ addElm = notElm;
+ }
+ else if (notAttr) {
+ var att = getAttr(notElm, notAttr[1]);
+ if (!att || !notRegExp.test(att)) {
+ addElm = notElm;
}
}
+ if (addElm && !addElm.added) {
+ addElm.added = true;
+ matchingElms[matchingElms.length] = addElm;
+ }
}
}
- var xPathNodes = document.evaluate(xPathExpression, this, nsResolver, 0, null), node;
- while ((node = xPathNodes.iterateNext())) {
- elm.push(node);
+ break;
+ default:
+ for (var t=0; (previous=previousMatch[t]); t++) {
+ if (getAttr(previous, pseudoClass) === pseudoValue) {
+ matchingElms[matchingElms.length] = previous;
+ }
}
- }
- return elm;
- };
+ break;
+ }
+ return matchingElms;
}
- else {
- DOMAssistant.cssSelection = function (cssRule) {
- var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(",");
- var elm = new HTMLArray();
- var prevElm = [], matchingElms = [];
- var prevParents, currentRule, identical, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, regExpClassNames, matchingClassElms, regExpAttributes, matchingAttributeElms, attributeMatchRegExp, current, previous, prevParent, addElm, iteratorNext, childCount, childElm, sequence;
- var childOrSiblingRefRegExp = /^(>|\+|~)$/;
- var cssSelectorRegExp = /^(\w+)?(#[\w\u00C0-\uFFFF\-\_]+|(\*))?((\.[\w\u00C0-\uFFFF\-_]+)*)?((\[\w+(\^|\$|\*|\||~)?(=([\w\u00C0-\uFFFF\s\-\_\.]+|"[^"]*"|'[^']*'))?\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\-?\d*n?((\+|\-)\d+)?|[\w\u00C0-\uFFFF\-_]+|"[^"]*"|'[^']*'|((\w*\.[\w\u00C0-\uFFFF\-_]+)*)?|(\[#?\w+(\^|\$|\*|\||~)?=?[\w\u00C0-\uFFFF\s\-\_\.]+\]+)|(:\w+[\w\-]*))\))?)*)?/;
- var selectorSplitRegExp;
- try {
- selectorSplitRegExp = new RegExp("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]", "g");
- }
- catch (e) {
- selectorSplitRegExp = /[^\s]+/g;
- }
- function clearAdded (elm) {
- elm = elm || prevElm;
- for (var n=0, nl=elm.length; n<nl; n++) {
- elm[n].added = null;
+ for (var a=0; (currentRule=cssRules[a]); a++) {
+ if (a > 0) {
+ identical = false;
+ for (var b=0, bl=a; b<bl; b++) {
+ if (cssRules[a] === cssRules[b]) {
+ identical = true;
+ break;
}
}
- function clearChildElms () {
- for (var n=0, nl=prevParents.length; n<nl; n++) {
- prevParents[n].childElms = null;
- }
+ if (identical) {
+ continue;
}
- function subtractArray (arr1, arr2) {
- for (var i=0, src1; (src1=arr1[i]); i++) {
- var found = false;
- for (var j=0, src2; (src2=arr2[j]); j++) {
- if (src2 === src1) {
- found = true;
- break;
+ }
+ cssSelectors = currentRule.match(selectorSplitRegExp);
+ prevElm = [this];
+ for (var i=0, rule; (rule=cssSelectors[i]); i++) {
+ matchingElms = [];
+ if (i > 0 && childOrSiblingRefRegExp.test(rule)) {
+ childOrSiblingRef = childOrSiblingRefRegExp.exec(rule);
+ if (childOrSiblingRef) {
+ nextTag = /^\w+/.exec(cssSelectors[i+1]);
+ if (nextTag) {
+ nextTag = nextTag[0];
+ nextRegExp = new RegExp("(^|\\s)" + nextTag + "(\\s|$)", "i");
+ }
+ for (var j=0, prevRef; (prevRef=prevElm[j]); j++) {
+ switch (childOrSiblingRef[0]) {
+ case ">":
+ var children = getElementsByTagName(nextTag, prevRef);
+ for (var k=0, child; (child=children[k]); k++) {
+ if (child.parentNode === prevRef) {
+ matchingElms[matchingElms.length] = child;
+ }
+ }
+ break;
+ case "+":
+ while ((prevRef = prevRef.nextSibling) && prevRef.nodeType !== 1) {}
+ if (prevRef) {
+ if (!nextTag || nextRegExp.test(prevRef.nodeName)) {
+ matchingElms[matchingElms.length] = prevRef;
+ }
+ }
+ break;
+ case "~":
+ while ((prevRef = prevRef.nextSibling) && !prevRef.added) {
+ if (!nextTag || nextRegExp.test(prevRef.nodeName)) {
+ prevRef.added = true;
+ matchingElms[matchingElms.length] = prevRef;
+ }
+ }
+ break;
}
}
- if (found) {
- arr1.splice(i--, 1);
+ prevElm = matchingElms;
+ clearAdded();
+ rule = cssSelectors[++i];
+ if (/^\w+$/.test(rule)) {
+ continue;
}
+ prevElm.skipTag = true;
}
- return arr1;
- }
- function getAttr (elm, attr) {
- return isIE? elm[camel[attr.toLowerCase()] || attr] : elm.getAttribute(attr, 2);
}
- function attrToRegExp (attrVal, substrOperator) {
- attrVal = attrVal? attrVal.replace(/^["'](.*)["']$/, "$1").replace(/\./g, "\\.") : null;
- switch (substrOperator) {
- case "^": return "^" + attrVal;
- case "$": return attrVal + "$";
- case "*": return attrVal;
- case "|": return "(^" + attrVal + "(\\-\\w+)*$)";
- case "~": return "\\b" + attrVal + "\\b";
- default: return attrVal? "^" + attrVal + "$" : null;
+ var cssSelector = cssSelectorRegExp.exec(rule);
+ var splitRule = {
+ tag : (!cssSelector[1] || cssSelector[3] === "*")? "*" : cssSelector[1],
+ id : (cssSelector[3] !== "*")? cssSelector[2] : null,
+ allClasses : cssSelector[4],
+ allAttr : cssSelector[6],
+ allPseudos : cssSelector[11]
+ };
+ if (splitRule.id) {
+ var DOMElm = document.getElementById(splitRule.id.replace(/#/, ""));
+ if (DOMElm) {
+ matchingElms = [DOMElm];
}
+ prevElm = matchingElms;
}
- function getElementsByTagName (tag, parent) {
- tag = tag || "*";
- parent = parent || document;
- if (parent === document || parent.lastModified) {
- if (!cachedElms[tag]) {
- cachedElms[tag] = isIE? ((tag === "*")? document.all : document.all.tags(tag)) : document.getElementsByTagName(tag);
+ else if (splitRule.tag && !prevElm.skipTag) {
+ if (i===0 && !matchingElms.length && prevElm.length === 1) {
+ prevElm = matchingElms = pushAll([], getElementsByTagName(splitRule.tag, prevElm[0]));
+ }
+ else {
+ for (var l=0, ll=prevElm.length, tagCollectionMatches, tagMatch; l<ll; l++) {
+ tagCollectionMatches = getElementsByTagName(splitRule.tag, prevElm[l]);
+ for (var m=0; (tagMatch=tagCollectionMatches[m]); m++) {
+ if (!tagMatch.added) {
+ tagMatch.added = true;
+ matchingElms[matchingElms.length] = tagMatch;
+ }
+ }
}
- return cachedElms[tag];
+ prevElm = matchingElms;
+ clearAdded();
}
- return isIE? ((tag === "*")? parent.all : parent.all.tags(tag)) : parent.getElementsByTagName(tag);
}
- function getElementsByPseudo (previousMatch, pseudoClass, pseudoValue) {
- prevParents = [];
- var pseudo = pseudoClass.split("-"), matchingElms = [], checkNodeName;
- var prop = (checkNodeName = /\-of\-type$/.test(pseudoClass))? "nodeName" : "nodeType";
- function getPrevElm(elm) {
- var val = checkNodeName? elm.nodeName : 1;
- while ((elm = elm.previousSibling) && elm[prop] !== val) {}
- return elm;
- }
- function getNextElm(elm) {
- var val = checkNodeName? elm.nodeName : 1;
- while ((elm = elm.nextSibling) && elm[prop] !== val) {}
- return elm;
+ if (!matchingElms.length) {
+ break;
+ }
+ prevElm.skipTag = false;
+ if (splitRule.allClasses) {
+ var allClasses = splitRule.allClasses.replace(/^\./, "").split(".");
+ regExpClassNames = [];
+ for (var n=0, nl=allClasses.length; n<nl; n++) {
+ regExpClassNames[n] = new RegExp("(^|\\s)" + allClasses[n] + "(\\s|$)");
}
- switch (pseudo[0]) {
- case "first":
- for (var i=0; (previous=previousMatch[i]); i++) {
- if (!getPrevElm(previous)) {
- matchingElms[matchingElms.length] = previous;
- }
- }
- break;
- case "last":
- for (var j=0; (previous=previousMatch[j]); j++) {
- if (!getNextElm(previous)) {
- matchingElms[matchingElms.length] = previous;
- }
- }
- break;
- case "only":
- for (var k=0, kParent; (previous=previousMatch[k]); k++) {
- prevParent = previous.parentNode;
- if (prevParent !== kParent) {
- if (!getPrevElm(previous) && !getNextElm(previous)) {
- matchingElms[matchingElms.length] = previous;
- }
- kParent = prevParent;
- }
- }
- break;
- case "nth":
- if (/^n$/.test(pseudoValue)) {
- matchingElms = previousMatch;
- }
- else {
- var direction = (pseudo[1] === "last")? ["lastChild", "previousSibling"] : ["firstChild", "nextSibling"];
- sequence = getSequence(pseudoValue);
- if (sequence) {
- for (var l=0; (previous=previousMatch[l]); l++) {
- prevParent = previous.parentNode;
- if (!prevParent.childElms) {
- iteratorNext = sequence.start;
- childCount = 0;
- childElm = prevParent[direction[0]];
- while (childElm && (sequence.max < 0 || iteratorNext <= sequence.max)) {
- if (checkNodeName) {
- if (childElm.nodeName === previous.nodeName) {
- if (++childCount === iteratorNext) {
- matchingElms[matchingElms.length] = childElm;
- iteratorNext += sequence.add;
- }
- }
- }
- else {
- if (childElm.nodeType === 1) {
- if (++childCount === iteratorNext) {
- if (childElm.nodeName === previous.nodeName) {
- matchingElms[matchingElms.length] = childElm;
- }
- iteratorNext += sequence.add;
- }
- }
- }
- childElm = childElm[direction[1]];
- }
- prevParent.childElms = true;
- prevParents[prevParents.length] = prevParent;
- }
- }
- clearChildElms();
- }
- }
- break;
- case "empty":
- for (var m=0; (previous=previousMatch[m]); m++) {
- if (!previous.childNodes.length) {
- matchingElms[matchingElms.length] = previous;
- }
- }
- break;
- case "enabled":
- for (var n=0; (previous=previousMatch[n]); n++) {
- if (!previous.disabled) {
- matchingElms[matchingElms.length] = previous;
- }
- }
- break;
- case "disabled":
- for (var o=0; (previous=previousMatch[o]); o++) {
- if (previous.disabled) {
- matchingElms[matchingElms.length] = previous;
- }
- }
- break;
- case "checked":
- for (var p=0; (previous=previousMatch[p]); p++) {
- if (previous.checked) {
- matchingElms[matchingElms.length] = previous;
- }
- }
- break;
- case "contains":
- pseudoValue = pseudoValue.replace(/^["'](.*)["']$/, "$1");
- for (var q=0; (previous=previousMatch[q]); q++) {
- if (!previous.added) {
- if (previous.innerText.indexOf(pseudoValue) !== -1) {
- previous.added = true;
- matchingElms[matchingElms.length] = previous;
- }
- }
- }
- break;
- case "target":
- var hash = document.location.hash.slice(1);
- if (hash) {
- for (var r=0; (previous=previousMatch[r]); r++) {
- if (getAttr(previous, "name") === hash || getAttr(previous, "id") === hash) {
- matchingElms[matchingElms.length] = previous;
- break;
- }
- }
- }
- break;
- case "not":
- if (/^(:\w+[\w\-]*)$/.test(pseudoValue)) {
- matchingElms = subtractArray(previousMatch, getElementsByPseudo(previousMatch, pseudoValue.slice(1)));
- }
- else {
- pseudoValue = pseudoValue.replace(/^\[#([\w\u00C0-\uFFFF\-\_]+)\]$/, "[id=$1]");
- var notTag = /^(\w+)/.exec(pseudoValue);
- var notClass = /^\.([\w\u00C0-\uFFFF\-_]+)/.exec(pseudoValue);
- var notAttr = /\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/.exec(pseudoValue);
- var notRegExp = new RegExp("(^|\\s)" + (notTag? notTag[1] : notClass? notClass[1] : "") + "(\\s|$)", "i");
- if (notAttr) {
- var notMatchingAttrVal = attrToRegExp(notAttr[3], notAttr[2]);
- notRegExp = new RegExp(notMatchingAttrVal, "i");
- }
- for (var s=0, notElm; (notElm=previousMatch[s]); s++) {
- addElm = null;
- if (notTag && !notRegExp.test(notElm.nodeName)) {
- addElm = notElm;
- }
- else if (notClass && !notRegExp.test(notElm.className)) {
- addElm = notElm;
- }
- else if (notAttr) {
- var att = getAttr(notElm, notAttr[1]);
- if (!att || !notRegExp.test(att)) {
- addElm = notElm;
- }
- }
- if (addElm && !addElm.added) {
- addElm.added = true;
- matchingElms[matchingElms.length] = addElm;
- }
+ matchingClassElms = [];
+ for (var o=0, elmClass; (current=prevElm[o]); o++) {
+ elmClass = current.className;
+ if (elmClass && !current.added) {
+ addElm = false;
+ for (var p=0, pl=regExpClassNames.length; p<pl; p++) {
+ addElm = regExpClassNames[p].test(elmClass);
+ if (!addElm) {
+ break;
}
}
- break;
- default:
- for (var t=0; (previous=previousMatch[t]); t++) {
- if (getAttr(previous, pseudoClass) === pseudoValue) {
- matchingElms[matchingElms.length] = previous;
- }
+ if (addElm) {
+ current.added = true;
+ matchingClassElms[matchingClassElms.length] = current;
}
- break;
+ }
}
- return matchingElms;
+ clearAdded();
+ prevElm = matchingElms = matchingClassElms;
}
- for (var a=0; (currentRule=cssRules[a]); a++) {
- if (a > 0) {
- identical = false;
- for (var b=0, bl=a; b<bl; b++) {
- if (cssRules[a] === cssRules[b]) {
- identical = true;
+ if (splitRule.allAttr) {
+ var allAttr = splitRule.allAttr.match(/\[[^\]]+\]/g);
+ regExpAttributes = [];
+ attributeMatchRegExp = /(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+|"[^"]*"|'[^']*')?/;
+ for (var q=0, ql=allAttr.length, attributeMatch, attrVal; q<ql; q++) {
+ attributeMatch = attributeMatchRegExp.exec(allAttr[q]);
+ attrVal = attrToRegExp(attributeMatch[3], (attributeMatch[2] || null));
+ regExpAttributes[q] = [(attrVal? new RegExp(attrVal) : null), attributeMatch[1]];
+ }
+ matchingAttributeElms = [];
+ for (var r=0, currentAttr; (current=matchingElms[r]); r++) {
+ for (var s=0, sl=regExpAttributes.length, attributeRegExp; s<sl; s++) {
+ addElm = false;
+ attributeRegExp = regExpAttributes[s][0];
+ currentAttr = getAttr(current, regExpAttributes[s][1]);
+ if (typeof currentAttr === "string" && currentAttr.length) {
+ if (!attributeRegExp || typeof attributeRegExp === "undefined" || (attributeRegExp && attributeRegExp.test(currentAttr))) {
+ addElm = true;
+ }
+ }
+ if (!addElm) {
break;
}
}
- if (identical) {
- continue;
+ if (addElm) {
+ matchingAttributeElms[matchingAttributeElms.length] = current;
}
}
- cssSelectors = currentRule.match(selectorSplitRegExp);
- prevElm = [this];
- for (var i=0, rule; (rule=cssSelectors[i]); i++) {
- matchingElms = [];
- if (i > 0 && childOrSiblingRefRegExp.test(rule)) {
- childOrSiblingRef = childOrSiblingRefRegExp.exec(rule);
- if (childOrSiblingRef) {
- nextTag = /^\w+/.exec(cssSelectors[i+1]);
- if (nextTag) {
- nextTag = nextTag[0];
- nextRegExp = new RegExp("(^|\\s)" + nextTag + "(\\s|$)", "i");
- }
- for (var j=0, prevRef; (prevRef=prevElm[j]); j++) {
- switch (childOrSiblingRef[0]) {
- case ">":
- var children = getElementsByTagName(nextTag, prevRef);
- for (var k=0, child; (child=children[k]); k++) {
- if (child.parentNode === prevRef) {
- matchingElms[matchingElms.length] = child;
- }
- }
- break;
- case "+":
- while ((prevRef = prevRef.nextSibling) && prevRef.nodeType !== 1) {}
- if (prevRef) {
- if (!nextTag || nextRegExp.test(prevRef.nodeName)) {
- matchingElms[matchingElms.length] = prevRef;
- }
- }
- break;
- case "~":
- while ((prevRef = prevRef.nextSibling) && !prevRef.added) {
- if (!nextTag || nextRegExp.test(prevRef.nodeName)) {
- prevRef.added = true;
- matchingElms[matchingElms.length] = prevRef;
- }
- }
- break;
- }
+ prevElm = matchingElms = matchingAttributeElms;
+ }
+ if (splitRule.allPseudos) {
+ var pseudoSplitRegExp = /:(\w[\w\-]*)(\(([^\)]+)\))?/;
+ var allPseudos = splitRule.allPseudos.match(/(:\w+[\w\-]*)(\([^\)]+\))?/g);
+ for (var t=0, tl=allPseudos.length; t<tl; t++) {
+ var pseudo = allPseudos[t].match(pseudoSplitRegExp);
+ var pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null;
+ var pseudoValue = pseudo[3]? pseudo[3] : null;
+ matchingElms = getElementsByPseudo(matchingElms, pseudoClass, pseudoValue);
+ clearAdded(matchingElms);
+ }
+ prevElm = matchingElms;
+ }
+ }
+ elm = pushAll(elm, prevElm);
+ }
+ return elm;
+ },
+
+ cssByXpath : function (cssRule) {
+ var ns = { xhtml: "http://www.w3.org/1999/xhtml" };
+ var prefix = (document.documentElement.namespaceURI === ns.xhtml)? "xhtml:" : "";
+ var nsResolver = function lookupNamespaceURI (prefix) {
+ return ns[prefix] || null;
+ };
+ DOMAssistant.cssByXpath = function (cssRule) {
+ if (/:checked/.test(cssRule)) {
+ return DOMAssistant.cssByDOM.call(this, cssRule);
+ }
+ var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(",");
+ var elm = new HTMLArray();
+ var currentRule, identical, cssSelectors, xPathExpression, cssSelector, splitRule, sequence;
+ var cssSelectorRegExp = /^(\w+)?(#[\w\u00C0-\uFFFF\-\_]+|(\*))?((\.[\w\u00C0-\uFFFF\-_]+)*)?((\[\w+(\^|\$|\*|\||~)?(=([\w\u00C0-\uFFFF\s\-\_\.]+|"[^"]*"|'[^']*'))?\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\-?\d*n?((\+|\-)\d+)?|[\w\u00C0-\uFFFF\-_\.]+|"[^"]*"|'[^']*'|((\w*\.[\w\u00C0-\uFFFF\-_]+)*)?|(\[#?\w+(\^|\$|\*|\||~)?=?[\w\u00C0-\uFFFF\s\-\_\.]+\]+)|(:\w+[\w\-]*))\))?)*)?(>|\+|~)?/;
+ var selectorSplitRegExp = new RegExp("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]", "g");
+ function attrToXPath (match, p1, p2, p3) {
+ p3 = p3? p3.replace(/^["'](.*)["']$/, "$1") : p3;
+ switch (p2) {
+ case "^": return "starts-with(@" + p1 + ", \"" + p3 + "\")";
+ case "$": return "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p3.length - 1) + "), " + p3.length + ") = \"" + p3 + "\"";
+ case "*": return "contains(concat(\" \", @" + p1 + ", \" \"), \"" + p3 + "\")";
+ case "|": return "(@" + p1 + "=\"" + p3 + "\" or starts-with(@" + p1 + ", \"" + p3 + "-\"))";
+ case "~": return "contains(concat(\" \", @" + p1 + ", \" \"), \" " + p3 + " \")";
+ default: return "@" + p1 + (p3? "=\"" + p3 + "\"" : "");
+ }
+ }
+ function pseudoToXPath (tag, pseudoClass, pseudoValue) {
+ tag = /\-child$/.test(pseudoClass)? "*" : tag;
+ var xpath = "", pseudo = pseudoClass.split("-");
+ switch (pseudo[0]) {
+ case "first":
+ xpath = "not(preceding-sibling::" + tag + ")";
+ break;
+ case "last":
+ xpath = "not(following-sibling::" + tag + ")";
+ break;
+ case "only":
+ xpath = "not(preceding-sibling::" + tag + " or following-sibling::" + tag + ")";
+ break;
+ case "nth":
+ if (!/^n$/.test(pseudoValue)) {
+ var position = ((pseudo[1] === "last")? "(count(following-sibling::" : "(count(preceding-sibling::") + tag + ") + 1)";
+ sequence = DOMAssistant.getSequence.call(this, pseudoValue);
+ if (sequence) {
+ if (sequence.start === sequence.max) {
+ xpath = position + " = " + sequence.start;
}
- prevElm = matchingElms;
- clearAdded();
- rule = cssSelectors[++i];
- if (/^\w+$/.test(rule)) {
- continue;
+ else {
+ xpath = position + " mod " + sequence.add + " = " + sequence.modVal + ((sequence.start > 1)? " and " + position + " >= " + sequence.start : "") + ((sequence.max > 0)? " and " + position + " <= " + sequence.max: "");
}
- prevElm.skipTag = true;
}
}
- var cssSelector = cssSelectorRegExp.exec(rule);
- var splitRule = {
- tag : (!cssSelector[1] || cssSelector[3] === "*")? "*" : cssSelector[1],
- id : (cssSelector[3] !== "*")? cssSelector[2] : null,
- allClasses : cssSelector[4],
- allAttr : cssSelector[6],
- allPseudos : cssSelector[11]
- };
- if (splitRule.id) {
- var DOMElm = document.getElementById(splitRule.id.replace(/#/, ""));
- if (DOMElm) {
- matchingElms = [DOMElm];
- }
- prevElm = matchingElms;
+ break;
+ case "empty":
+ xpath = "count(child::*) = 0 and string-length(text()) = 0";
+ break;
+ case "contains":
+ xpath = "contains(., \"" + pseudoValue.replace(/^["'](.*)["']$/, "$1") + "\")";
+ break;
+ case "enabled":
+ xpath = "not(@disabled)";
+ break;
+ case "disabled":
+ xpath = "@disabled";
+ break;
+ case "target":
+ var hash = document.location.hash.slice(1);
+ xpath = "@name=\"" + hash + "\" or @id=\"" + hash + "\"";
+ break;
+ case "not":
+ if (/^(:\w+[\w\-]*)$/.test(pseudoValue)) {
+ xpath = "not(" + pseudoToXPath(tag, pseudoValue.slice(1)) + ")";
}
- else if (splitRule.tag && !prevElm.skipTag) {
- if (i===0 && !matchingElms.length && prevElm.length === 1) {
- prevElm = matchingElms = pushAll([], getElementsByTagName(splitRule.tag, prevElm[0]));
- }
- else {
- for (var l=0, ll=prevElm.length, tagCollectionMatches, tagMatch; l<ll; l++) {
- tagCollectionMatches = getElementsByTagName(splitRule.tag, prevElm[l]);
- for (var m=0; (tagMatch=tagCollectionMatches[m]); m++) {
- if (!tagMatch.added) {
- tagMatch.added = true;
- matchingElms[matchingElms.length] = tagMatch;
- }
- }
- }
- prevElm = matchingElms;
- clearAdded();
- }
+ else {
+ pseudoValue = pseudoValue.replace(/^\[#([\w\u00C0-\uFFFF\-\_]+)\]$/, "[id=$1]");
+ var notSelector = pseudoValue.replace(/^(\w+)/, "self::$1");
+ notSelector = notSelector.replace(/^\.([\w\u00C0-\uFFFF\-_]+)/g, "contains(concat(\" \", @class, \" \"), \" $1 \")");
+ notSelector = notSelector.replace(/\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/g, attrToXPath);
+ xpath = "not(" + notSelector + ")";
}
- if (!matchingElms.length) {
+ break;
+ default:
+ xpath = "@" + pseudoClass + "=\"" + pseudoValue + "\"";
+ break;
+ }
+ return xpath;
+ }
+ for (var i=0; (currentRule=cssRules[i]); i++) {
+ if (i > 0) {
+ identical = false;
+ for (var x=0, xl=i; x<xl; x++) {
+ if (cssRules[i] === cssRules[x]) {
+ identical = true;
break;
}
- prevElm.skipTag = false;
- if (splitRule.allClasses) {
- splitRule.allClasses = splitRule.allClasses.replace(/^\./, "").split(".");
- regExpClassNames = [];
- for (var n=0, nl=splitRule.allClasses.length; n<nl; n++) {
- regExpClassNames[regExpClassNames.length] = new RegExp("(^|\\s)" + splitRule.allClasses[n] + "(\\s|$)");
- }
- matchingClassElms = [];
- for (var o=0, elmClass; (current=prevElm[o]); o++) {
- elmClass = current.className;
- if (elmClass && !current.added) {
- addElm = false;
- for (var p=0, pl=regExpClassNames.length; p<pl; p++) {
- addElm = regExpClassNames[p].test(elmClass);
- if (!addElm) {
- break;
- }
- }
- if (addElm) {
- current.added = true;
- matchingClassElms[matchingClassElms.length] = current;
- }
- }
- }
- clearAdded();
- prevElm = matchingElms = matchingClassElms;
- }
- if (splitRule.allAttr) {
- splitRule.allAttr = splitRule.allAttr.match(/\[[^\]]+\]/g);
- regExpAttributes = [];
- attributeMatchRegExp = /(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+|"[^"]*"|'[^']*')?/;
- for (var q=0, ql=splitRule.allAttr.length, attributeMatch, attrVal; q<ql; q++) {
- attributeMatch = attributeMatchRegExp.exec(splitRule.allAttr[q]);
- attrVal = attrToRegExp(attributeMatch[3], (attributeMatch[2] || null));
- regExpAttributes[regExpAttributes.length] = [(attrVal? new RegExp(attrVal) : null), attributeMatch[1]];
- }
- matchingAttributeElms = [];
- for (var r=0, currentAttr; (current=matchingElms[r]); r++) {
- for (var s=0, sl=regExpAttributes.length, attributeRegExp; s<sl; s++) {
- addElm = false;
- attributeRegExp = regExpAttributes[s][0];
- currentAttr = getAttr(current, regExpAttributes[s][1]);
- if (typeof currentAttr === "string" && currentAttr.length) {
- if (!attributeRegExp || typeof attributeRegExp === "undefined" || (attributeRegExp && attributeRegExp.test(currentAttr))) {
- addElm = true;
- }
- }
- if (!addElm) {
- break;
- }
- }
- if (addElm) {
- matchingAttributeElms[matchingAttributeElms.length] = current;
- }
- }
- prevElm = matchingElms = matchingAttributeElms;
+ }
+ if (identical) {
+ continue;
+ }
+ }
+ cssSelectors = currentRule.match(selectorSplitRegExp);
+ xPathExpression = ".";
+ for (var j=0, jl=cssSelectors.length; j<jl; j++) {
+ cssSelector = cssSelectorRegExp.exec(cssSelectors[j]);
+ splitRule = {
+ tag : prefix + ((!cssSelector[1] || cssSelector[3] === "*")? "*" : cssSelector[1]),
+ id : (cssSelector[3] !== "*")? cssSelector[2] : null,
+ allClasses : cssSelector[4],
+ allAttr : cssSelector[6],
+ allPseudos : cssSelector[11],
+ tagRelation : cssSelector[23]
+ };
+ if (splitRule.tagRelation) {
+ switch (splitRule.tagRelation) {
+ case ">":
+ xPathExpression += "/child::";
+ break;
+ case "+":
+ xPathExpression += "/following-sibling::*[1]/self::";
+ break;
+ case "~":
+ xPathExpression += "/following-sibling::";
+ break;
}
- if (splitRule.allPseudos) {
- var pseudoSplitRegExp = /:(\w[\w\-]*)(\(([^\)]+)\))?/;
- splitRule.allPseudos = splitRule.allPseudos.match(/(:\w+[\w\-]*)(\([^\)]+\))?/g);
- for (var t=0, tl=splitRule.allPseudos.length; t<tl; t++) {
- var pseudo = splitRule.allPseudos[t].match(pseudoSplitRegExp);
- var pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null;
- var pseudoValue = pseudo[3]? pseudo[3] : null;
- matchingElms = getElementsByPseudo(matchingElms, pseudoClass, pseudoValue);
- clearAdded(matchingElms);
+ }
+ 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\u00C0-\uFFFF\-_]+)/g, "[contains(concat(\" \", @class, \" \"), \" $1 \")]");
+ }
+ if (splitRule.allAttr) {
+ xPathExpression += splitRule.allAttr.replace(/(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+|"[^"]*"|'[^']*')?/g, attrToXPath);
+ }
+ if (splitRule.allPseudos) {
+ var pseudoSplitRegExp = /:(\w[\w\-]*)(\(([^\)]+)\))?/;
+ var allPseudos = splitRule.allPseudos.match(/(:\w+[\w\-]*)(\([^\)]+\))?/g);
+ for (var k=0, kl=allPseudos.length; k<kl; k++) {
+ var pseudo = allPseudos[k].match(pseudoSplitRegExp);
+ var pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null;
+ var pseudoValue = pseudo[3]? pseudo[3] : null;
+ var xpath = pseudoToXPath(splitRule.tag, pseudoClass, pseudoValue);
+ if (xpath.length) {
+ xPathExpression += "[" + xpath + "]";
}
- prevElm = matchingElms;
}
}
- elm = pushAll(elm, prevElm);
}
- return elm;
- };
- }
+ var xPathNodes = document.evaluate(xPathExpression, this, nsResolver, 0, null), node;
+ while ((node = xPathNodes.iterateNext())) {
+ elm.push(node);
+ }
+ }
+ return elm;
+ };
+ return DOMAssistant.cssByXpath.call(this, cssRule);
+ },
+
+ cssSelection : function (cssRule) {
+ DOMAssistant.cssSelection = document.evaluate? DOMAssistant.cssByXpath : DOMAssistant.cssByDOM;
if (document.querySelectorAll) {
var cssSelectionBackup = DOMAssistant.cssSelection;
DOMAssistant.cssSelection = function (cssRule) {
@@ -794,27 +797,27 @@ var DOMAssistant = function () {
}
};
}
- return DOMAssistant.cssSelection.call(this, cssRule);
+ return DOMAssistant.cssSelection.call(this, cssRule);
},
cssSelect : function (cssRule) {
return DOMAssistant.cssSelection.call(this, cssRule);
},
-
+
elmsByClass : function (className, tag) {
var cssRule = (tag || "") + "." + className;
return DOMAssistant.cssSelection.call(this, cssRule);
},
-
+
elmsByAttribute : function (attr, attrVal, tag, substrMatchSelector) {
var cssRule = (tag || "") + "[" + attr + ((attrVal && attrVal !== "*")? ((substrMatchSelector || "") + "=" + attrVal + "]") : "]");
return DOMAssistant.cssSelection.call(this, cssRule);
},
-
+
elmsByTag : function (tag) {
return DOMAssistant.cssSelection.call(this, tag);
}
- };
+ };
}();
DOMAssistant.initCore();
DOMAssistant.AJAX = function () {
@@ -830,7 +833,7 @@ DOMAssistant.AJAX = function () {
url = url[0];
}
return {
- url: url,
+ url : url,
method : method,
callback : callback,
params : params,
@@ -859,7 +862,7 @@ DOMAssistant.AJAX = function () {
else if (typeof window.ActiveXObject !== "undefined") {
var XMLHttpMS = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
for (var i=0; i<XMLHttpMS.length; i++) {
- try {
+ try {
XMLHttp = new window.ActiveXObject(XMLHttpMS[i]);
DOMAssistant.AJAX.initRequest = function () {
return new window.ActiveXObject(XMLHttpMS[i]);
@@ -928,7 +931,7 @@ DOMAssistant.AJAX = function () {
if (typeof callback === "function") {
XMLHttp.onreadystatechange = function () {
if (XMLHttp.readyState === 4) {
- var response = (/xml/i.test(responseType))? XMLHttp.responseXML : XMLHttp.responseText;
+ var response = /xml/i.test(responseType)? XMLHttp.responseXML : XMLHttp.responseText;
callback.call(elm, response, addToContent);
readyState = 4;
status = XMLHttp.status;
@@ -939,7 +942,7 @@ DOMAssistant.AJAX = function () {
};
}
XMLHttp.send(params);
- }(this);
+ }(this);
}
return this;
},
@@ -1121,7 +1124,7 @@ DOMAssistant.Content = function () {
}
else {
this.setAttribute(i, attr[i]);
- }
+ }
}
return this;
};
@@ -1130,16 +1133,17 @@ DOMAssistant.Content = function () {
},
addContent : function (content) {
- if (typeof content === "string" || typeof content === "number") {
+ var type = typeof content;
+ if (type === "string" || type === "number") {
this.innerHTML += content;
}
- else if ((typeof content === "object") || (typeof content === "function" && typeof content.nodeName !== "undefined")) {
+ else if (type === "object" || (type === "function" && typeof content.nodeName !== "undefined")) {
this.appendChild(content);
}
return this;
},
- replaceContent : function (newContent) {
+ replaceContent : function (content) {
var children = this.all || this.getElementsByTagName("*");
for (var i=0, child, attr; (child=children[i]); i++) {
attr = child.attributes;
@@ -1155,10 +1159,27 @@ DOMAssistant.Content = function () {
while (this.hasChildNodes()) {
this.removeChild(this.firstChild);
}
- DOMAssistant.$(this).addContent(newContent);
+ DOMAssistant.$(this).addContent(content);
return this;
},
+ replace : function (content, returnNew) {
+ var type = typeof content;
+ if (type === "string" || type === "number") {
+ var parent = this.parentNode;
+ var tmp = DOMAssistant.$(parent).create("div", null, false, content);
+ for (var i=tmp.childNodes.length-1; i>=0; i--) {
+ parent.insertBefore(tmp.childNodes[i], this.nextSibling);
+ }
+ content = this.nextSibling;
+ parent.removeChild(this);
+ }
+ else if (type === "object" || (type === "function" && typeof content.nodeName !== "undefined")) {
+ this.parentNode.replaceChild(content, this);
+ }
+ return returnNew? content : this;
+ },
+
remove : function () {
this.parentNode.removeChild(this);
return null;
@@ -1170,6 +1191,7 @@ DOMAssistant.Events = function () {
var uniqueHandlerId = 1;
return {
publicMethods : [
+ "triggerEvent",
"addEvent",
"removeEvent",
"preventDefault",
@@ -1183,8 +1205,28 @@ DOMAssistant.Events = function () {
DOMAssistant.cancelBubble = this.cancelBubble;
},
+ triggerEvent : function (evt, target) {
+ if (this.events && this.events[evt]) {
+ // Create synthetic event
+ var event = {
+ type: evt,
+ target: target || this,
+ currentTarget: this,
+ bubbles: false,
+ cancelable: false,
+ preventDefault: function(){},
+ stopPropagation: function(){},
+ timeStamp: +new Date()
+ };
+ for (var i=0, iL=this.events[evt].length; i<iL; i++) {
+ this.events[evt][i].call(this, event);
+ }
+ }
+ return this;
+ },
+
addEvent : function (evt, func) {
- var XULEvent = (/^DOM/.test(evt));
+ var XULEvent = /^DOM/.test(evt);
if (XULEvent) {
if (this.addEventListener) {
this.addEventListener(evt, func, false);
@@ -1194,11 +1236,7 @@ DOMAssistant.Events = function () {
if (!this.uniqueHandlerId) {
this.uniqueHandlerId = uniqueHandlerId++;
}
- var alreadyExists = false;
- if (func.attachedElements && func.attachedElements[evt + this.uniqueHandlerId]) {
- alreadyExists = true;
- }
- if (!alreadyExists) {
+ if (!(func.attachedElements && func.attachedElements[evt + this.uniqueHandlerId])) {
if (!this.events) {
this.events = {};
}
@@ -1208,7 +1246,7 @@ DOMAssistant.Events = function () {
if (existingEvent) {
this.events[evt].push(existingEvent);
}
- }
+ }
this.events[evt].push(func);
this["on" + evt] = DOMAssistant.Events.handleEvent;
if (typeof this.window === "object") {
@@ -1228,7 +1266,7 @@ DOMAssistant.Events = function () {
var currentTarget = currentEvt.target || currentEvt.srcElement || document;
while (currentTarget.nodeType !== 1 && currentTarget.parentNode) {
currentTarget = currentTarget.parentNode;
- }
+ }
currentEvt.eventTarget = currentTarget;
var eventColl = this.events[currentEvt.type].slice(0);
var eventCollLength = eventColl.length - 1;
View
2,066 speed/frameworks/mootools.js
@@ -6,7 +6,7 @@ License:
MIT-style license.
Copyright:
- Copyright (c) 2006-2007 [Valerio Proietti](http://mad4milk.net/).
+ Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/).
Code & Documentation:
[The MooTools production team](http://mootools.net/developers/).
@@ -17,22 +17,21 @@ Inspiration:
*/
var MooTools = {
- 'version': '1.2.0',
- 'build': ''
+ 'version': '1.2.1',
+ 'build': '0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf'
};
-
+
var Native = function(options){
options = options || {};
-
- var afterImplement = options.afterImplement || function(){};
- var generics = options.generics;
- generics = (generics !== false);
+ var name = options.name;
var legacy = options.legacy;
- var initialize = options.initialize;
var protect = options.protect;
- var name = options.name;
-
+ var methods = options.implement;
+ var generics = options.generics;
+ var initialize = options.initialize;
+ var afterImplement = options.afterImplement || function(){};
var object = initialize || legacy;
+ generics = generics !== false;
object.constructor = Native;
object.$family = {name: 'native'};
@@ -51,28 +50,24 @@ var Native = function(options){
afterImplement.call(obj, name, method);
return obj;
};
-
- object.implement = function(a1, a2, a3){
- if (typeof a1 == 'string') return add(this, a1, a2, a3);
- for (var p in a1) add(this, p, a1[p], a2);
- return this;
- };
-
+
object.alias = function(a1, a2, a3){
if (typeof a1 == 'string'){
- a1 = this.prototype[a1];
- if (a1) add(this, a2, a1, a3);
- } else {
- for (var a in a1) this.alias(a, a1[a], a2);
+ if ((a1 = this.prototype[a1])) return add(this, a2, a1, a3);
}
+ for (var a in a1) this.alias(a, a1[a], a2);
return this;
};
- return object;
-};
+ object.implement = function(a1, a2, a3){
+ if (typeof a1 == 'string') return add(this, a1, a2, a3);
+ for (var p in a1) add(this, p, a1[p], a2);
+ return this;
+ };
-Native.implement = function(objects, properties){
- for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties);
+ if (methods) object.implement(methods);
+
+ return object;
};
Native.genericize = function(object, property, check){
@@ -82,30 +77,96 @@ Native.genericize = function(object, property, check){
};
};
+Native.implement = function(objects, properties){
+ for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties);
+};
+
Native.typize = function(object, family){
if (!object.type) object.type = function(item){
return ($type(item) === family);
};
};
-Native.alias = function(objects, a1, a2, a3){
- for (var i = 0, j = objects.length; i < j; i++) objects[i].alias(a1, a2, a3);
-};
+(function(){
+ var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Number': Number, 'RegExp': RegExp, 'String': String};
+ for (var n in natives) new Native({name: n, initialize: natives[n], protect: true});
+
+ var types = {'boolean': Boolean, 'native': Native, 'object': Object};
+ for (var t in types) Native.typize(types[t], t);
+
+ var generics = {
+ 'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"],
+ 'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"]
+ };
+ for (var g in generics){
+ for (var i = generics[g].length; i--;) Native.genericize(window[g], generics[g][i], true);
+ };
+})();
+
+var Hash = new Native({
+
+ name: 'Hash',
+
+ initialize: function(object){
+ if ($type(object) == 'hash') object = $unlink(object.getClean());
+ for (var key in object) this[key] = object[key];
+ return this;
+ }
+
+});
+
+Hash.implement({
+
+ forEach: function(fn, bind){
+ for (var key in this){
+ if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
+ }
+ },
+
+ getClean: function(){
+ var clean = {};
+ for (var key in this){
+ if (this.hasOwnProperty(key)) clean[key] = this[key];
+ }
+ return clean;
+ },
+
+ getLength: function(){
+ var length = 0;
+ for (var key in this){
+ if (this.hasOwnProperty(key)) length++;
+ }
+ return length;
+ }
+
+});
+
+Hash.alias('forEach', 'each');
-(function(objects){
- for (var name in objects) Native.typize(objects[name], name);
-})({'boolean': Boolean, 'native': Native, 'object': Object});
+Array.implement({
+
+ forEach: function(fn, bind){
+ for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
+ }
+
+});
+
+Array.alias('forEach', 'each');
-(function(objects){
- for (var name in objects) new Native({name: name, initialize: objects[name], protect: true});
-})({'String': String, 'Function': Function, 'Number': Number, 'Array': Array, 'RegExp': RegExp, 'Date': Date});
+function $A(iterable){
+ if (iterable.item){
+ var array = [];
+ for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
+ return array;
+ }
+ return Array.prototype.slice.call(iterable);
+};
-(function(object, methods){
- for (var i = methods.length; i--; i) Native.genericize(object, methods[i], true);
- return arguments.callee;
-})
-(Array, ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 'toString', 'valueOf', 'indexOf', 'lastIndexOf'])
-(String, ['charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'replace', 'search', 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase', 'valueOf']);
+function $arguments(i){
+ return function(){
+ return arguments[i];
+ };
+};
function $chk(obj){
return !!(obj || obj === 0);
@@ -121,44 +182,26 @@ function $defined(obj){
return (obj != undefined);
};
-function $empty(){};
-
-function $arguments(i){
- return function(){
- return arguments[i];
- };
+function $each(iterable, fn, bind){
+ var type = $type(iterable);
+ ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind);
};
-function $lambda(value){
- return (typeof value == 'function') ? value : function(){
- return value;
- };
-};
+function $empty(){};
function $extend(original, extended){
for (var key in (extended || {})) original[key] = extended[key];
return original;
};
-function $unlink(object){
- var unlinked;
-
- switch ($type(object)){
- case 'object':
- unlinked = {};
- for (var p in object) unlinked[p] = $unlink(object[p]);
- break;
- case 'hash':
- unlinked = $unlink(object.getClean());
- break;
- case 'array':
- unlinked = [];
- for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
- break;
- default: return object;
- }
-
- return unlinked;
+function $H(object){
+ return new Hash(object);
+};
+
+function $lambda(value){
+ return (typeof value == 'function') ? value : function(){
+ return value;
+ };
};
function $merge(){
@@ -191,7 +234,7 @@ function $splat(obj){
};
var $time = Date.now || function(){
- return new Date().getTime();
+ return +new Date;
};
function $try(){
@@ -218,99 +261,84 @@ function $type(obj){
return typeof obj;
};
-var Hash = new Native({
+function $unlink(object){
+ var unlinked;
+ switch ($type(object)){
+ case 'object':
+ unlinked = {};
+ for (var p in object) unlinked[p] = $unlink(object[p]);
+ break;
+ case 'hash':
+ unlinked = new Hash(object);
+ break;
+ case 'array':
+ unlinked = [];
+ for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
+ break;
+ default: return object;
+ }
+ return unlinked;
+};
- name: 'Hash',
- initialize: function(object){
- if ($type(object) == 'hash') object = $unlink(object.getClean());
- for (var key in object) this[key] = object[key];
- return this;
- }
+/*
+Script: Browser.js
+ The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash.
-});
+License:
+ MIT-style license.
+*/
-Hash.implement({
-
- getLength: function(){
- var length = 0;
- for (var key in this){
- if (this.hasOwnProperty(key)) length++;
- }
- return length;
- },
+var Browser = $merge({
- forEach: function(fn, bind){
- for (var key in this){
- if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
- }
- },
-
- getClean: function(){
- var clean = {};
- for (var key in this){
- if (this.hasOwnProperty(key)) clean[key] = this[key];
- }
- return clean;
- }
+ Engine: {name: 'unknown', version: 0},
-});
+ Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
-Hash.alias('forEach', 'each');
+ Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
-function $H(object){
- return new Hash(object);
-};
+ Plugins: {},
-Array.implement({
+ Engines: {
- forEach: function(fn, bind){
- for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
- }
+ presto: function(){
+ return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
+ },
-});
+ trident: function(){
+ return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? 5 : 4);
+ },
-Array.alias('forEach', 'each');
+ webkit: function(){
+ return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
+ },
-function $A(iterable){
- if (iterable.item){
- var array = [];
- for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
- return array;
- }
- return Array.prototype.slice.call(iterable);
-};
+ gecko: function(){
+ return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18);
+ }
-function $each(iterable, fn, bind){
- var type = $type(iterable);
- ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind);
-};
+ }
+}, Browser || {});
-/*
-Script: Browser.js
- The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash.
+Browser.Platform[Browser.Platform.name] = true;
-License:
- MIT-style license.
-*/
+Browser.detect = function(){
-var Browser = new Hash({
- Engine: {name: 'unknown', version: ''},
- Platform: {name: (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
- Features: {xpath: !!(document.evaluate), air: !!(window.runtime)},
- Plugins: {}
-});
+ for (var engine in this.Engines){
+ var version = this.Engines[engine]();
+ if (version){
+ this.Engine = {name: engine, version: version};
+ this.Engine[engine] = this.Engine[engine + version] = true;
+ break;
+ }
+ }
-if (window.opera) Browser.Engine = {name: 'presto', version: (document.getElementsByClassName) ? 950 : 925};
-else if (window.ActiveXObject) Browser.Engine = {name: 'trident', version: (window.XMLHttpRequest) ? 5 : 4};
-else if (!navigator.taintEnabled) Browser.Engine = {name: 'webkit', version: (Browser.Features.xpath) ? 420 : 419};
-else if (document.getBoxObjectFor != null) Browser.Engine = {name: 'gecko', version: (document.getElementsByClassName) ? 19 : 18};
-Browser.Engine[Browser.Engine.name] = Browser.Engine[Browser.Engine.name + Browser.Engine.version] = true;
+ return {name: engine, version: version};
-if (window.orientation != undefined) Browser.Platform.name = 'ipod';
+};
-Browser.Platform[Browser.Platform.name] = true;
+Browser.detect();
Browser.Request = function(){
return $try(function(){
@@ -338,7 +366,7 @@ function $exec(text){
} else {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
- script.text = text;
+ script[(Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerText' : 'text'] = text;
document.head.appendChild(script);
document.head.removeChild(script);
}
@@ -366,6 +394,7 @@ var Window = new Native({
if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2
win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {};
}
+ win.document.window = win;
return $extend(win, Window.Prototype);
},
@@ -389,10 +418,13 @@ var Document = new Native({
$uid(doc);
doc.head = doc.getElementsByTagName('head')[0];
doc.html = doc.getElementsByTagName('html')[0];
- doc.window = doc.defaultView || doc.parentWindow;
- if (Browser.Engine.trident4) $try(function(){
+ if (Browser.Engine.trident && Browser.Engine.version <= 4) $try(function(){
doc.execCommand("BackgroundImageCache", false, true);
});
+ if (Browser.Engine.trident) doc.window.attachEvent('onunload', function() {
+ doc.window.detachEvent('onunload', arguments.callee);
+ doc.head = doc.html = doc.window = null;
+ });
return $extend(doc, Document.Prototype);
},
@@ -406,9 +438,10 @@ Document.Prototype = {$family: {name: 'document'}};
new Document(document);
+
/*
Script: Array.js
- Contains Array Prototypes like copy, each, contains, and remove.
+ Contains Array Prototypes like each, contains, and erase.
License:
MIT-style license.
@@ -430,7 +463,7 @@ Array.implement({
}
return results;
},
-
+
clean: function() {
return this.filter($defined);
},
@@ -547,97 +580,99 @@ Array.implement({
});
-/*
-Script: Function.js
- Contains Function Prototypes like create, bind, pass, and delay.
-
-License:
- MIT-style license.
-*/
-
-Function.implement({
-
- extend: function(properties){
- for (var property in properties) this[property] = properties[property];
- return this;
- },
-
- create: function(options){
- var self = this;
- options = options || {};
- return function(event){
- var args = options.arguments;
- args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0);
- if (options.event) args = [event || window.event].extend(args);
- var returns = function(){
- return self.apply(options.bind || null, args);
- };
- if (options.delay) return setTimeout(returns, options.delay);
- if (options.periodical) return setInterval(returns, options.periodical);
- if (options.attempt) return $try(returns);
- return returns();
- };
- },
-
- pass: function(args, bind){
- return this.create({arguments: args, bind: bind});
- },
-
- attempt: function(args, bind){
- return this.create({arguments: args, bind: bind, attempt: true})();
- },
-
- bind: function(bind, args){
- return this.create({bind: bind, arguments: args});
- },
-
- bindWithEvent: function(bind, args){
- return this.create({bind: bind, event: true, arguments: args});
- },
-
- delay: function(delay, bind, args){
- return this.create({delay: delay, bind: bind, arguments: args})();
- },
-
- periodical: function(interval, bind, args){
- return this.create({periodical: interval, bind: bind, arguments: args})();
- },
-
- run: function(args, bind){
- return this.apply(bind, $splat(args));
- }
-
-});
/*
-Script: Number.js
- Contains Number Prototypes like limit, round, times, and ceil.
+Script: Function.js
+ Contains Function Prototypes like create, bind, pass, and delay.
License:
MIT-style license.
*/
-Number.implement({
+Function.implement({
- limit: function(min, max){
- return Math.min(max, Math.max(min, this));
+ extend: function(properties){
+ for (var property in properties) this[property] = properties[property];
+ return this;
},
- round: function(precision){
- precision = Math.pow(10, precision || 0);
- return Math.round(this * precision) / precision;
+ create: function(options){
+ var self = this;
+ options = options || {};
+ return function(event){
+ var args = options.arguments;
+ args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0);
+ if (options.event) args = [event || window.event].extend(args);
+ var returns = function(){
+ return self.apply(options.bind || null, args);
+ };
+ if (options.delay) return setTimeout(returns, options.delay);
+ if (options.periodical) return setInterval(returns, options.periodical);
+ if (options.attempt) return $try(returns);
+ return returns();
+ };
},
- times: function(fn, bind){
- for (var i = 0; i < this; i++) fn.call(bind, i, this);
+ run: function(args, bind){
+ return this.apply(bind, $splat(args));
},
- toFloat: function(){
- return parseFloat(this);
+ pass: function(args, bind){
+ return this.create({bind: bind, arguments: args});
},
- toInt: function(base){
- return parseInt(this, base || 10);
+ bind: function(bind, args){
+ return this.create({bind: bind, arguments: args});
+ },
+
+ bindWithEvent: function(bind, args){
+ return this.create({bind: bind, arguments: args, event: true});
+ },
+
+ attempt: function(args, bind){
+ return this.create({bind: bind, arguments: args, attempt: true})();
+ },
+
+ delay: function(delay, bind, args){
+ return this.create({bind: bind, arguments: args, delay: delay})();
+ },
+
+ periodical: function(periodical, bind, args){
+ return this.create({bind: bind, arguments: args, periodical: periodical})();
+ }
+
+});
+
+
+/*
+Script: Number.js
+ Contains Number Prototypes like limit, round, times, and ceil.
+
+License:
+ MIT-style license.
+*/
+
+Number.implement({
+
+ limit: function(min, max){
+ return Math.min(max, Math.max(min, this));
+ },
+
+ round: function(precision){
+ precision = Math.pow(10, precision || 0);
+ return Math.round(this * precision) / precision;
+ },
+
+ times: function(fn, bind){
+ for (var i = 0; i < this; i++) fn.call(bind, i, this);
+ },
+
+ toFloat: function(){
+ return parseFloat(this);
+ },
+
+ toInt: function(base){
+ return parseInt(this, base || 10);
}
});
@@ -654,6 +689,7 @@ Number.alias('times', 'each');
Number.implement(methods);
})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
+
/*
Script: String.js
Contains String Prototypes like camelCase, capitalize, test, and toInt.
@@ -732,7 +768,7 @@ String.implement({
},
substitute: function(object, regexp){
- return this.replace(regexp || (/\\?\{([^}]+)\}/g), function(match, name){
+ return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
if (match.charAt(0) == '\\') return match.slice(1);
return (object[name] != undefined) ? object[name] : '';
});
@@ -740,6 +776,7 @@ String.implement({
});
+
/*
Script: Hash.js
Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects.
@@ -849,7 +886,7 @@ Hash.implement({
});
return values;
},
-
+
toQueryString: function(base){
var queryString = [];
Hash.each(this, function(value, key){
@@ -868,7 +905,7 @@ Hash.implement({
}
if (value != undefined) queryString.push(result);
});
-
+
return queryString.join('&');
}
@@ -876,6 +913,7 @@ Hash.implement({
Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});
+
/*
Script: Event.js
Contains the Event Native, to make the event object completely crossbrowser.
@@ -897,7 +935,7 @@ var Event = new Native({
var type = event.type;
var target = event.target || event.srcElement;
while (target && target.nodeType == 3) target = target.parentNode;
-
+
if (type.test(/key/)){
var code = event.which || event.keyCode;
var key = Event.Keys.keyOf(code);
@@ -936,19 +974,19 @@ var Event = new Native({
return $extend(this, {
event: event,
type: type,
-
+
page: page,
client: client,
rightClick: rightClick,
-
+
wheel: wheel,
-
+
relatedTarget: related,
target: target,
-
+
code: code,
key: key,
-
+
shift: event.shiftKey,
control: event.ctrlKey,
alt: