]> git.wh0rd.org - tt-rss.git/blobdiff - lib/dojo/selector/lite.js.uncompressed.js
update dojo to 1.7.3
[tt-rss.git] / 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 (file)
index 0000000..374f7a2
--- /dev/null
@@ -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;
+});