From 1354d17270961fff662d40f90521223f8fd0d73b Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Tue, 14 Aug 2012 18:59:10 +0400 Subject: update dojo to 1.7.3 --- lib/dojo/selector/lite.js.uncompressed.js | 264 ++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 lib/dojo/selector/lite.js.uncompressed.js (limited to 'lib/dojo/selector/lite.js.uncompressed.js') diff --git a/lib/dojo/selector/lite.js.uncompressed.js b/lib/dojo/selector/lite.js.uncompressed.js new file mode 100644 index 000000000..374f7a2ad --- /dev/null +++ b/lib/dojo/selector/lite.js.uncompressed.js @@ -0,0 +1,264 @@ +define("dojo/selector/lite", ["../has", "../_base/kernel"], function(has, dojo){ +"use strict"; +// summary: +// A small lightweight query selector engine that implements CSS2.1 selectors +// minus pseudo-classes and the sibling combinator, plus CSS3 attribute selectors +var testDiv = document.createElement("div"); +var matchesSelector = testDiv.matchesSelector || testDiv.webkitMatchesSelector || testDiv.mozMatchesSelector || testDiv.msMatchesSelector || testDiv.oMatchesSelector; // IE9, WebKit, Firefox have this, but not Opera yet +var querySelectorAll = testDiv.querySelectorAll; +has.add("dom-matches-selector", !!matchesSelector); +has.add("dom-qsa", !!querySelectorAll); + +// this is a simple query engine. It has handles basic selectors, and for simple +// common selectors is extremely fast +var liteEngine = function(selector, root){ + if(combine && selector.indexOf(',') > -1){ + return combine(selector, root); + } + var match = (querySelectorAll ? + /^([\w]*)#([\w\-]+$)|^(\.)([\w\-\*]+$)|^(\w+$)/ : // this one only matches on simple queries where we can beat qSA with specific methods + /^([\w]*)#([\w\-]+)(?:\s+(.*))?$|(?:^|(>|.+\s+))([\w\-\*]+)(\S*$)/) // this one matches parts of the query that we can use to speed up manual filtering + .exec(selector); + root = root || document; + if(match){ + // fast path regardless of whether or not querySelectorAll exists + if(match[2]){ + // an #id + // use dojo.byId if available as it fixes the id retrieval in IE + var found = dojo.byId ? dojo.byId(match[2]) : document.getElementById(match[2]); + if(!found || (match[1] && match[1] != found.tagName.toLowerCase())){ + // if there is a tag qualifer and it doesn't match, no matches + return []; + } + if(root != document){ + // there is a root element, make sure we are a child of it + var parent = found; + while(parent != root){ + parent = parent.parentNode; + if(!parent){ + return []; + } + } + } + return match[3] ? + liteEngine(match[3], found) + : [found]; + } + if(match[3] && root.getElementsByClassName){ + // a .class + return root.getElementsByClassName(match[4]); + } + var found; + if(match[5]){ + // a tag + found = root.getElementsByTagName(match[5]); + if(match[4] || match[6]){ + selector = (match[4] || "") + match[6]; + }else{ + // that was the entirety of the query, return results + return found; + } + } + } + if(querySelectorAll){ + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if (root.nodeType === 1 && root.nodeName.toLowerCase() !== "object"){ + return useRoot(root, selector, root.querySelectorAll); + }else{ + // we can use the native qSA + return root.querySelectorAll(selector); + } + }else if(!found){ + // search all children and then filter + found = root.getElementsByTagName("*"); + } + // now we filter the nodes that were found using the matchesSelector + var results = []; + for(var i = 0, l = found.length; i < l; i++){ + var node = found[i]; + if(node.nodeType == 1 && jsMatchesSelector(node, selector, root)){ + // keep the nodes that match the selector + results.push(node); + } + } + return results; +}; +var useRoot = function(context, query, method){ + // this function creates a temporary id so we can do rooted qSA queries, this is taken from sizzle + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || "__dojo__", + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if(relativeHierarchySelector && !hasParent){ + return []; + } + if(!old){ + context.setAttribute("id", nid); + }else{ + nid = nid.replace(/'/g, "\\$&"); + } + if(relativeHierarchySelector && hasParent){ + context = context.parentNode; + } + + try { + return method.call(context, "[id='" + nid + "'] " + query ); + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } +}; + +if(!has("dom-matches-selector")){ + var jsMatchesSelector = (function(){ + // a JS implementation of CSS selector matching, first we start with the various handlers + var caseFix = testDiv.tagName == "div" ? "toLowerCase" : "toUpperCase"; + function tag(tagName){ + tagName = tagName[caseFix](); + return function(node){ + return node.tagName == tagName; + } + } + function className(className){ + var classNameSpaced = ' ' + className + ' '; + return function(node){ + return node.className.indexOf(className) > -1 && (' ' + node.className + ' ').indexOf(classNameSpaced) > -1; + } + } + var attrComparators = { + "^=": function(attrValue, value){ + return attrValue.indexOf(value) == 0; + }, + "*=": function(attrValue, value){ + return attrValue.indexOf(value) > -1; + }, + "$=": function(attrValue, value){ + return attrValue.substring(attrValue.length - value.length, attrValue.length) == value; + }, + "~=": function(attrValue, value){ + return (' ' + attrValue + ' ').indexOf(' ' + value + ' ') > -1; + }, + "|=": function(attrValue, value){ + return (attrValue + '-').indexOf(value + '-') == 0; + }, + "=": function(attrValue, value){ + return attrValue == value; + }, + "": function(attrValue, value){ + return true; + } + }; + function attr(name, value, type){ + if(value.match(/['"]/)){ + // it is quoted, do an eval to parse the string (CSS and JS parsing are close enough) + value = eval(value); + } + var comparator = attrComparators[type || ""]; + return function(node){ + var attrValue = node.getAttribute(name); + return attrValue && comparator(attrValue, value); + } + } + function ancestor(matcher){ + return function(node, root){ + while((node = node.parentNode) != root){ + if(matcher(node, root)){ + return true; + } + } + }; + } + function parent(matcher){ + return function(node, root){ + node = node.parentNode; + return matcher ? + node != root && matcher(node, root) + : node == root; + }; + } + var cache = {}; + function and(matcher, next){ + return matcher ? + function(node, root){ + return next(node) && matcher(node, root); + } + : next; + } + return function(node, selector, root){ + // this returns true or false based on if the node matches the selector (optionally within the given root) + var matcher = cache[selector]; // check to see if we have created a matcher function for the given selector + if(!matcher){ + // create a matcher function for the given selector + // parse the selectors + if(selector.replace(/(?:\s*([> ])\s*)|(\.)?([\w-]+)|\[([\w-]+)\s*(.?=)?\s*([^\]]*)\]/g, function(t, combinator, type, value, attrName, attrType, attrValue){ + if(value){ + if(type == "."){ + matcher = and(matcher, className(value)); + } + else{ + matcher = and(matcher, tag(value)); + } + } + else if(combinator){ + matcher = (combinator == " " ? ancestor : parent)(matcher); + } + else if(attrName){ + matcher = and(matcher, attr(attrName, attrValue, attrType)); + } + return ""; + })){ + throw new Error("Syntax error in query"); + } + if(!matcher){ + return true; + } + cache[selector] = matcher; + } + // now run the matcher function on the node + return matcher(node, root); + }; + })(); +} +if(!has("dom-qsa")){ + var combine = function(selector, root){ + // combined queries + selector = selector.split(/\s*,\s*/); + var indexed = []; + // add all results and keep unique ones, this only runs in IE, so we take advantage + // of known IE features, particularly sourceIndex which is unique and allows us to + // order the results + for(var i = 0; i < selector.length; i++){ + var results = liteEngine(selector[i], root); + for(var j = 0, l = results.length; j < l; j++){ + var node = results[j]; + indexed[node.sourceIndex] = node; + } + } + // now convert from a sparse array to a dense array + var totalResults = []; + for(i in indexed){ + totalResults.push(indexed[i]); + } + return totalResults; + }; +} + +liteEngine.match = matchesSelector ? function(node, selector, root){ + if(root){ + // doesn't support three args, use rooted id trick + return useRoot(root, selector, function(query){ + return matchesSelector.call(node, query); + }); + } + // we have a native matchesSelector, use that + return matchesSelector.call(node, selector); +} : jsMatchesSelector; // otherwise use the JS matches impl + +return liteEngine; +}); -- cgit v1.2.3