mirror of
https://git.tt-rss.org/git/tt-rss.git
synced 2025-12-14 21:45:55 +00:00
update dojo to 1.7.3
This commit is contained in:
264
lib/dojo/selector/lite.js.uncompressed.js
Normal file
264
lib/dojo/selector/lite.js.uncompressed.js
Normal file
@@ -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;
|
||||
});
|
||||
Reference in New Issue
Block a user