X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6:/src/ext-core/src/core/DomQuery.js..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/core/src/dom/DomQuery.js diff --git a/src/ext-core/src/core/DomQuery.js b/src/core/src/dom/DomQuery.js similarity index 82% rename from src/ext-core/src/core/DomQuery.js rename to src/core/src/dom/DomQuery.js index 5fefcba7..9c6f83e0 100644 --- a/src/ext-core/src/core/DomQuery.js +++ b/src/core/src/dom/DomQuery.js @@ -1,9 +1,3 @@ -/*! - * Ext JS Library 3.3.1 - * Copyright(c) 2006-2010 Sencha Inc. - * licensing@sencha.com - * http://www.sencha.com/license - */ /* * This is code is also distributed under MIT license for use * with jQuery and prototype JavaScript libraries. @@ -70,26 +64,28 @@ All selectors, attribute filters and pseudos below can be combined infinitely in * @singleton */ -Ext.DomQuery = function(){ - var cache = {}, - simpleCache = {}, - valueCache = {}, - nonSpace = /\S/, - trimRe = /^\s+|\s+$/g, - tplRe = /\{(\d+)\}/g, - modeRe = /^(\s?[\/>+~]\s?|\s|$)/, - tagTokenRe = /^(#)?([\w-\*]+)/, - nthRe = /(\d*)n\+?(\d*)/, - nthRe2 = /\D/, - // This is for IE MSXML which does not support expandos. - // IE runs the same speed using setAttribute, however FF slows way down - // and Safari completely fails so they need to continue to use expandos. - isIE = window.ActiveXObject ? true : false, - key = 30803; - +Ext.ns('Ext.core'); + +Ext.core.DomQuery = Ext.DomQuery = function(){ + var cache = {}, + simpleCache = {}, + valueCache = {}, + nonSpace = /\S/, + trimRe = /^\s+|\s+$/g, + tplRe = /\{(\d+)\}/g, + modeRe = /^(\s?[\/>+~]\s?|\s|$)/, + tagTokenRe = /^(#)?([\w-\*]+)/, + nthRe = /(\d*)n\+?(\d*)/, + nthRe2 = /\D/, + // This is for IE MSXML which does not support expandos. + // IE runs the same speed using setAttribute, however FF slows way down + // and Safari completely fails so they need to continue to use expandos. + isIE = window.ActiveXObject ? true : false, + key = 30803; + // this eval is stop the compressor from // renaming the variable to something shorter - eval("var batch = 30803;"); + eval("var batch = 30803;"); // Retrieve the child node from a particular // parent at the specified index. @@ -108,12 +104,12 @@ Ext.DomQuery = function(){ } // retrieve the next element node - function next(n){ + function next(n){ while((n = n.nextSibling) && n.nodeType != 1); return n; } - // retrieve the previous element node + // retrieve the previous element node function prev(n){ while((n = n.previousSibling) && n.nodeType != 1); return n; @@ -123,20 +119,20 @@ Ext.DomQuery = function(){ // removing empty text nodes. function children(parent){ var n = parent.firstChild, - nodeIndex = -1, - nextNode; - while(n){ - nextNode = n.nextSibling; - // clean worthless empty nodes. - if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ - parent.removeChild(n); - }else{ - // add an expando nodeIndex - n.nodeIndex = ++nodeIndex; - } - n = nextNode; - } - return this; + nodeIndex = -1, + nextNode; + while(n){ + nextNode = n.nextSibling; + // clean worthless empty nodes. + if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ + parent.removeChild(n); + }else{ + // add an expando nodeIndex + n.nodeIndex = ++nodeIndex; + } + n = nextNode; + } + return this; } @@ -156,7 +152,7 @@ Ext.DomQuery = function(){ }; function attrValue(n, attr){ - // if its an array, use the first node. + // if its an array, use the first node. if(!n.tagName && typeof n.length != "undefined"){ n = n[0]; } @@ -184,13 +180,13 @@ Ext.DomQuery = function(){ return result; } tagName = tagName || "*"; - // convert to array + // convert to array if(typeof ns.getElementsByTagName != "undefined"){ ns = [ns]; } - - // no mode specified, grab all elements by tagName - // at any depth + + // no mode specified, grab all elements by tagName + // at any depth if(!mode){ for(var i = 0, ni; ni = ns[i]; i++){ cs = ni.getElementsByTagName(tagName); @@ -198,8 +194,8 @@ Ext.DomQuery = function(){ result[++ri] = ci; } } - // Direct Child mode (/ or >) - // E > F or E/F all direct children elements of E that have the tag + // Direct Child mode (/ or >) + // E > F or E/F all direct children elements of E that have the tag } else if(mode == "/" || mode == ">"){ var utag = tagName.toUpperCase(); for(var i = 0, ni, cn; ni = ns[i]; i++){ @@ -210,8 +206,8 @@ Ext.DomQuery = function(){ } } } - // Immediately Preceding mode (+) - // E + F all elements with the tag F that are immediately preceded by an element with the tag E + // Immediately Preceding mode (+) + // E + F all elements with the tag F that are immediately preceded by an element with the tag E }else if(mode == "+"){ var utag = tagName.toUpperCase(); for(var i = 0, n; n = ns[i]; i++){ @@ -220,8 +216,8 @@ Ext.DomQuery = function(){ result[++ri] = n; } } - // Sibling mode (~) - // E ~ F all elements with the tag F that are preceded by a sibling element with the tag E + // Sibling mode (~) + // E ~ F all elements with the tag F that are preceded by a sibling element with the tag E }else if(mode == "~"){ var utag = tagName.toUpperCase(); for(var i = 0, n; n = ns[i]; i++){ @@ -282,16 +278,16 @@ Ext.DomQuery = function(){ // operators are =, !=, ^=, $=, *=, %=, |= and ~= // custom can be "{" function byAttribute(cs, attr, value, op, custom){ - var result = [], - ri = -1, - useGetStyle = custom == "{", - fn = Ext.DomQuery.operators[op], + var result = [], + ri = -1, + useGetStyle = custom == "{", + fn = Ext.DomQuery.operators[op], a, xml, hasXml; - + for(var i = 0, ci; ci = cs[i]; i++){ - // skip non-element nodes. + // skip non-element nodes. if(ci.nodeType != 1){ continue; } @@ -300,7 +296,7 @@ Ext.DomQuery = function(){ xml = Ext.DomQuery.isXml(ci); hasXml = true; } - + // we only need to change the property names if we're dealing with html nodes, not XML if(!xml){ if(useGetStyle){ @@ -310,8 +306,8 @@ Ext.DomQuery = function(){ } else if (attr == "for"){ a = ci.htmlFor; } else if (attr == "href"){ - // getAttribute href bug - // http://www.glennjones.net/Post/809/getAttributehrefbug.htm + // getAttribute href bug + // http://www.glennjones.net/Post/809/getAttributehrefbug.htm a = ci.getAttribute("href", 2); } else{ a = ci.getAttribute(attr); @@ -331,7 +327,7 @@ Ext.DomQuery = function(){ } function nodupIEXml(cs){ - var d = ++key, + var d = ++key, r; cs[0].setAttribute("_nodup", d); r = [cs[0]]; @@ -386,7 +382,7 @@ Ext.DomQuery = function(){ r = []; for(var i = 0, len = c1.length; i < len; i++){ c1[i].setAttribute("_qdiff", d); - } + } for(var i = 0, len = c2.length; i < len; i++){ if(c2[i].getAttribute("_qdiff") != d){ r[r.length] = c2[i]; @@ -400,17 +396,17 @@ Ext.DomQuery = function(){ function quickDiff(c1, c2){ var len1 = c1.length, - d = ++key, - r = []; + d = ++key, + r = []; if(!len1){ return c2; } if(isIE && typeof c1[0].selectSingleNode != "undefined"){ return quickDiffIEXml(c1, c2); - } + } for(var i = 0; i < len1; i++){ c1[i]._qdiff = d; - } + } for(var i = 0, len = c2.length; i < len; i++){ if(c2[i]._qdiff != d){ r[r.length] = c2[i]; @@ -442,21 +438,21 @@ Ext.DomQuery = function(){ compile : function(path, type){ type = type || "select"; - // setup fn preamble + // setup fn preamble var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"], - mode, - lastPath, - matchers = Ext.DomQuery.matchers, - matchersLn = matchers.length, - modeMatch, - // accept leading mode switch - lmode = path.match(modeRe); - + mode, + lastPath, + matchers = Ext.DomQuery.matchers, + matchersLn = matchers.length, + modeMatch, + // accept leading mode switch + lmode = path.match(modeRe); + if(lmode && lmode[1]){ fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";'; path = path.replace(lmode[1], ""); } - + // strip leading slashes while(path.substr(0, 1)=="/"){ path = path.substr(1); @@ -467,9 +463,9 @@ Ext.DomQuery = function(){ var tokenMatch = path.match(tagTokenRe); if(type == "select"){ if(tokenMatch){ - // ID Selector + // ID Selector if(tokenMatch[1] == "#"){ - fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");'; + fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");'; }else{ fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");'; } @@ -477,7 +473,7 @@ Ext.DomQuery = function(){ }else if(path.substr(0, 1) != '@'){ fn[fn.length] = 'n = getNodes(n, mode, "*");'; } - // type of "simple" + // type of "simple" }else{ if(tokenMatch){ if(tokenMatch[1] == "#"){ @@ -495,8 +491,8 @@ Ext.DomQuery = function(){ var m = path.match(t.re); if(m){ fn[fn.length] = t.select.replace(tplRe, function(x, i){ - return m[i]; - }); + return m[i]; + }); path = path.replace(m[0], ""); matched = true; break; @@ -504,7 +500,13 @@ Ext.DomQuery = function(){ } // prevent infinite loop on bad selector if(!matched){ - throw 'Error parsing selector, parsing failed at "' + path + '"'; + // + Ext.Error.raise({ + sourceClass: 'Ext.DomQuery', + sourceMethod: 'compile', + msg: 'Error parsing selector. Parsing failed at "' + path + '"' + }); + // } } if(modeMatch[1]){ @@ -512,10 +514,10 @@ Ext.DomQuery = function(){ path = path.replace(modeMatch[1], ""); } } - // close fn out + // close fn out fn[fn.length] = "return nodup(n);\n}"; - - // eval fn and return it + + // eval fn and return it eval(fn.join("")); return f; }, @@ -527,24 +529,30 @@ Ext.DomQuery = function(){ * @return {Array} An Array of DOM elements which match the selector. If there are * no matches, and empty Array is returned. */ - jsSelect: function(path, root, type){ - // set root to doc if not specified. - root = root || document; - + jsSelect: function(path, root, type){ + // set root to doc if not specified. + root = root || document; + if(typeof root == "string"){ root = document.getElementById(root); } var paths = path.split(","), - results = []; - - // loop over each selector - for(var i = 0, len = paths.length; i < len; i++){ + results = []; + + // loop over each selector + for(var i = 0, len = paths.length; i < len; i++){ var subPath = paths[i].replace(trimRe, ""); - // compile and place in cache + // compile and place in cache if(!cache[subPath]){ cache[subPath] = Ext.DomQuery.compile(subPath); if(!cache[subPath]){ - throw subPath + " is not a valid selector"; + // + Ext.Error.raise({ + sourceClass: 'Ext.DomQuery', + sourceMethod: 'jsSelect', + msg: subPath + ' is not a valid selector' + }); + // } } var result = cache[subPath](root); @@ -552,31 +560,33 @@ Ext.DomQuery = function(){ results = results.concat(result); } } - - // if there were multiple selectors, make sure dups - // are eliminated + + // if there were multiple selectors, make sure dups + // are eliminated if(paths.length > 1){ return nodup(results); } return results; }, - isXml: function(el) { - var docEl = (el ? el.ownerDocument || el : 0).documentElement; - return docEl ? docEl.nodeName !== "HTML" : false; - }, + + isXml: function(el) { + var docEl = (el ? el.ownerDocument || el : 0).documentElement; + return docEl ? docEl.nodeName !== "HTML" : false; + }, + select : document.querySelectorAll ? function(path, root, type) { - root = root || document; - if (!Ext.DomQuery.isXml(root)) { - try { - var cs = root.querySelectorAll(path); - return Ext.toArray(cs); - } - catch (ex) {} - } - return Ext.DomQuery.jsSelect.call(this, path, root, type); - } : function(path, root, type) { - return Ext.DomQuery.jsSelect.call(this, path, root, type); - }, + root = root || document; + if (!Ext.DomQuery.isXml(root)) { + try { + var cs = root.querySelectorAll(path); + return Ext.Array.toArray(cs); + } + catch (ex) {} + } + return Ext.DomQuery.jsSelect.call(this, path, root, type); + } : function(path, root, type) { + return Ext.DomQuery.jsSelect.call(this, path, root, type); + }, /** * Selects a single element. @@ -602,13 +612,13 @@ Ext.DomQuery = function(){ } var n = valueCache[path](root), v; n = n[0] ? n[0] : n; - - // overcome a limitation of maximum textnode size - // Rumored to potentially crash IE6 but has not been confirmed. - // http://reference.sitepoint.com/javascript/Node/normalize - // https://developer.mozilla.org/En/DOM/Node.normalize + + // overcome a limitation of maximum textnode size + // Rumored to potentially crash IE6 but has not been confirmed. + // http://reference.sitepoint.com/javascript/Node/normalize + // https://developer.mozilla.org/En/DOM/Node.normalize if (typeof n.normalize == 'function') n.normalize(); - + v = (n && n.firstChild ? n.firstChild.nodeValue : null); return ((v === null||v === undefined||v==='') ? defaultValue : v); }, @@ -636,7 +646,7 @@ Ext.DomQuery = function(){ el = document.getElementById(el); } var isArray = Ext.isArray(el), - result = Ext.DomQuery.filter(isArray ? el : [el], ss); + result = Ext.DomQuery.filter(isArray ? el : [el], ss); return isArray ? (result.length == el.length) : (result.length > 0); }, @@ -713,30 +723,38 @@ Ext.DomQuery = function(){ }, /** - *

Object hash of "pseudo class" filter functions which are used when filtering selections. Each function is passed - * two parameters:

- *

A filter function returns an Array of DOM elements which conform to the pseudo class.

- *

In addition to the provided pseudo classes listed above such as first-child and nth-child, - * developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.

- *

For example, to filter <a> elements to only return links to external resources:

- *
-Ext.DomQuery.pseudos.external = function(c, v){
-    var r = [], ri = -1;
-    for(var i = 0, ci; ci = c[i]; i++){
-//      Include in result set only if it's a link to an external resource
-        if(ci.hostname != location.hostname){
-            r[++ri] = ci;
+Object hash of "pseudo class" filter functions which are used when filtering selections. 
+Each function is passed two parameters:
+
+- **c** : Array
+    An Array of DOM elements to filter.
+    
+- **v** : String
+    The argument (if any) supplied in the selector.
+
+A filter function returns an Array of DOM elements which conform to the pseudo class.
+In addition to the provided pseudo classes listed above such as `first-child` and `nth-child`,
+developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.
+
+For example, to filter `a` elements to only return links to __external__ resources:
+
+    Ext.DomQuery.pseudos.external = function(c, v){
+        var r = [], ri = -1;
+        for(var i = 0, ci; ci = c[i]; i++){
+            // Include in result set only if it's a link to an external resource
+            if(ci.hostname != location.hostname){
+                r[++ri] = ci;
+            }
         }
-    }
-    return r;
-};
- * Then external links could be gathered with the following statement:
-var externalLinks = Ext.select("a:external");
-
- */ + return r; + }; + +Then external links could be gathered with the following statement: + + var externalLinks = Ext.select("a:external"); + + * @markdown + */ pseudos : { "first-child" : function(c){ var r = [], ri = -1, n; @@ -762,8 +780,8 @@ var externalLinks = Ext.select("a:external"); "nth-child" : function(c, a) { var r = [], ri = -1, - m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a), - f = (m[1] || 1) - 0, l = m[2] - 0; + m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a), + f = (m[1] || 1) - 0, l = m[2] - 0; for(var i = 0, n; n = c[i]; i++){ var pn = n.parentNode; if (batch != pn._batch) { @@ -851,7 +869,7 @@ var externalLinks = Ext.select("a:external"); "any" : function(c, selectors){ var ss = selectors.split('|'), - r = [], ri = -1, s; + r = [], ri = -1, s; for(var i = 0, ci; ci = c[i]; i++){ for(var j = 0; s = ss[j]; j++){ if(Ext.DomQuery.is(ci, s)){ @@ -885,7 +903,7 @@ var externalLinks = Ext.select("a:external"); "has" : function(c, ss){ var s = Ext.DomQuery.select, - r = [], ri = -1; + r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ if(s(ss, ci).length > 0){ r[++ri] = ci; @@ -896,7 +914,7 @@ var externalLinks = Ext.select("a:external"); "next" : function(c, ss){ var is = Ext.DomQuery.is, - r = [], ri = -1; + r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ var n = next(ci); if(n && is(n, ss)){ @@ -908,7 +926,7 @@ var externalLinks = Ext.select("a:external"); "prev" : function(c, ss){ var is = Ext.DomQuery.is, - r = [], ri = -1; + r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ var n = prev(ci); if(n && is(n, ss)){