Skip to content

Instantly share code, notes, and snippets.

@termi
Created May 5, 2012 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save termi/2604786 to your computer and use it in GitHub Desktop.
Save termi/2604786 to your computer and use it in GitHub Desktop.
getElementsByClassName/querySelector/querySelectorAll/matchesSelector Polyfill
/** @license MIT License (c) copyright Egor Halimonenko (termi1uc1@gmail.com) */
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @warning_level VERBOSE
// @jscomp_warning missingProperties
// @output_file_name a.js.querySelector.min.js
// @check_types
// ==/ClosureCompiler==
;(function(global) {
"use strict";
var
/** Browser sniffing
* @type {boolean}
* @const */
_browser_msie = (+(/msie (\d+)/i.exec(navigator.userAgent) || [])[1]) || void 0
/** @type {RegExp} @const */
, RE__getElementsByClassName = /\s*(\S+)\s*/g
/** @type {string} @const */
, STRING_FOR_RE__getElementsByClassName = '(?=(^|.*\\s)$1(\\s|$))'
/** @type {RegExp} @const */
, RE__selector__easySelector = /^([\w-\|]+)?((?:\.(?:[\w-]+))+)?$|^#([\w-]+$)/
/** @type {RegExp} @const */
, RE__queryManySelector__doubleSpaces = /\s*([,>+~ ])\s*/g//Note: Use with "$1"
/** @type {RegExp} @const */
, RE__querySelector__arrtSpaceSeparated_toSafe = /\~\=/g//Note: Use with "@="
/** @type {RegExp} @const */
, RE__queryManySelector__selectorsMatcher = /(^[>+~ ]?|,|\>|\+|~| ).*?(?=[,>+~ ]|$)/g
/** @type {RegExp} @const */
, RE__querySelector__dottes = /\./g
/** @type {RegExp} @const */
, RE__queryOneSelector__spaces = /\s/g
/** @type {RegExp} @const */
, RE__queryOneSelector__selectorMatch = /^([,>+~ ])?([\w-\|\*]*)\#?([\w-]*)((?:\.?[\w-])*)(\[.+\])?(?:\:(.+))?$/
/** @type {RegExp} @const */
, RE__queryOneSelector__attrMatcher = /^\[?(.*?)(?:([\*~&\^\$\@!]?=)(.*?))?\]?$/
/** @type {RegExp} @const */
, RE__queryOneSelector__pseudoMatcher = /^([^(]+)(?:\(([^)]+)\))?$//* regexpt from jass 0.3.9 (http://yass.webo.in/) rev. 371 line 166 from right */
/** @type {RegExp} @const */
, RE__queryOneSelector__pseudoNthChildPlus = /\-child\((\dn)\+(\d)\)/g//Note: Use with "-child\($1%$2\)"
/** @type {RegExp} @const */
, RE__queryOneSelector__pseudoNthChildMatcher = /(?:([-]?\d*)n)?(?:(%|-)(\d*))?//* regexpt from jass 0.3.9 (http://yass.webo.in/) rev. 371 line 181 ( mod === 'nth-last-child' ?...) */
/** @type {RegExp} @const */
, RE_matchSelector__isSimpleSelector = /([,>+~ ])/
/** @type {Object} @const */
, selectorCombinatorTypeMap = {
"" : 1,
" " : 1,
"," : 1,
">" : 2,
"~" : 3,
"+" : 4
}
/** @type {Object} @const */
, selectorAttrOperatorsMap = {
"" : 1,
'=' : 2,
'&=' : 3,
'^=' : 4,
'$=' : 5,
'*=' : 6,
'|=' : 7,
'!=' : 8,
'@=' : 9//this is '~='
}
/** @type {Object} @const */
, selectorPseudosMap = {
'nth-child' : 0,
'nth-last-child' : 1,
'only-child' : 2,
'first-child' : 3,
'last-child' : 4,
'root' : 5,
'empty' : 6,
'checked' : 7,
'lang' : 8,
'enabled' : 9,
'disabled' : 10,
'selected' : 11,
'contains' : 12,
'not' : 13
}
/** @type {Object} @const */
, attributeSpecialCase = {
"href" : function(node) {
return node.getAttribute("href", 2);
}
}
/** @type {Object} @const */
, attributeSpecialSpecified = {"coords" : 1, "id" : 1, "name" : 1}
, _document_documentElement = document.documentElement
/**
* @const
* Use native and probably broken function or Quick, but non-full-standart
* For system use only
* More standart solution in a.js
*/
, _String_trim = String.prototype.trim || function () {//Cache origin trim function
var str = this.replace(/^\s+/, ''),
ws = /\s/,
i = str.length;
while (ws.test(str.charAt(--i))){};
return str.slice(0, i + 1);
}
/** @const */
, _String_split = String.prototype.split
/** @const */
, _String_substr = String.prototype.substr
, _shim_getElementsByClassName
, isNative_getElementsByClassName = _document_documentElement.getElementsByClassName && (_document_documentElement.getElementsByClassName + "").length < 80
, _Array_slice = Array.prototype.slice
, _Array_from = function(iterable, iterable_is_sparseArray) {
var length = iterable.length >>> 0,
result;
if(!iterable_is_sparseArray) {
try {
result = _Array_slice.call(iterable);
}
catch(e) { }
if(result && result.length === length)return result;
}
result = [];
for(var key = 0 ; key < length ; key++) {
if(key in iterable)
result.push(iterable[key]);
}
return result;
}
, _can_useGetElementsByName_as_getElementById = (function() {
var result = false,
uiid = "_" + Math.random(),
tempNode = document.createElement("br");
_document_documentElement.appendChild(tempNode).id = uiid;
try {
result = document.getElementsByName(uiid)[0].id === uiid;
}
catch(e) {
result = false;
}
finally {
_document_documentElement.removeChild(tempNode);
}
return result;
})()
, sourceIndex_propertyName = "sourceIndex"
, hasSourceIndex = sourceIndex_propertyName in _document_documentElement
, UUID = 1
, getNextElement = "nextElementSibling" in _document_documentElement ?
function(node) {
return node.nextElementSibling;
}
:
function(node) {
while((node = node.nextSibling) && node.nodeType != 1) {}
return node;
}
;
if(!hasSourceIndex)sourceIndex_propertyName = "uniqueId";
//[BUGFIX, IE lt 9] IE < 9 substr() with negative value not working in IE
if("ab".substr(-1) !== "b") {
//String.prototype._itlt9_substr_ = String.prototype.substr;
String.prototype.substr = function(start, length) {
return _String_substr.call(this, start < 0 ? (start = this.length + start) < 0 ? 0 : start : start, length);
}
}
//Only for IE
if(!isNative_getElementsByClassName)_shim_getElementsByClassName = function(klas) {
klas = klas + "";
var re,
result = [],
nodes = this.all,
node,
i = -1;
if(nodes.length) {
re = new RegExp(klas.replace(RE__getElementsByClassName, STRING_FOR_RE__getElementsByClassName));
while(node = nodes[++i]) {
if(node.className && re.test(node.className)) {
result.push(node);
}
}
}
return result;
}
/**
* @param {!string} selector CSS3-selector
* @param {Node|Array.<Node>|Object} roots
* @param {Array.<Node>} globalResult
* @param {boolean} globalResultAsSparseArray
* @param {Node|Array.<HTMLElement>=} preResult
* @param {boolean=} onlyOne only one need
* {(Object|boolean)=} resultKeys
* @return {Array.<Node>}
*/
function queryOneSelector(selector, roots, globalResult, globalResultAsSparseArray, preResult, onlyOne/*, resultKeys*/) {
var /** @type {Array.<string>} */selectorArr = selector.match(RE__queryOneSelector__selectorMatch);
//if(selector === "," || !selectorArr)_throwDOMException("SYNTAX_ERR");
var result = globalResult || [];
var /** @type {boolean} */isMatchesSelector = !!preResult
, /** @type {Node} */root = isMatchesSelector && (roots = {}) || (!roots ? document :
"length" in roots ? //fast and unsafe isArray
roots[0] :
roots)
, /** @type {Node} */nextRoot
, /** @type {number} */rootIndex = 0
, /** @type {(Node|undefined)} */child
, /** @type {Node} */brother
, /** @type {number} */combinatorType = selectorCombinatorTypeMap[selectorArr[1] || ""] || 0
, /** @type {boolean} */combinatorTypeMoreThen_2 = combinatorType > 2
, /** @type {(string|undefined)} */tag = selectorArr[2]
, /** @type {boolean} */needCheck_tag = !!tag
, /** @type {(string|undefined)} */id = selectorArr[3]
, /** @type {boolean} */needCheck_id = !!id
, /** @type {(string|Array.<string>|undefined)} */classes = selectorArr[4]
, /** @type {boolean} */needCheck_classes = !!classes
, /** @type {boolean} */needCheck_nodeType = tag === "*"
, /** @type {number} */kr
, /** @type {number} */childrenIndex
, /** @type {number} */indexIn_resultKeys
, /** @type {boolean} */match
, /** @type {boolean} */canWeReturnUnsafeArray
//, {boolean} needToRemove
, /** @type {boolean} */isNthLastChild
, /** @type {Array.<string>} */css3Attr_add
, /** @type {Array.<string>} */css3Pseudo_add
, /** @type {number} */css3PseudoOperatorType
, /** @type {string} */nodeAttrCurrent_value
, /** @type {string} */nodeAttrExpected_value
, /** @type {(RegExp|string)} */klas
//, {(string|Array.<string>|boolean)} css3AttrAndcss3Pseudo
, /** @type {(string|Array.<string>)} */ css3Attr
, /** @type {(string|Array.<string>)} */ css3Pseudo
, /** @type {Array} */elementsById_Cache
, a, b, c, u
, A, B, C
;
if(needCheck_tag) {
tag = (needCheck_nodeType ? void 0 : tag.replace("|", ":").toUpperCase());
}
if(needCheck_classes) {
classes = classes.replace(RE__querySelector__dottes, " ");
if(!isNative_getElementsByClassName || combinatorType !== 1)klas = new RegExp(classes.replace(RE__getElementsByClassName, STRING_FOR_RE__getElementsByClassName));
}
if(isMatchesSelector)combinatorType = 0;
if(css3Attr = selectorArr[5]) {
css3Attr = _String_split.call(css3Attr, "][");
kr = -1;
while(css3Attr_add = css3Attr[++kr]) {
css3Attr_add = css3Attr[kr] = css3Attr_add.match(RE__queryOneSelector__attrMatcher);
selectorAttrOperatorsMap
b = css3Attr_add[1];
if((a = b.charAt(0)) === "\'" || a === "\"" && b.substr(-1) === a) {//Note: original IE substr not allowed negative value as first param
b = css3Attr_add[1] = _String_substr.call(b, 1, b.length - 2);
}
css3Attr_add[2] = selectorAttrOperatorsMap[css3Attr_add[2]];
b = css3Attr_add[3];
if(b && ((a = b.charAt(0)) === "\'" || a === "\"" && b.substr(-1) === a)) {
b = css3Attr_add[3] = _String_substr.call(b, 1, b.length - 2);
}
}
}
if(css3Pseudo = selectorArr[6]) {
css3Pseudo = css3Pseudo.match(RE__queryOneSelector__pseudoMatcher);
css3PseudoOperatorType = selectorPseudosMap[css3Pseudo[1]];
if(css3PseudoOperatorType < 2 && css3Pseudo[2]) {// 'nth-child':0 and 'nth-last-child':1
if(!/\D/.test(css3Pseudo[2]))css3Pseudo_add = [null, 0, '%', css3Pseudo[2]];
else if(css3Pseudo[2] === 'even')css3Pseudo_add = [null, 2];
else if(css3Pseudo[2] === 'odd')css3Pseudo_add = [null, 2, '%', 1];
else css3Pseudo_add = css3Pseudo[2].match(RE__queryOneSelector__pseudoNthChildMatcher);
A = css3PseudoOperatorType ? "nodeIndexLast" : "nodeIndex";
B = css3PseudoOperatorType ? "lastChild" : "firstChild";
C = css3PseudoOperatorType ? "previousSibling" : "nextSibling";
}
}
selectorArr = selector = void 0;
//prepear
if(combinatorType == 1) {
if(!needCheck_id) {
needCheck_classes = needCheck_classes && !isNative_getElementsByClassName;
needCheck_tag = needCheck_tag && isNative_getElementsByClassName && !!classes;
}
else {
if(_can_useGetElementsByName_as_getElementById) {//workaround for IE
preResult = document.getElementsByName(id);
elementsById_Cache = [];
kr = -1;
while(child = preResult[++kr]) {
if(child.id == id) {
elementsById_Cache.push(child);
}
};
}
else {
//other browsers with no native querySelector support
//workaround from QSA by Dmitriy Pakhtinov ( spb.piksel@gmail.com | http://spb-piksel.ru/ )
elementsById_Cache = [];
preResult = [];
while(child = document.getElementById(id)) {
preResult.push(child);
if(child.id == id) {
elementsById_Cache.push(child);
}
child.setAttribute("id", id + " _");
};
kr = -1;
while(child = preResult[++kr]) {
child.setAttribute("id", id);
};
}
preResult = needCheck_id = void 0;
}
}
canWeReturnUnsafeArray = (!("length" in roots) || roots.length === 1) && !globalResultAsSparseArray && !css3Attr && !css3Pseudo && !needCheck_tag && !needCheck_classes && !needCheck_id;
do {
child = void 0;
switch(combinatorType) {
case 1://" " or ""
//if("all" in root && !root.all.length)continue;
if(!id) {//tagName or/and class
if(tag === "BODY" && root.nodeType === 9) {
preResult = [root.body];
needCheck_classes = !!classes;
canWeReturnUnsafeArray = canWeReturnUnsafeArray && !needCheck_classes;
}
else if(!classes || !isNative_getElementsByClassName) {
preResult = root.getElementsByTagName(tag || "*");
}
else {
preResult = root.getElementsByClassName(classes);
}
}
else {//id
preResult = [];
if(elementsById_Cache.length) {
kr = -1;
while(child = elementsById_Cache[++kr]) {
if(root === document || root.contains(child)){
preResult.push(child);
elementsById_Cache.splice(kr--, 1);
}
};
}
else return result;
}
child = preResult[0];
break;
case 2://">" W3C: "an F element preceded by an E element"
preResult = root.children;
child = preResult[0];
break;
case 3://"~" W3C: "an F element preceded by an E element"
nextRoot = roots[rootIndex + 1];
case 4://"+"
if(!(child = getNextElement(root)))continue;
default:
}
if(canWeReturnUnsafeArray)return preResult;
childrenIndex = 0;
if(child) do {
if((!needCheck_nodeType || child.nodeType === 1) && !(globalResultAsSparseArray && (indexIn_resultKeys = (child[sourceIndex_propertyName] || (child[sourceIndex_propertyName] = ++UUID))) in globalResult)) {
/*if(needCheck_tag && child.nodeName !== tag || needCheck_id && child.id !== id || needCheck_classes && !(child.className && klas.test(child.className))) {
resultKeys && (resultKeys[indexIn_resultKeys] = false);
continue;
}*/
//if(combinatorType === 1 && nextRoot && nextRoot.contains(root))continue;
if(match = !(needCheck_tag && child.nodeName.toUpperCase() !== tag || needCheck_id && child.id !== id || needCheck_classes && !(child.className && klas.test(child.className)))) {
if(css3Attr) {
kr = -1;
u = child.attributes;
while(match && (css3Attr_add = css3Attr[++kr]) && (match = (c = css3Attr_add[1]) in u)) {
if(c in attributeSpecialCase)nodeAttrCurrent_value = attributeSpecialCase[c](child);
else {
nodeAttrCurrent_value = u[c];
nodeAttrCurrent_value = (nodeAttrCurrent_value && (nodeAttrCurrent_value.specified || c in attributeSpecialSpecified) && nodeAttrCurrent_value.nodeValue !== "") ? nodeAttrCurrent_value.nodeValue : null;
}
a = css3Attr_add[2];
if(nodeAttrCurrent_value === null) {
if(!(match = a === 8))
match = false;
continue;
}
nodeAttrExpected_value = css3Attr_add[3];
// TODO: Проверить, что все опреации ^=, !=, *= и т.д. работают или ввести nodeAttrCurrent_value = child.getattribute(); if(nodeAttrCurrent_value)nodeAttrCurrent_value = nodeAttrCurrent_value + ''
/* from yass 0.3.9 http://yass.webo.in/
and edited by me :) */
/* function calls for CSS2/3 attributes selectors */
switch(a) {
/* W3C "an E element with a "nodeAttrCurrent_value" attribute" */
case 1://css3Attr[2] == ''
match = !!nodeAttrCurrent_value || nodeAttrCurrent_value === "";
break;
/*
W3C "an E element whose "nodeAttrCurrent_value" attribute nodeAttrExpected_value is
exactly equal to "nodeAttrExpected_value"
*/
case 2://'='
match = /*nodeAttrCurrent_value && */nodeAttrCurrent_value === nodeAttrExpected_value;
break;
/*
from w3.prg "an E element whose "nodeAttrCurrent_value" attribute nodeAttrExpected_value is
a list of space-separated nodeAttrExpected_value's, one of which is exactly
equal to "nodeAttrExpected_value"
*/
case 3://'&='
/* nodeAttrCurrent_value doesn't contain given nodeAttrExpected_value */
case 8://'!='
match = /*nodeAttrCurrent_value && */(new RegExp('(^| +)' + nodeAttrExpected_value + '($| +)').test(nodeAttrCurrent_value));
if(a === 8)match = !match;
break;
/*
from w3.prg "an E element whose "nodeAttrCurrent_value" attribute nodeAttrExpected_value
begins exactly with the string "nodeAttrExpected_value"
*/
case 4://'^='
/*
W3C "an E element whose "nodeAttrCurrent_value" attribute nodeAttrExpected_value
ends exactly with the string "nodeAttrExpected_value"
*/
case 5://'$='
/*
W3C "an E element whose "nodeAttrCurrent_value" attribute nodeAttrExpected_value
contains the substring "nodeAttrExpected_value"
*/
case 6://'*='
b = nodeAttrCurrent_value.indexOf(nodeAttrExpected_value);
match = a === 6 ? ~b : a === 5 ? (b == nodeAttrCurrent_value.length - nodeAttrExpected_value.length) : !b;
break;
/*
W3C "an E element whose "nodeAttrCurrent_value" attribute has
a hyphen-separated list of nodeAttrExpected_value's beginning (from the
left) with "nodeAttrExpected_value"
*/
case 7://'|='
match = (/*nodeAttrCurrent_value && */(nodeAttrCurrent_value === nodeAttrExpected_value || !!~nodeAttrCurrent_value.indexOf(nodeAttrExpected_value + '-')));
break;
case 9://'~='
match = /*nodeAttrCurrent_value && */!!~(" " + nodeAttrCurrent_value.replace(RE__queryOneSelector__spaces, " ") + " ").indexOf(" " + nodeAttrExpected_value + " ");
break;
}
}
}
if(match && css3Pseudo) {
/*
function calls for CSS2/3 modificatos. Specification taken from
http://www.w3.org/TR/2005/WD-css3-selectors-20051215/
on success return negative result.
*/
switch(css3PseudoOperatorType) {
/* W3C: "an E element, the n-th child of its parent" */
case 0://'nth-child':
/* W3C: "an E element, the n-th rs of its parent, counting from the last one" */
case 1://'nth-last-child':
if(!css3Pseudo_add[1] && !css3Pseudo_add[3])break;
c = child[A] || 0;
a = css3Pseudo_add[3] ? (css3Pseudo_add[2] === '%' ? -1 : 1) * css3Pseudo_add[3] : 0;
b = css3Pseudo_add[1];
if (c) {//check if we have already looked into siblings, using exando - very bad
match = !b ? !(c + a) : !((c + a) % b);
}
else {//in the other case just reverse logic for n and loop siblings
match = false;
brother = child.parentNode[B];
//c++;
do {//looping in rs to find if nth expression is correct
//nodeIndex expando used from Peppy / Sizzle/ jQuery
if (brother.nodeType == 1 &&
(brother[A] = ++c) &&
child === brother &&
(!b ? !(c + a) : !((c + a) % b))) {
match = true;
}
} while (!match && (brother = brother[C]));
}
break;
/* W3C: "an E element, only child of its parent" */
case 2://'only-child':
/* implementation was taken from jQuery.1.7 */
/* W3C: "an E element, first rs of its parent" */
case 3://'first-child':
/* implementation was taken from jQuery.1.7 */
brother = child;
while ((brother = brother.previousSibling) && brother.nodeType !== 1) {}
/* Check for node's existence */
match = !brother;
if(!match || css3PseudoOperatorType == 3)break;
/* W3C: "an E element, last rs of its parent" */
case 4://'last-child'://In this block we lose "rs" value
/* Check for node's existence */
match = !getNextElement(child);
break;
/* W3C: "an E element, root of the document" */
case 5://'root':
match = child.nodeName == "HTML";
break;
/*
Rrom w3.org: "an E element that has no rsren (including text nodes)".
Thx to John, from Sizzle, 2008-12-05, line 416
*/
case 6://'empty':
match = !child.firstChild;
/*
var n, i;
for (i = 0;
(n = e.childNodes[i]); i++) {
if (n.nodeType == 1 || n.nodeType == 3) return false
}
return true
*/
break;
/*
W3C: "a user interface element E which is checked
(for instance a radio-button or checkbox)"
*/
case 7://'checked':
match = !!child.checked;
break;
/*
W3C: "an element of type E in language "fr"
(the document language specifies how language is determined)"
*/
case 8://'lang':
match = (child.lang == css3Pseudo_add || _document_documentElement.lang == css3Pseudo_add);
break;
case 9://'enabled':
case 10://'disabled':
match = ("disabled" in child && "form" in child/*filter only form elements TODO::check it*/) && (css3PseudoOperatorType == 10 ? child.disabled === true && child.type !== 'hidden' : child.disabled === false);
break;
/* thx to John, from Sizzle, 2008-12-05, line 407 */
case 11://'selected':
// Accessing this property makes selected-by-default options in Safari work properly.
match = child.parentNode.selectedIndex && !!child.selected;//Тут уже Closure Compiler не удаляет нужный вызов
break;
case 12://'contains':
match = !!~(child.textContent || child.data || child.innerText || child.nodeValue || child.value || "").indexOf(css3Pseudo[2]);
break;
case 13://'not':
match = !_matchesSelector.call(child, css3Pseudo[2]);
break;
/*TODO::
default:
//Non-standart pseudo-classes
var f = $$N.nonStandartPseudoClasses[css3Pseudo[1]];
if(f)match = f(child);*/
}
}
}
if(match) {
if(onlyOne)return [child];
//result.push(child);
//resultKeys && (resultKeys[indexIn_resultKeys] = result.length - 1);
if(globalResultAsSparseArray) {
result[indexIn_resultKeys] = child;
}
else {
result.push(child);
}
//resultKeys && (resultKeys[indexIn_resultKeys] = true);
}
//else resultKeys && (resultKeys[indexIn_resultKeys] = false);
/*else if(indexIn_resultKeys && indexIn_resultKeys in resultKeys && (A = resultKeys[indexIn_resultKeys]) && A !== false) {
//sort result
result.splice(A, 1);
resultKeys[indexIn_resultKeys] = globalResult.length;
result.push(child);
}*/
}
}
while( child = combinatorTypeMoreThen_2 ? (combinatorType === 4 ? void 0 : child === nextRoot ? void 0 : getNextElement(child) ) : preResult[ ++childrenIndex ] );
}
while(root = roots[++rootIndex]);
return result;
}
/**
* @param {!string} selector Строка с CSS3-selector
* @param {boolean=} onlyOne only one need
* @param {(Node|Array.<Node>)=} root
* @this {Document|HTMLElement|Node} root
* @return {Array.<HTMLElement>}
* @version 4.0
*/
var queryManySelector = function queryManySelector(selector, onlyOne, root) {
//var rules = selector.replace(/ *([,>+~. ]) */g, "$1").match(/[^,]\w*/g),
root || (root = this);
var rt,
rules,
timeStamp;
selector = _String_trim.call(selector.replace(RE__queryManySelector__doubleSpaces, "$1"));
var result = [],
rule,
i = -1,
selElements = root,
el,
k,
l,
//resultKeys,
nextRule,
lastRule,
firstRule = true,
fail = false,
need_SparseArray,
result_isSparseArray;
rules = selector
.replace(RE__querySelector__arrtSpaceSeparated_toSafe, "@=")
.replace(RE__queryOneSelector__pseudoNthChildPlus, "-child\($1%$2\)")
.match(RE__queryManySelector__selectorsMatcher);
while((rule = rules[++i])) {
nextRule = rules[i + 1];
lastRule = !nextRule || nextRule.charAt(0) === ',';
//if(nextRule && nextRule.length > 1 && !resultKeys)resultKeys = {};
if(!fail) {
if(firstRule && ("nodeType" in root) && root.nodeType === 9 && rule.toUpperCase() === "BODY") {
selElements = [root.body];
lastRule ? (result = selElements) : result.concat(selElements);
}
else if(firstRule && rule === ":root") {
selElements = [_document_documentElement];
lastRule && (result = selElements);
}
else if(selElements && (!(root = selElements) || selElements.length === 0)) {//No result in previous rule -> Nothing to do
selElements = null;
fail = true;
}
else if(!fail) {//CSS3 selector
if(need_SparseArray = !!(lastRule && (result_isSparseArray || nextRule || root.length > 1)))result_isSparseArray = true;
selElements = queryOneSelector(rule, root, lastRule ? result : [], need_SparseArray, null, onlyOne && lastRule/*, lastRule && resultKeys || !firstRule && root.length > 1 && {}*/);
}
}
//If last rule in this selector
if(firstRule = lastRule) {
if(!result.length && selElements) {
result_isSparseArray = false;
result = _Array_from(selElements);
}
selElements = null;
root = this;
fail = false;
}
if(!nextRule || nextRule === ",")break;
}
if(!hasSourceIndex) {
result.sort(queryManySelector_sort);
}
return result_isSparseArray ?
_Array_from(result, true) :
result;
};
function queryManySelector_sort(a, b) {
return a === b ? 0 : a.compareDocumentPosition( b ) & 4 ? -1 : 1;
}
/**
* @param {!string} selector
* @this {HTMLElement}
* @return {boolean}
*/
function _matchesSelector(selector) {
if(!selector)return false;
if(selector === "*")return true;
if(selector === ":root" && this === _document_documentElement)return true;
if(selector === "body" && this === document.body)return true;
//selector = _String_trim.call(selector.replace(RE__queryManySelector__doubleSpaces, "$1"));
var thisObj = this,
isSimpleSelector,
tmp,
match = false,
i,
str;
selector = _String_trim.call(selector);
if(isSimpleSelector = selector.match(RE__selector__easySelector)) {
switch (selector.charAt(0)) {
case '#':
return thisObj.id === selector.slice(1);
break;
default:
match = !(tmp = isSimpleSelector[2]) || thisObj.className && (new RegExp(tmp.replace(RE__querySelector__dottes, " ").replace(RE__getElementsByClassName, STRING_FOR_RE__getElementsByClassName))).test(thisObj.className);
return match && !(tmp = isSimpleSelector[1]) || (thisObj.tagName && thisObj.tagName.toUpperCase() === tmp.toUpperCase());
break;
}
}
else if(!RE_matchSelector__isSimpleSelector.test(selector)) {//easy selector
tmp = queryOneSelector(selector, null, false, null, thisObj, true);
return tmp[0] === thisObj;
}
else {
tmp = queryManySelector.call(thisObj.ownerDocument, selector);
for ( i in tmp ) if(Object.prototype.hasOwnProperty.call(tmp, i)) {
match = tmp[i] === thisObj;
if(match)return true;
}
return false;
}
}
//SHIM export
if(!_document_documentElement.matchesSelector)_document_documentElement.matchesSelector = _document_documentElement.webkitMatchesSelector ||
_document_documentElement.mozMatchesSelector ||
_document_documentElement.msMatchesSelector ||
_document_documentElement.oMatchesSelector ||
"querySelector" in document ? function(selector) {
if(!selector)return false;
if(selector === "*")return true;
if(selector === ":root" && this === _document_documentElement)return true;
if(selector === "body" && this === document.body)return true;
var thisObj = this,
parent,
i,
str,
tmp,
match = false;
if(!RE_matchSelector__isSimpleSelector.test(selector) && (parent = thisObj.parentNode) && "querySelector" in parent) {
match = parent.querySelector(selector) === thisObj;
}
if(!match && (parent = thisObj.ownerDocument)) {
tmp = parent.querySelectorAll(selector);
for (i in tmp ) if(Object.prototype.hasOwnProperty.call(tmp, i)) {
match = tmp[i] === thisObj;
if(match)return true;
}
}
return match;
} : _matchesSelector;
if(!document.querySelectorAll) {
/**
* @param {!string} selector
* @param {(Node|Array.<Node>)=} nodesRef
* @this {Document|Node}
* @return {Array.<Node>}
*/
document.querySelectorAll = function(selector, nodesRef) {
return queryManySelector.call(this, selector, false, nodesRef);
}
}
if(!document.querySelector) {
/**
* @param {!string} selector
* @param {(Node|Array.<Node>)=} nodesRef
* @this {Document|Node}
* @return {Node}
*/
document.querySelector = function(selector, nodesRef) {
return queryManySelector.call(this, selector, true, nodesRef)[0] || null;
}
}
if(!_document_documentElement.getElementsByClassName)_document_documentElement.getElementsByClassName = _shim_getElementsByClassName;
//SHIM export
//export for tests
/*
window["query_test"] = function(selector, root) {
return queryManySelector.call(root || document, selector);
}*/
//export for tests
})(window);
/* MIT License (c) copyright Egor Halimonenko (termi1uc1@gmail.com) */
;(function(){"use strict";var o=!0,r=null,t=!1;function F(a,c,d){d||(d=this);for(var a=G.call(a.replace(ba,"$1")),e=[],g,N=-1,b=d,l,j,D=o,z=t,h,a=a.replace(ca,"@=").replace(da,"-child($1%$2)").match(ea);g=a[++N];){l=a[N+1];j=!l||","===l.charAt(0);if(!z)if(D&&"nodeType"in d&&9===d.nodeType&&"BODY"===g.toUpperCase())b=[d.body],j&&(e=b);else if(D&&":root"===g)b=[i],j&&(e=b);else if(b&&(!(d=b)||0===b.length))b=r,z=o;else if(!z){if(b=!(!j||!h&&!(l||1<d.length)))h=o;b=H(g,d,j?e:[],b,r,c&&j)}if(D=j)!e.length&&b&&(h=t,e=I(b)),b=r,d=this,z=
t;if(!l||","===l)break}J||e.sort(fa);return h?I(e,o):e}function I(a,c){var d=a.length>>>0,e;if(!c){try{e=ga.call(a)}catch(g){}if(e&&e.length===d)return e}e=[];for(var i=0;i<d;i++)i in a&&e.push(a[i]);return e}function H(a,c,d,e,g,N){var b=a.match(ha),a=d||[],l=!!g,j=l&&(c={})||(!c?document:"length"in c?c[0]:c),D,z=0,h,E=ia[b[1]||""]||0,F=2<E,A=b[2],K=!!A,u=b[3],O=!!u,w=b[4],B=!!w,G="*"===A,H,f,P,q,v,x,n,y,I,p,C,m,k,s,R,S,J,M;K&&(A=G?void 0:A.replace("|",":").toUpperCase());if(B&&(w=w.replace(X," "),
!L||1!==E))I=RegExp(w.replace(T,U));l&&(E=0);if(l=b[5]){l=ja.call(l,"][");for(h=-1;q=l[++h];){q=l[h]=q.match(ka);Y;k=q[1];if("'"===(m=k.charAt(0))||'"'===m&&k.substr(-1)===m)q[1]=V.call(k,1,k.length-2);q[2]=Y[q[2]];if((k=q[3])&&("'"===(m=k.charAt(0))||'"'===m&&k.substr(-1)===m))q[3]=V.call(k,1,k.length-2)}}if(p=b[6])p=p.match(la),x=ma[p[1]],2>x&&p[2]&&(v=/\D/.test(p[2])?"even"===p[2]?[r,2]:"odd"===p[2]?[r,2,"%",1]:p[2].match(na):[r,0,"%",p[2]],S=x?"nodeIndexLast":"nodeIndex",J=x?"lastChild":"firstChild",
M=x?"previousSibling":"nextSibling");if(1==E)if(O){if(oa){g=document.getElementsByName(u);C=[];for(h=-1;b=g[++h];)b.id==u&&C.push(b)}else{C=[];for(g=[];b=document.getElementById(u);)g.push(b),b.id==u&&C.push(b),b.setAttribute("id",u+" _");for(h=-1;b=g[++h];)b.setAttribute("id",u)}g=O=void 0}else B=B&&!L,K=K&&L&&!!w;P=(!("length"in c)||1===c.length)&&!e&&!l&&!p&&!K&&!B&&!O;do{b=void 0;switch(E){case 1:if(u)if(g=[],C.length)for(h=-1;b=C[++h];){if(j===document||j.contains(b))g.push(b),C.splice(h--,1)}else return a;
else"BODY"===A&&9===j.nodeType?(g=[j.body],B=!!w,P=P&&!B):g=!w||!L?j.getElementsByTagName(A||"*"):j.getElementsByClassName(w);b=g[0];break;case 2:g=j.children;b=g[0];break;case 3:D=c[z+1];case 4:if(!(b=W(j)))continue}if(P)return g;j=0;if(b){do if((!G||1===b.nodeType)&&!(e&&(H=b[Q]||(b[Q]=++pa))in d)){if(f=!(K&&b.nodeName.toUpperCase()!==A||O&&b.id!==u||B&&(!b.className||!I.test(b.className)))){if(l){h=-1;for(R=b.attributes;f&&(q=l[++h])&&(f=(s=q[1])in R);)if(n=s in Z?Z[s](b):(n=R[s])&&(n.specified||
s in qa)&&""!==n.nodeValue?n.nodeValue:r,m=q[2],n===r){if(!(f=8===m))f=t}else switch(y=q[3],m){case 1:f=!!n||""===n;break;case 2:f=n===y;break;case 3:case 8:f=RegExp("(^| +)"+y+"($| +)").test(n);8===m&&(f=!f);break;case 4:case 5:case 6:k=n.indexOf(y);f=6===m?~k:5===m?k==n.length-y.length:!k;break;case 7:f=n===y||!!~n.indexOf(y+"-");break;case 9:f=!!~(" "+n.replace(ra," ")+" ").indexOf(" "+y+" ")}}if(f&&p)switch(x){case 0:case 1:if(!v[1]&&!v[3])break;s=b[S]||0;m=v[3]?("%"===v[2]?-1:1)*v[3]:0;k=v[1];
if(s)f=!k?!(s+m):!((s+m)%k);else{f=t;h=b.parentNode[J];do if(1==h.nodeType&&(h[S]=++s)&&b===h&&(!k?!(s+m):!((s+m)%k)))f=o;while(!f&&(h=h[M]))}break;case 2:case 3:for(h=b;(h=h.previousSibling)&&1!==h.nodeType;);f=!h;if(!f||3==x)break;case 4:f=!W(b);break;case 5:f="HTML"==b.nodeName;break;case 6:f=!b.firstChild;break;case 7:f=!!b.checked;break;case 8:f=b.lang==v||i.lang==v;break;case 9:case 10:f="disabled"in b&&"form"in b&&(10==x?b.disabled===o&&"hidden"!==b.type:b.disabled===t);break;case 11:f=b.parentNode.selectedIndex&&
!!b.selected;break;case 12:f=!!~(b.textContent||b.data||b.innerText||b.nodeValue||b.value||"").indexOf(p[2]);break;case 13:f=!$.call(b,p[2])}}if(f){if(N)return[b];e?a[H]=b:a.push(b)}}while(b=F?4===E?void 0:b===D?void 0:W(b):g[++j])}}while(j=c[++z]);return a}function fa(a,c){return a===c?0:a.compareDocumentPosition(c)&4?-1:1}function $(a){if(!a)return t;if("*"===a||":root"===a&&this===i||"body"===a&&this===document.body)return o;var c,d,e=t,g,a=G.call(a);if(c=a.match(sa))switch(a.charAt(0)){case "#":return this.id===
a.slice(1);default:return(e=!(d=c[2])||this.className&&RegExp(d.replace(X," ").replace(T,U)).test(this.className))&&!(d=c[1])||this.tagName&&this.tagName.toUpperCase()===d.toUpperCase()}else{if(M.test(a)){d=F.call(this.ownerDocument,a);for(g in d)if(Object.prototype.hasOwnProperty.call(d,g)&&(e=d[g]===this))return o;return t}d=H(a,r,t,r,this,o);return d[0]===this}}var T=/\s*(\S+)\s*/g,U="(?=(^|.*\\s)$1(\\s|$))",sa=/^([\w-\|]+)?((?:\.(?:[\w-]+))+)?$|^#([\w-]+$)/,ba=/\s*([,>+~ ])\s*/g,ca=/\~\=/g,ea=
/(^[>+~ ]?|,|\>|\+|~| ).*?(?=[,>+~ ]|$)/g,X=/\./g,ra=/\s/g,ha=/^([,>+~ ])?([\w-\|\*]*)\#?([\w-]*)((?:\.?[\w-])*)(\[.+\])?(?:\:(.+))?$/,ka=/^\[?(.*?)(?:([\*~&\^\$\@!]?=)(.*?))?\]?$/,la=/^([^(]+)(?:\(([^)]+)\))?$/,da=/\-child\((\dn)\+(\d)\)/g,na=/(?:([-]?\d*)n)?(?:(%|-)(\d*))?/,M=/([,>+~ ])/,ia={"":1," ":1,",":1,">":2,"~":3,"+":4},Y={"":1,"=":2,"&=":3,"^=":4,"$=":5,"*=":6,"|=":7,"!=":8,"@=":9},ma={"nth-child":0,"nth-last-child":1,"only-child":2,"first-child":3,"last-child":4,root:5,empty:6,checked:7,
lang:8,enabled:9,disabled:10,selected:11,contains:12,not:13},Z={href:function(a){return a.getAttribute("href",2)}},qa={coords:1,id:1,name:1},i=document.documentElement,G=String.prototype.trim||function(){for(var a=this.replace(/^\s+/,""),c=/\s/,d=a.length;c.test(a.charAt(--d)););return a.slice(0,d+1)},ja=String.prototype.split,V=String.prototype.substr,aa,L=i.getElementsByClassName&&80>(i.getElementsByClassName+"").length,ga=Array.prototype.slice,oa=function(){var a=t,c="_"+Math.random(),d=document.createElement("br");
i.appendChild(d).id=c;try{a=document.getElementsByName(c)[0].id===c}catch(e){a=t}finally{i.removeChild(d)}return a}(),Q="sourceIndex",J=Q in i,pa=1,W="nextElementSibling"in i?function(a){return a.nextElementSibling}:function(a){for(;(a=a.nextSibling)&&1!=a.nodeType;);return a};J||(Q="uniqueId");"b"!=="ab".substr(-1)&&(String.prototype.substr=function(a,c){return V.call(this,0>a?0>(a=this.length+a)?0:a:a,c)});L||(aa=function(a){var c=[],d=this.all,e,g=-1;if(d.length)for(a=RegExp((a+"").replace(T,U));e=
d[++g];)e.className&&a.test(e.className)&&c.push(e);return c});i.matchesSelector||(i.matchesSelector=i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.a||"querySelector"in document?function(a){if(!a)return t;if(a==="*"||a===":root"&&this===i||a==="body"&&this===document.body)return o;var c,d,e=t;if(!M.test(a)&&(c=this.parentNode)&&"querySelector"in c)e=c.querySelector(a)===this;if(!e&&(c=this.ownerDocument)){a=c.querySelectorAll(a);for(d in a)if(Object.prototype.hasOwnProperty.call(a,
d))if(e=a[d]===this)return o}return e}:$);document.querySelectorAll||(document.querySelectorAll=function(a,c){return F.call(this,a,t,c)});document.querySelector||(document.querySelector=function(a,c){return F.call(this,a,o,c)[0]||r});i.getElementsByClassName||(i.getElementsByClassName=aa)})(window);
<html>
<script>
(function(){"use strict";var o=!0,r=null,t=!1;function F(a,c,d){d||(d=this);for(var a=G.call(a.replace(ba,"$1")),e=[],g,N=-1,b=d,l,j,D=o,z=t,h,a=a.replace(ca,"@=").replace(da,"-child($1%$2)").match(ea);g=a[++N];){l=a[N+1];j=!l||","===l.charAt(0);if(!z)if(D&&"nodeType"in d&&9===d.nodeType&&"BODY"===g.toUpperCase())b=[d.body],j&&(e=b);else if(D&&":root"===g)b=[i],j&&(e=b);else if(b&&(!(d=b)||0===b.length))b=r,z=o;else if(!z){if(b=!(!j||!h&&!(l||1<d.length)))h=o;b=H(g,d,j?e:[],b,r,c&&j)}if(D=j)!e.length&&b&&(h=t,e=I(b)),b=r,d=this,z=
t;if(!l||","===l)break}J||e.sort(fa);return h?I(e,o):e}function I(a,c){var d=a.length>>>0,e;if(!c){try{e=ga.call(a)}catch(g){}if(e&&e.length===d)return e}e=[];for(var i=0;i<d;i++)i in a&&e.push(a[i]);return e}function H(a,c,d,e,g,N){var b=a.match(ha),a=d||[],l=!!g,j=l&&(c={})||(!c?document:"length"in c?c[0]:c),D,z=0,h,E=ia[b[1]||""]||0,F=2<E,A=b[2],K=!!A,u=b[3],O=!!u,w=b[4],B=!!w,G="*"===A,H,f,P,q,v,x,n,y,I,p,C,m,k,s,R,S,J,M;K&&(A=G?void 0:A.replace("|",":").toUpperCase());if(B&&(w=w.replace(X," "),
!L||1!==E))I=RegExp(w.replace(T,U));l&&(E=0);if(l=b[5]){l=ja.call(l,"][");for(h=-1;q=l[++h];){q=l[h]=q.match(ka);Y;k=q[1];if("'"===(m=k.charAt(0))||'"'===m&&k.substr(-1)===m)q[1]=V.call(k,1,k.length-2);q[2]=Y[q[2]];if((k=q[3])&&("'"===(m=k.charAt(0))||'"'===m&&k.substr(-1)===m))q[3]=V.call(k,1,k.length-2)}}if(p=b[6])p=p.match(la),x=ma[p[1]],2>x&&p[2]&&(v=/\D/.test(p[2])?"even"===p[2]?[r,2]:"odd"===p[2]?[r,2,"%",1]:p[2].match(na):[r,0,"%",p[2]],S=x?"nodeIndexLast":"nodeIndex",J=x?"lastChild":"firstChild",
M=x?"previousSibling":"nextSibling");if(1==E)if(O){if(oa){g=document.getElementsByName(u);C=[];for(h=-1;b=g[++h];)b.id==u&&C.push(b)}else{C=[];for(g=[];b=document.getElementById(u);)g.push(b),b.id==u&&C.push(b),b.setAttribute("id",u+" _");for(h=-1;b=g[++h];)b.setAttribute("id",u)}g=O=void 0}else B=B&&!L,K=K&&L&&!!w;P=(!("length"in c)||1===c.length)&&!e&&!l&&!p&&!K&&!B&&!O;do{b=void 0;switch(E){case 1:if(u)if(g=[],C.length)for(h=-1;b=C[++h];){if(j===document||j.contains(b))g.push(b),C.splice(h--,1)}else return a;
else"BODY"===A&&9===j.nodeType?(g=[j.body],B=!!w,P=P&&!B):g=!w||!L?j.getElementsByTagName(A||"*"):j.getElementsByClassName(w);b=g[0];break;case 2:g=j.children;b=g[0];break;case 3:D=c[z+1];case 4:if(!(b=W(j)))continue}if(P)return g;j=0;if(b){do if((!G||1===b.nodeType)&&!(e&&(H=b[Q]||(b[Q]=++pa))in d)){if(f=!(K&&b.nodeName.toUpperCase()!==A||O&&b.id!==u||B&&(!b.className||!I.test(b.className)))){if(l){h=-1;for(R=b.attributes;f&&(q=l[++h])&&(f=(s=q[1])in R);)if(n=s in Z?Z[s](b):(n=R[s])&&(n.specified||
s in qa)&&""!==n.nodeValue?n.nodeValue:r,m=q[2],n===r){if(!(f=8===m))f=t}else switch(y=q[3],m){case 1:f=!!n||""===n;break;case 2:f=n===y;break;case 3:case 8:f=RegExp("(^| +)"+y+"($| +)").test(n);8===m&&(f=!f);break;case 4:case 5:case 6:k=n.indexOf(y);f=6===m?~k:5===m?k==n.length-y.length:!k;break;case 7:f=n===y||!!~n.indexOf(y+"-");break;case 9:f=!!~(" "+n.replace(ra," ")+" ").indexOf(" "+y+" ")}}if(f&&p)switch(x){case 0:case 1:if(!v[1]&&!v[3])break;s=b[S]||0;m=v[3]?("%"===v[2]?-1:1)*v[3]:0;k=v[1];
if(s)f=!k?!(s+m):!((s+m)%k);else{f=t;h=b.parentNode[J];do if(1==h.nodeType&&(h[S]=++s)&&b===h&&(!k?!(s+m):!((s+m)%k)))f=o;while(!f&&(h=h[M]))}break;case 2:case 3:for(h=b;(h=h.previousSibling)&&1!==h.nodeType;);f=!h;if(!f||3==x)break;case 4:f=!W(b);break;case 5:f="HTML"==b.nodeName;break;case 6:f=!b.firstChild;break;case 7:f=!!b.checked;break;case 8:f=b.lang==v||i.lang==v;break;case 9:case 10:f="disabled"in b&&"form"in b&&(10==x?b.disabled===o&&"hidden"!==b.type:b.disabled===t);break;case 11:f=b.parentNode.selectedIndex&&
!!b.selected;break;case 12:f=!!~(b.textContent||b.data||b.innerText||b.nodeValue||b.value||"").indexOf(p[2]);break;case 13:f=!$.call(b,p[2])}}if(f){if(N)return[b];e?a[H]=b:a.push(b)}}while(b=F?4===E?void 0:b===D?void 0:W(b):g[++j])}}while(j=c[++z]);return a}function fa(a,c){return a===c?0:a.compareDocumentPosition(c)&4?-1:1}function $(a){if(!a)return t;if("*"===a||":root"===a&&this===i||"body"===a&&this===document.body)return o;var c,d,e=t,g,a=G.call(a);if(c=a.match(sa))switch(a.charAt(0)){case "#":return this.id===
a.slice(1);default:return(e=!(d=c[2])||this.className&&RegExp(d.replace(X," ").replace(T,U)).test(this.className))&&!(d=c[1])||this.tagName&&this.tagName.toUpperCase()===d.toUpperCase()}else{if(M.test(a)){d=F.call(this.ownerDocument,a);for(g in d)if(Object.prototype.hasOwnProperty.call(d,g)&&(e=d[g]===this))return o;return t}d=H(a,r,t,r,this,o);return d[0]===this}}var T=/\s*(\S+)\s*/g,U="(?=(^|.*\\s)$1(\\s|$))",sa=/^([\w-\|]+)?((?:\.(?:[\w-]+))+)?$|^#([\w-]+$)/,ba=/\s*([,>+~ ])\s*/g,ca=/\~\=/g,ea=
/(^[>+~ ]?|,|\>|\+|~| ).*?(?=[,>+~ ]|$)/g,X=/\./g,ra=/\s/g,ha=/^([,>+~ ])?([\w-\|\*]*)\#?([\w-]*)((?:\.?[\w-])*)(\[.+\])?(?:\:(.+))?$/,ka=/^\[?(.*?)(?:([\*~&\^\$\@!]?=)(.*?))?\]?$/,la=/^([^(]+)(?:\(([^)]+)\))?$/,da=/\-child\((\dn)\+(\d)\)/g,na=/(?:([-]?\d*)n)?(?:(%|-)(\d*))?/,M=/([,>+~ ])/,ia={"":1," ":1,",":1,">":2,"~":3,"+":4},Y={"":1,"=":2,"&=":3,"^=":4,"$=":5,"*=":6,"|=":7,"!=":8,"@=":9},ma={"nth-child":0,"nth-last-child":1,"only-child":2,"first-child":3,"last-child":4,root:5,empty:6,checked:7,
lang:8,enabled:9,disabled:10,selected:11,contains:12,not:13},Z={href:function(a){return a.getAttribute("href",2)}},qa={coords:1,id:1,name:1},i=document.documentElement,G=String.prototype.trim||function(){for(var a=this.replace(/^\s+/,""),c=/\s/,d=a.length;c.test(a.charAt(--d)););return a.slice(0,d+1)},ja=String.prototype.split,V=String.prototype.substr,aa,L=i.getElementsByClassName&&80>(i.getElementsByClassName+"").length,ga=Array.prototype.slice,oa=function(){var a=t,c="_"+Math.random(),d=document.createElement("br");
i.appendChild(d).id=c;try{a=document.getElementsByName(c)[0].id===c}catch(e){a=t}finally{i.removeChild(d)}return a}(),Q="sourceIndex",J=Q in i,pa=1,W="nextElementSibling"in i?function(a){return a.nextElementSibling}:function(a){for(;(a=a.nextSibling)&&1!=a.nodeType;);return a};J||(Q="uniqueId");"b"!=="ab".substr(-1)&&(String.prototype.substr=function(a,c){return V.call(this,0>a?0>(a=this.length+a)?0:a:a,c)});L||(aa=function(a){var c=[],d=this.all,e,g=-1;if(d.length)for(a=RegExp((a+"").replace(T,U));e=
d[++g];)e.className&&a.test(e.className)&&c.push(e);return c});i.matchesSelector||(i.matchesSelector=i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.a||"querySelector"in document?function(a){if(!a)return t;if(a==="*"||a===":root"&&this===i||a==="body"&&this===document.body)return o;var c,d,e=t;if(!M.test(a)&&(c=this.parentNode)&&"querySelector"in c)e=c.querySelector(a)===this;if(!e&&(c=this.ownerDocument)){a=c.querySelectorAll(a);for(d in a)if(Object.prototype.hasOwnProperty.call(a,
d))if(e=a[d]===this)return o}return e}:$);document.querySelectorAll||(document.querySelectorAll=function(a,c){return F.call(this,a,t,c)});document.querySelector||(document.querySelector=function(a,c){return F.call(this,a,o,c)[0]||r});i.getElementsByClassName||(i.getElementsByClassName=aa)})(window);
var _matchesSelector = function(node, selector) {
return node === document ? selector === ":root" :
node.matchesSelector ? node.matchesSelector(selector) :
document.documentElement.matchesSelector.call(node, selector)
}
, $$ = function(node, selector) {
return node.querySelectorAll ? node.querySelectorAll(selector) :
document.querySelectorAll.call(node, selector);
}
, $ = function(node, selector) {
return node.querySelector ? node.querySelector(selector) :
document.querySelector.call(node, selector);
}
window.onload = function() {
var divClas1 = $(document, ".clas1"),
divClas2 = $$(divClas1, ".clas2")[0],
result = "";
for(var i = 0 ; i < divClas2.childNodes.length ; i++) {
result += ("child: '" + divClas2.childNodes[i] + "(" + divClas2.childNodes[i].nodeName + (divClas2.childNodes[i].id ? "#" + divClas2.childNodes[i].id : "") + (divClas2.childNodes[i].className ? "." + divClas2.childNodes[i].className : "") + ") is mathes: " + _matchesSelector(divClas2.childNodes[i], ".clas3") + "\n");
}
alert(result)
}
</script>
<div class=clas1>
<div class=clas2>
<div class=clas3 id=test>
test
</div>
</div>
<div class=clas2>
<div class=clas3>
test
</div>
</div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment