summaryrefslogtreecommitdiff
path: root/school/node_modules/nwsapi/src
diff options
context:
space:
mode:
Diffstat (limited to 'school/node_modules/nwsapi/src')
-rw-r--r--school/node_modules/nwsapi/src/modules/nwsapi-jquery.js135
-rw-r--r--school/node_modules/nwsapi/src/modules/nwsapi-traversal.js90
-rw-r--r--school/node_modules/nwsapi/src/nwsapi.js1807
3 files changed, 2032 insertions, 0 deletions
diff --git a/school/node_modules/nwsapi/src/modules/nwsapi-jquery.js b/school/node_modules/nwsapi/src/modules/nwsapi-jquery.js
new file mode 100644
index 0000000..961cb30
--- /dev/null
+++ b/school/node_modules/nwsapi/src/modules/nwsapi-jquery.js
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007-2017 Diego Perini
+ * All rights reserved.
+ *
+ * this is just a small example to show
+ * how an extension for NWMatcher could be
+ * adapted to handle special jQuery selectors
+ *
+ * Child Selectors
+ * :even, :odd, :eq, :lt, :gt, :first, :last, :nth
+ *
+ * Pseudo Selectors
+ * :has, :button, :header, :input, :checkbox, :radio, :file, :image
+ * :password, :reset, :submit, :text, :hidden, :visible, :parent
+ *
+ */
+
+// for structural pseudo-classes extensions
+NW.Dom.registerSelector(
+ 'jquery:child',
+ /^\:((?:(nth|eq|lt|gt)\(([^()]*)\))|(?:even|odd|first|last))(.*)/i,
+ (function(global) {
+
+ return function(match, source, mode, callback) {
+
+ var status = true,
+ macro = mode ? NW.Dom.S_BODY : NW.Dom.M_BODY;
+
+ macro = macro.replace('@', typeof callback == 'function' ? (mode ? NW.Dom.S_TEST : NW.Dom.M_TEST) : '');
+
+ switch (match[1].toLowerCase()) {
+ case 'odd':
+ source = source.replace(macro, 'if((n=n^1)==0){' + macro + '}');
+ break;
+ case 'even':
+ source = source.replace(macro, 'if((n=n^1)==1){' + macro + '}');
+ break;
+ case 'first':
+ source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[0]===e){' + source + '}';
+ break;
+ case 'last':
+ source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[n.length-1]===e){' + source + '}';
+ break;
+ default:
+ switch (match[2].toLowerCase()) {
+ case 'nth':
+ source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[' + match[3] + ']===e){' + source + '}';
+ break;
+ case 'eq':
+ source = source.replace(macro, 'if(x++==' + match[3] + '){' + macro + '}');
+ break;
+ case 'lt':
+ source = source.replace(macro, 'if(x++<' + match[3] + '){' + macro + '}');
+ break;
+ case 'gt':
+ source = source.replace(macro, 'if(x++>' + match[3] + '){' + macro + '}');
+ break;
+ default:
+ status = false;
+ break;
+ }
+ break;
+ }
+
+ // compiler will add this to "source"
+ return {
+ 'source': source,
+ 'status': status,
+ 'modvar': 'x=0'
+ };
+
+ };
+
+ })(this));
+
+// for element pseudo-classes extensions
+NW.Dom.registerSelector(
+ 'jquery:pseudo',
+ /^\:(has|checkbox|file|image|password|radio|reset|submit|text|button|input|header|hidden|visible|parent)(?:\(\s*(["']*)?([^'"()]*)\2\s*\))?(.*)/i,
+ (function(global) {
+
+ return function(match, source, mode, callback) {
+
+ var status = true,
+ macro = mode ? NW.Dom.S_BODY : NW.Dom.M_BODY;
+
+ macro = macro.replace('@', typeof callback == 'function' ? (mode ? NW.Dom.S_TEST : NW.Dom.M_TEST) : '');
+
+ switch(match[1].toLowerCase()) {
+ case 'has':
+ source = source.replace(macro, 'if(e.getElementsByTagName("' + match[3].replace(/^\s|\s$/g, '') + '")[0]){' + macro + '}');
+ break;
+ case 'checkbox':
+ case 'file':
+ case 'image':
+ case 'password':
+ case 'radio':
+ case 'reset':
+ case 'submit':
+ case 'text':
+ // :checkbox, :file, :image, :password, :radio, :reset, :submit, :text
+ source = 'if(/^' + match[1] + '$/i.test(e.type)){' + source + '}';
+ break;
+ case 'button':
+ source = 'if(/^button$/i.test(e.nodeName)){' + source + '}';
+ break;
+ case 'input':
+ source = 'if(/^(?:button|input|select|textarea)$/i.test(e.nodeName)){' + source + '}';
+ break;
+ case 'header':
+ source = 'if(/^h[1-6]$/i.test(e.nodeName)){' + source + '}';
+ break;
+ case 'hidden':
+ source = 'if(!e.offsetWidth&&!e.offsetHeight){' + source + '}';
+ break;
+ case 'visible':
+ source = 'if(e.offsetWidth||e.offsetHeight){' + source + '}';
+ break;
+ case 'parent':
+ source = 'if(e.firstChild){' + source + '}';
+ break;
+ default:
+ status = false;
+ break;
+ }
+
+ // compiler will add this to "source"
+ return {
+ 'source': source,
+ 'status': status
+ };
+
+ };
+
+ })(this));
diff --git a/school/node_modules/nwsapi/src/modules/nwsapi-traversal.js b/school/node_modules/nwsapi/src/modules/nwsapi-traversal.js
new file mode 100644
index 0000000..9d2b62f
--- /dev/null
+++ b/school/node_modules/nwsapi/src/modules/nwsapi-traversal.js
@@ -0,0 +1,90 @@
+/*
+ * Element Traversal methods from Juriy Zaytsev (kangax)
+ * used to emulate Prototype up/down/previous/next methods
+ */
+
+(function(D){
+
+ // TODO: all of this needs tests
+ var match = D.match, select = D.select, root = document.documentElement,
+
+ // Use the Element Traversal API if available.
+ nextElement = 'nextElementSibling',
+ previousElement = 'previousElementSibling',
+ parentElement = 'parentElement';
+
+ // Fall back to the DOM Level 1 API.
+ if (!(nextElement in root)) nextElement = 'nextSibling';
+ if (!(previousElement in root)) previousElement = 'previousSibling';
+ if (!(parentElement in root)) parentElement = 'parentNode';
+
+ function walkElements(property, element, expr) {
+ var i = 0, isIndex = typeof expr == 'number';
+ if (typeof expr == 'undefined') {
+ isIndex = true;
+ expr = 0;
+ }
+ while ((element = element[property])) {
+ if (element.nodeType != 1) continue;
+ if (isIndex) {
+ ++i;
+ if (i == expr) return element;
+ } else if (match(element, expr)) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @method up
+ * @param {HTMLElement} element element to walk from
+ * @param {String | Number} expr CSS expression or an index
+ * @return {HTMLElement | null}
+ */
+ function up(element, expr) {
+ return walkElements(parentElement, element, expr);
+ }
+ /**
+ * @method next
+ * @param {HTMLElement} element element to walk from
+ * @param {String | Number} expr CSS expression or an index
+ * @return {HTMLElement | null}
+ */
+ function next(element, expr) {
+ return walkElements(nextElement, element, expr);
+ }
+ /**
+ * @method previous
+ * @param {HTMLElement} element element to walk from
+ * @param {String | Number} expr CSS expression or an index
+ * @return {HTMLElement | null}
+ */
+ function previous(element, expr) {
+ return walkElements(previousElement, element, expr);
+ }
+ /**
+ * @method down
+ * @param {HTMLElement} element element to walk from
+ * @param {String | Number} expr CSS expression or an index
+ * @return {HTMLElement | null}
+ */
+ function down(element, expr) {
+ var isIndex = typeof expr == 'number', descendants, index, descendant;
+ if (expr === null) {
+ element = element.firstChild;
+ while (element && element.nodeType != 1) element = element[nextElement];
+ return element;
+ }
+ if (!isIndex && match(element, expr) || isIndex && expr === 0) return element;
+ descendants = select('*', element);
+ if (isIndex) return descendants[expr] || null;
+ index = 0;
+ while ((descendant = descendants[index]) && !match(descendant, expr)) { ++index; }
+ return descendant || null;
+ }
+ D.up = up;
+ D.down = down;
+ D.next = next;
+ D.previous = previous;
+})(NW.Dom);
diff --git a/school/node_modules/nwsapi/src/nwsapi.js b/school/node_modules/nwsapi/src/nwsapi.js
new file mode 100644
index 0000000..d5ec57c
--- /dev/null
+++ b/school/node_modules/nwsapi/src/nwsapi.js
@@ -0,0 +1,1807 @@
+/*
+ * Copyright (C) 2007-2019 Diego Perini
+ * All rights reserved.
+ *
+ * nwsapi.js - Fast CSS Selectors API Engine
+ *
+ * Author: Diego Perini <diego.perini at gmail com>
+ * Version: 2.2.0
+ * Created: 20070722
+ * Release: 20220901
+ *
+ * License:
+ * http://javascript.nwbox.com/nwsapi/MIT-LICENSE
+ * Download:
+ * http://javascript.nwbox.com/nwsapi/nwsapi.js
+ */
+
+(function Export(global, factory) {
+
+ 'use strict';
+
+ if (typeof module == 'object' && typeof exports == 'object') {
+ module.exports = factory;
+ } else if (typeof define == 'function' && define['amd']) {
+ define(factory);
+ } else {
+ global.NW || (global.NW = { });
+ global.NW.Dom = factory(global, Export);
+ }
+
+})(this, function Factory(global, Export) {
+
+ var version = 'nwsapi-2.2.2',
+
+ doc = global.document,
+ root = doc.documentElement,
+ slice = Array.prototype.slice,
+
+ WSP = '[\\x20\\t\\r\\n\\f]',
+
+ CFG = {
+ // extensions
+ operators: '[~*^$|]=|=',
+ combinators: '[\\x20\\t>+~](?=[^>+~])'
+ },
+
+ NOT = {
+ // not enclosed in double/single/parens/square
+ double_enc: '(?=(?:[^"]*["][^"]*["])*[^"]*$)',
+ single_enc: "(?=(?:[^']*['][^']*['])*[^']*$)",
+ parens_enc: '(?![^\\x28]*\\x29)',
+ square_enc: '(?![^\\x5b]*\\x5d)'
+ },
+
+ REX = {
+ // regular expressions
+ HasEscapes: RegExp('\\\\'),
+ HexNumbers: RegExp('^[0-9a-fA-F]'),
+ EscOrQuote: RegExp('^\\\\|[\\x22\\x27]'),
+ RegExpChar: RegExp('(?:(?!\\\\)[\\\\^$.*+?()[\\]{}|\\/])', 'g'),
+ TrimSpaces: RegExp('[\\r\\n\\f]|^' + WSP + '+|' + WSP + '+$', 'g'),
+ CommaGroup: RegExp('(\\s*,\\s*)' + NOT.square_enc + NOT.parens_enc, 'g'),
+ SplitGroup: RegExp('((?:\\x28[^\\x29]*\\x29|\\[[^\\]]*\\]|\\\\.|[^,])+)', 'g'),
+ FixEscapes: RegExp('\\\\([0-9a-fA-F]{1,6}' + WSP + '?|.)|([\\x22\\x27])', 'g'),
+ CombineWSP: RegExp('[\\n\\r\\f\\x20]+' + NOT.single_enc + NOT.double_enc, 'g'),
+ TabCharWSP: RegExp('(\\x20?\\t+\\x20?)' + NOT.single_enc + NOT.double_enc, 'g'),
+ PseudosWSP: RegExp('\\s+([-+])\\s+' + NOT.square_enc, 'g')
+ },
+
+ STD = {
+ combinator: RegExp('\\s?([>+~])\\s?', 'g'),
+ apimethods: RegExp('^(?:[a-z]+|\\*)\\|', 'i'),
+ namespaces: RegExp('(\\*|[a-z]+)\\|[-a-z]+', 'i')
+ },
+
+ GROUPS = {
+ // pseudo-classes requiring parameters
+ linguistic: '(dir|lang)\\x28\\s?([-\\w]{2,})\\s?(?:\\x29|$)',
+ logicalsel: '(is|where|matches|not)\\x28\\s?([^()]*|[^\\x28]*\\x28[^\\x29]*\\x29)\\s?(?:\\x29|$)',
+ treestruct: '(nth(?:-last)?(?:-child|-of-type))(?:\\x28\\s?(even|odd|(?:[-+]?\\d*)(?:n\\s?[-+]?\\s?\\d*)?)\\s?(?:\\x29|$))',
+ // pseudo-classes not requiring parameters
+ locationpc: '(any-link|link|visited|target)\\b',
+ useraction: '(hover|active|focus|focus-within)\\b',
+ structural: '(root|empty|(?:(?:first|last|only)(?:-child|-of-type)))\\b',
+ inputstate: '(enabled|disabled|read-only|read-write|placeholder-shown|default)\\b',
+ inputvalue: '(checked|indeterminate|required|optional|valid|invalid|in-range|out-of-range)\\b',
+ // pseudo-classes for parsing only selectors
+ pseudo_nop: '(autofill|-webkit-autofill)\\b',
+ // pseudo-elements starting with single colon (:)
+ pseudo_sng: '(after|before|first-letter|first-line)\\b',
+ // pseudo-elements starting with double colon (::)
+ pseudo_dbl: ':(after|before|first-letter|first-line|selection|placeholder|-webkit-[-a-zA-Z0-9]{2,})\\b'
+ },
+
+ Patterns = {
+ // pseudo-classes
+ treestruct: RegExp('^:(?:' + GROUPS.treestruct + ')(.*)', 'i'),
+ structural: RegExp('^:(?:' + GROUPS.structural + ')(.*)', 'i'),
+ linguistic: RegExp('^:(?:' + GROUPS.linguistic + ')(.*)', 'i'),
+ useraction: RegExp('^:(?:' + GROUPS.useraction + ')(.*)', 'i'),
+ inputstate: RegExp('^:(?:' + GROUPS.inputstate + ')(.*)', 'i'),
+ inputvalue: RegExp('^:(?:' + GROUPS.inputvalue + ')(.*)', 'i'),
+ locationpc: RegExp('^:(?:' + GROUPS.locationpc + ')(.*)', 'i'),
+ logicalsel: RegExp('^:(?:' + GROUPS.logicalsel + ')(.*)', 'i'),
+ pseudo_nop: RegExp('^:(?:' + GROUPS.pseudo_nop + ')(.*)', 'i'),
+ pseudo_sng: RegExp('^:(?:' + GROUPS.pseudo_sng + ')(.*)', 'i'),
+ pseudo_dbl: RegExp('^:(?:' + GROUPS.pseudo_dbl + ')(.*)', 'i'),
+ // combinator symbols
+ children: RegExp('^' + WSP + '?\\>' + WSP + '?(.*)'),
+ adjacent: RegExp('^' + WSP + '?\\+' + WSP + '?(.*)'),
+ relative: RegExp('^' + WSP + '?\\~' + WSP + '?(.*)'),
+ ancestor: RegExp('^' + WSP + '+(.*)'),
+ // universal & namespace
+ universal: RegExp('^\\*(.*)'),
+ namespace: RegExp('^(\\w+|\\*)?\\|(.*)')
+ },
+
+ // regexp to aproximate detection of RTL languages (Arabic)
+ RTL = RegExp('^[\\u0591-\\u08ff\\ufb1d-\\ufdfd\\ufe70-\\ufefc ]+$'),
+
+ // emulate firefox error strings
+ qsNotArgs = 'Not enough arguments',
+ qsInvalid = ' is not a valid selector',
+
+ // detect structural pseudo-classes in selectors
+ reNthElem = RegExp('(:nth(?:-last)?-child)', 'i'),
+ reNthType = RegExp('(:nth(?:-last)?-of-type)', 'i'),
+
+ // placeholder for global regexp
+ reOptimizer,
+ reValidator,
+
+ // special handling configuration flags
+ Config = {
+ IDS_DUPES: true,
+ MIXEDCASE: true,
+ LOGERRORS: true,
+ VERBOSITY: true
+ },
+
+ NAMESPACE,
+ QUIRKS_MODE,
+ HTML_DOCUMENT,
+
+ ATTR_STD_OPS = {
+ '=': 1, '^=': 1, '$=': 1, '|=': 1, '*=': 1, '~=': 1
+ },
+
+ HTML_TABLE = {
+ 'accept': 1, 'accept-charset': 1, 'align': 1, 'alink': 1, 'axis': 1,
+ 'bgcolor': 1, 'charset': 1, 'checked': 1, 'clear': 1, 'codetype': 1, 'color': 1,
+ 'compact': 1, 'declare': 1, 'defer': 1, 'dir': 1, 'direction': 1, 'disabled': 1,
+ 'enctype': 1, 'face': 1, 'frame': 1, 'hreflang': 1, 'http-equiv': 1, 'lang': 1,
+ 'language': 1, 'link': 1, 'media': 1, 'method': 1, 'multiple': 1, 'nohref': 1,
+ 'noresize': 1, 'noshade': 1, 'nowrap': 1, 'readonly': 1, 'rel': 1, 'rev': 1,
+ 'rules': 1, 'scope': 1, 'scrolling': 1, 'selected': 1, 'shape': 1, 'target': 1,
+ 'text': 1, 'type': 1, 'valign': 1, 'valuetype': 1, 'vlink': 1
+ },
+
+ Combinators = { },
+
+ Selectors = { },
+
+ Operators = {
+ '=': { p1: '^',
+ p2: '$',
+ p3: 'true' },
+ '^=': { p1: '^',
+ p2: '',
+ p3: 'true' },
+ '$=': { p1: '',
+ p2: '$',
+ p3: 'true' },
+ '*=': { p1: '',
+ p2: '',
+ p3: 'true' },
+ '|=': { p1: '^',
+ p2: '(-|$)',
+ p3: 'true' },
+ '~=': { p1: '(^|\\s)',
+ p2: '(\\s|$)',
+ p3: 'true' }
+ },
+
+ concatCall =
+ function(nodes, callback) {
+ var i = 0, l = nodes.length, list = Array(l);
+ while (l > i) {
+ if (false === callback(list[i] = nodes[i])) break;
+ ++i;
+ }
+ return list;
+ },
+
+ concatList =
+ function(list, nodes) {
+ var i = -1, l = nodes.length;
+ while (l--) { list[list.length] = nodes[++i]; }
+ return list;
+ },
+
+ documentOrder =
+ function(a, b) {
+ if (!hasDupes && a === b) {
+ hasDupes = true;
+ return 0;
+ }
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ },
+
+ hasDupes = false,
+
+ unique =
+ function(nodes) {
+ var i = 0, j = -1, l = nodes.length + 1, list = [ ];
+ while (--l) {
+ if (nodes[i++] === nodes[i]) continue;
+ list[++j] = nodes[i - 1];
+ }
+ hasDupes = false;
+ return list;
+ },
+
+ // check context for mixed content
+ hasMixedCaseTagNames =
+ function(context) {
+ var ns, api = 'getElementsByTagNameNS';
+
+ // current host context (ownerDocument)
+ context = context.ownerDocument || context;
+
+ // documentElement (root) element namespace or default html/xhtml namespace
+ ns = context.documentElement.namespaceURI || 'http://www.w3.org/1999/xhtml';
+
+ // checking the number of non HTML nodes in the document
+ return (context[api]('*', '*').length - context[api](ns, '*').length) > 0;
+ },
+
+ switchContext =
+ function(context, force) {
+ var oldDoc = doc;
+ doc = context.ownerDocument || context;
+ if (force || oldDoc !== doc) {
+ // force a new check for each document change
+ // performed before the next select operation
+ root = doc.documentElement;
+ HTML_DOCUMENT = isHTML(doc);
+ QUIRKS_MODE = HTML_DOCUMENT &&
+ doc.compatMode.indexOf('CSS') < 0;
+ NAMESPACE = root && root.namespaceURI;
+ Snapshot.doc = doc;
+ Snapshot.root = root;
+ }
+ return (Snapshot.from = context);
+ },
+
+ // convert single codepoint to UTF-16 encoding
+ codePointToUTF16 =
+ function(codePoint) {
+ // out of range, use replacement character
+ if (codePoint < 1 || codePoint > 0x10ffff ||
+ (codePoint > 0xd7ff && codePoint < 0xe000)) {
+ return '\\ufffd';
+ }
+ // javascript strings are UTF-16 encoded
+ if (codePoint < 0x10000) {
+ var lowHex = '000' + codePoint.toString(16);
+ return '\\u' + lowHex.substr(lowHex.length - 4);
+ }
+ // supplementary high + low surrogates
+ return '\\u' + (((codePoint - 0x10000) >> 0x0a) + 0xd800).toString(16) +
+ '\\u' + (((codePoint - 0x10000) % 0x400) + 0xdc00).toString(16);
+ },
+
+ // convert single codepoint to string
+ stringFromCodePoint =
+ function(codePoint) {
+ // out of range, use replacement character
+ if (codePoint < 1 || codePoint > 0x10ffff ||
+ (codePoint > 0xd7ff && codePoint < 0xe000)) {
+ return '\ufffd';
+ }
+ if (codePoint < 0x10000) {
+ return String.fromCharCode(codePoint);
+ }
+ return String.fromCodePoint ?
+ String.fromCodePoint(codePoint) :
+ String.fromCharCode(
+ ((codePoint - 0x10000) >> 0x0a) + 0xd800,
+ ((codePoint - 0x10000) % 0x400) + 0xdc00);
+ },
+
+ // convert escape sequence in a CSS string or identifier
+ // to javascript string with javascript escape sequences
+ convertEscapes =
+ function(str) {
+ return REX.HasEscapes.test(str) ?
+ str.replace(REX.FixEscapes,
+ function(substring, p1, p2) {
+ // unescaped " or '
+ return p2 ? '\\' + p2 :
+ // javascript strings are UTF-16 encoded
+ REX.HexNumbers.test(p1) ? codePointToUTF16(parseInt(p1, 16)) :
+ // \' \"
+ REX.EscOrQuote.test(p1) ? substring :
+ // \g \h \. \# etc
+ p1;
+ }
+ ) : str;
+ },
+
+ // convert escape sequence in a CSS string or identifier
+ // to javascript string with characters representations
+ unescapeIdentifier =
+ function(str) {
+ return REX.HasEscapes.test(str) ?
+ str.replace(REX.FixEscapes,
+ function(substring, p1, p2) {
+ // unescaped " or '
+ return p2 ? p2 :
+ // javascript strings are UTF-16 encoded
+ REX.HexNumbers.test(p1) ? stringFromCodePoint(parseInt(p1, 16)) :
+ // \' \"
+ REX.EscOrQuote.test(p1) ? substring :
+ // \g \h \. \# etc
+ p1;
+ }
+ ) : str;
+ },
+
+ method = {
+ '#': 'getElementById',
+ '*': 'getElementsByTagName',
+ '|': 'getElementsByTagNameNS',
+ '.': 'getElementsByClassName'
+ },
+
+ compat = {
+ '#': function(c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function(e, f) { return byId(n, c); }; },
+ '*': function(c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function(e, f) { return byTag(n, c); }; },
+ '|': function(c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function(e, f) { return byTag(n, c); }; },
+ '.': function(c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function(e, f) { return byClass(n, c); }; }
+ },
+
+ // find duplicate ids using iterative walk
+ byIdRaw =
+ function(id, context) {
+ var node = context, nodes = [ ], next = node.firstElementChild;
+ while ((node = next)) {
+ node.id == id && (nodes[nodes.length] = node);
+ if ((next = node.firstElementChild || node.nextElementSibling)) continue;
+ while (!next && (node = node.parentElement) && node !== context) {
+ next = node.nextElementSibling;
+ }
+ }
+ return nodes;
+ },
+
+ // context agnostic getElementById
+ byId =
+ function(id, context) {
+ var e, nodes, api = method['#'];
+
+ // duplicates id allowed
+ if (Config.IDS_DUPES === false) {
+ if (api in context) {
+ return (e = context[api](id)) ? [ e ] : none;
+ }
+ } else {
+ if ('all' in context) {
+ if ((e = context.all[id])) {
+ if (e.nodeType == 1) return e.getAttribute('id') != id ? [ ] : [ e ];
+ else if (id == 'length') return (e = context[api](id)) ? [ e ] : none;
+ for (i = 0, l = e.length, nodes = [ ]; l > i; ++i) {
+ if (e[i].id == id) nodes[nodes.length] = e[i];
+ }
+ return nodes && nodes.length ? nodes : [ nodes ];
+ } else return none;
+ }
+ }
+
+ return byIdRaw(id, context);
+ },
+
+ // context agnostic getElementsByTagName
+ byTag =
+ function(tag, context) {
+ var e, nodes, api = method['*'];
+ // DOCUMENT_NODE (9) & ELEMENT_NODE (1)
+ if (api in context) {
+ return slice.call(context[api](tag));
+ } else {
+ tag = tag.toLowerCase();
+ // DOCUMENT_FRAGMENT_NODE (11)
+ if ((e = context.firstElementChild)) {
+ if (!(e.nextElementSibling || tag == '*' || e.localName == tag)) {
+ return slice.call(e[api](tag));
+ } else {
+ nodes = [ ];
+ do {
+ if (tag == '*' || e.localName == tag) nodes[nodes.length] = e;
+ concatList(nodes, e[api](tag));
+ } while ((e = e.nextElementSibling));
+ }
+ } else nodes = none;
+ }
+ return nodes;
+ },
+
+ // context agnostic getElementsByClassName
+ byClass =
+ function(cls, context) {
+ var e, nodes, api = method['.'], reCls;
+ // DOCUMENT_NODE (9) & ELEMENT_NODE (1)
+ if (api in context) {
+ return slice.call(context[api](cls));
+ } else {
+ // DOCUMENT_FRAGMENT_NODE (11)
+ if ((e = context.firstElementChild)) {
+ reCls = RegExp('(^|\\s)' + cls + '(\\s|$)', QUIRKS_MODE ? 'i' : '');
+ if (!(e.nextElementSibling || reCls.test(e.className))) {
+ return slice.call(e[api](cls));
+ } else {
+ nodes = [ ];
+ do {
+ if (reCls.test(e.className)) nodes[nodes.length] = e;
+ concatList(nodes, e[api](cls));
+ } while ((e = e.nextElementSibling));
+ }
+ } else nodes = none;
+ }
+ return nodes;
+ },
+
+ // namespace aware hasAttribute
+ // helper for XML/XHTML documents
+ hasAttributeNS =
+ function(e, name) {
+ var i, l, attr = e.getAttributeNames();
+ name = RegExp(':?' + name + '$', HTML_DOCUMENT ? 'i' : '');
+ for (i = 0, l = attr.length; l > i; ++i) {
+ if (name.test(attr[i])) return true;
+ }
+ return false;
+ },
+
+ // fast resolver for the :nth-child() and :nth-last-child() pseudo-classes
+ nthElement = (function() {
+ var idx = 0, len = 0, set = 0, parent = undefined, parents = Array(), nodes = Array();
+ return function(element, dir) {
+ // ensure caches are emptied after each run, invoking with dir = 2
+ if (dir == 2) {
+ idx = 0; len = 0; set = 0; nodes.length = 0;
+ parents.length = 0; parent = undefined;
+ return -1;
+ }
+ var e, i, j, k, l;
+ if (parent === element.parentElement) {
+ i = set; j = idx; l = len;
+ } else {
+ l = parents.length;
+ parent = element.parentElement;
+ for (i = -1, j = 0, k = l - 1; l > j; ++j, --k) {
+ if (parents[j] === parent) { i = j; break; }
+ if (parents[k] === parent) { i = k; break; }
+ }
+ if (i < 0) {
+ parents[i = l] = parent;
+ l = 0; nodes[i] = Array();
+ e = parent && parent.firstElementChild || element;
+ while (e) { nodes[i][l] = e; if (e === element) j = l; e = e.nextElementSibling; ++l; }
+ set = i; idx = 0; len = l;
+ if (l < 2) return l;
+ } else {
+ l = nodes[i].length;
+ set = i;
+ }
+ }
+ if (element !== nodes[i][j] && element !== nodes[i][j = 0]) {
+ for (j = 0, e = nodes[i], k = l - 1; l > j; ++j, --k) {
+ if (e[j] === element) { break; }
+ if (e[k] === element) { j = k; break; }
+ }
+ }
+ idx = j + 1; len = l;
+ return dir ? l - j : idx;
+ };
+ })(),
+
+ // fast resolver for the :nth-of-type() and :nth-last-of-type() pseudo-classes
+ nthOfType = (function() {
+ var idx = 0, len = 0, set = 0, parent = undefined, parents = Array(), nodes = Array();
+ return function(element, dir) {
+ // ensure caches are emptied after each run, invoking with dir = 2
+ if (dir == 2) {
+ idx = 0; len = 0; set = 0; nodes.length = 0;
+ parents.length = 0; parent = undefined;
+ return -1;
+ }
+ var e, i, j, k, l, name = element.localName;
+ if (nodes[set] && nodes[set][name] && parent === element.parentElement) {
+ i = set; j = idx; l = len;
+ } else {
+ l = parents.length;
+ parent = element.parentElement;
+ for (i = -1, j = 0, k = l - 1; l > j; ++j, --k) {
+ if (parents[j] === parent) { i = j; break; }
+ if (parents[k] === parent) { i = k; break; }
+ }
+ if (i < 0 || !nodes[i][name]) {
+ parents[i = l] = parent;
+ nodes[i] || (nodes[i] = Object());
+ l = 0; nodes[i][name] = Array();
+ e = parent && parent.firstElementChild || element;
+ while (e) { if (e === element) j = l; if (e.localName == name) { nodes[i][name][l] = e; ++l; } e = e.nextElementSibling; }
+ set = i; idx = j; len = l;
+ if (l < 2) return l;
+ } else {
+ l = nodes[i][name].length;
+ set = i;
+ }
+ }
+ if (element !== nodes[i][name][j] && element !== nodes[i][name][j = 0]) {
+ for (j = 0, e = nodes[i][name], k = l - 1; l > j; ++j, --k) {
+ if (e[j] === element) { break; }
+ if (e[k] === element) { j = k; break; }
+ }
+ }
+ idx = j + 1; len = l;
+ return dir ? l - j : idx;
+ };
+ })(),
+
+ // check if the document type is HTML
+ isHTML =
+ function(node) {
+ var doc = node.ownerDocument || node;
+ return doc.nodeType == 9 &&
+ // contentType not in IE <= 11
+ 'contentType' in doc ?
+ doc.contentType.indexOf('/html') > 0 :
+ doc.createElement('DiV').localName == 'div';
+ },
+
+ // configure the engine to use special handling
+ configure =
+ function(option, clear) {
+ if (typeof option == 'string') { return !!Config[option]; }
+ if (typeof option != 'object') { return Config; }
+ for (var i in option) {
+ Config[i] = !!option[i];
+ }
+ // clear lambda cache
+ if (clear) {
+ matchResolvers = { };
+ selectResolvers = { };
+ }
+ setIdentifierSyntax();
+ return true;
+ },
+
+ // centralized error and exceptions handling
+ emit =
+ function(message, proto) {
+ var err;
+ if (Config.VERBOSITY) {
+ if (proto) {
+ err = new proto(message);
+ } else {
+ err = new global.DOMException(message, 'SyntaxError');
+ }
+ throw err;
+ }
+ if (Config.LOGERRORS && console && console.log) {
+ console.log(message);
+ }
+ },
+
+ // execute the engine initialization code
+ initialize =
+ function(doc) {
+ setIdentifierSyntax();
+ lastContext = switchContext(doc, true);
+ },
+
+ // build validation regexps used by the engine
+ setIdentifierSyntax =
+ function() {
+
+ //
+ // NOTE: SPECIAL CASES IN CSS SYNTAX PARSING RULES
+ //
+ // The <EOF-token> https://drafts.csswg.org/css-syntax/#typedef-eof-token
+ // allow mangled|unclosed selector syntax at the end of selectors strings
+ //
+ // Literal equivalent hex representations of the characters: " ' ` ] )
+ //
+ // \\x22 = " - double quotes \\x5b = [ - open square bracket
+ // \\x27 = ' - single quote \\x5d = ] - closed square bracket
+ // \\x60 = ` - back tick \\x28 = ( - open round parens
+ // \\x5c = \ - back slash \\x29 = ) - closed round parens
+ //
+ // using hex format prevents false matches of opened/closed instances
+ // pairs, coloring breakage and other editors highlightning problems.
+ //
+
+ var identifier =
+ // doesn't start with a digit
+ '(?=[^0-9])' +
+ // can start with double dash
+ '(?:-{2}' +
+ // may include ascii chars
+ '|[a-zA-Z0-9-_]' +
+ // non-ascii chars
+ '|[^\\x00-\\x9f]' +
+ // escaped chars
+ '|\\\\[^\\r\\n\\f0-9a-fA-F]' +
+ // unicode chars
+ '|\\\\[0-9a-fA-F]{1,6}(?:\\r\\n|\\s)?' +
+ // any escaped chars
+ '|\\\\.' +
+ ')+',
+
+ pseudonames = '[-\\w]+',
+ pseudoparms = '(?:[-+]?\\d*)(?:n\\s?[-+]?\\s?\\d*)',
+ doublequote = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*(?:"|$)',
+ singlequote = "'[^'\\\\]*(?:\\\\.[^'\\\\]*)*(?:'|$)",
+
+ attrparser = identifier + '|' + doublequote + '|' + singlequote,
+
+ attrvalues = '([\\x22\\x27]?)((?!\\3)*|(?:\\\\?.)*?)(?:\\3|$)',
+
+ attributes =
+ '\\[' +
+ // attribute presence
+ '(?:\\*\\|)?' +
+ WSP + '?' +
+ '(' + identifier + '(?::' + identifier + ')?)' +
+ WSP + '?' +
+ '(?:' +
+ '(' + CFG.operators + ')' + WSP + '?' +
+ '(?:' + attrparser + ')' +
+ ')?' +
+ // attribute case sensitivity
+ '(?:' + WSP + '?\\b(i))?' + WSP + '?' +
+ '(?:\\]|$)',
+
+ attrmatcher = attributes.replace(attrparser, attrvalues),
+
+ pseudoclass =
+ '(?:\\x28' + WSP + '*' +
+ '(?:' + pseudoparms + '?)?|' +
+ // universal * &
+ // namespace *|*
+ '(?:\\*|\\|)|' +
+ '(?:' +
+ '(?::' + pseudonames +
+ '(?:\\x28' + pseudoparms + '?(?:\\x29|$))?|' +
+ ')|' +
+ '(?:[.#]?' + identifier + ')|' +
+ '(?:' + attributes + ')' +
+ ')+|' +
+ '(?:' + WSP + '?,' + WSP + '?)|' +
+ '(?:' + WSP + '?)|' +
+ '(?:\\x29|$))*',
+
+ standardValidator =
+ '(?=' + WSP + '?[^>+~(){}<>])' +
+ '(?:' +
+ // universal * &
+ // namespace *|*
+ '(?:\\*|\\|)|' +
+ '(?:[.#]?' + identifier + ')+|' +
+ '(?:' + attributes + ')+|' +
+ '(?:::?' + pseudonames + pseudoclass + ')|' +
+ '(?:' + WSP + '?' + CFG.combinators + WSP + '?)|' +
+ '(?:' + WSP + '?,' + WSP + '?)|' +
+ '(?:' + WSP + '?)' +
+ ')+';
+
+ // the following global RE is used to return the
+ // deepest localName in selector strings and then
+ // use it to retrieve all possible matching nodes
+ // that will be filtered by compiled resolvers
+ reOptimizer = RegExp(
+ '(?:([.:#*]?)' +
+ '(' + identifier + ')' +
+ '(?:' +
+ ':[-\\w]+|' +
+ '\\[[^\\]]+(?:\\]|$)|' +
+ '\\x28[^\\x29]+(?:\\x29|$)' +
+ ')*)$');
+
+ // global
+ reValidator = RegExp(standardValidator, 'g');
+
+ Patterns.id = RegExp('^#(' + identifier + ')(.*)');
+ Patterns.tagName = RegExp('^(' + identifier + ')(.*)');
+ Patterns.className = RegExp('^\\.(' + identifier + ')(.*)');
+ Patterns.attribute = RegExp('^(?:' + attrmatcher + ')(.*)');
+ },
+
+ F_INIT = '"use strict";return function Resolver(c,f,x,r)',
+
+ S_HEAD = 'var e,n,o,j=r.length-1,k=-1',
+ M_HEAD = 'var e,n,o',
+
+ S_LOOP = 'main:while((e=c[++k]))',
+ N_LOOP = 'main:while((e=c.item(++k)))',
+ M_LOOP = 'e=c;',
+
+ S_BODY = 'r[++j]=c[k];',
+ N_BODY = 'r[++j]=c.item(k);',
+ M_BODY = '',
+
+ S_TAIL = 'continue main;',
+ M_TAIL = 'r=true;',
+
+ S_TEST = 'if(f(c[k])){break main;}',
+ N_TEST = 'if(f(c.item(k))){break main;}',
+ M_TEST = 'f(c);',
+
+ S_VARS = [ ],
+ M_VARS = [ ],
+
+ // compile groups or single selector strings into
+ // executable functions for matching or selecting
+ compile =
+ function(selector, mode, callback) {
+ var factory, token, head = '', loop = '', macro = '', source = '', vars = '';
+
+ // 'mode' can be boolean or null
+ // true = select / false = match
+ // null to use collection.item()
+ switch (mode) {
+ case true:
+ if (selectLambdas[selector]) { return selectLambdas[selector]; }
+ macro = S_BODY + (callback ? S_TEST : '') + S_TAIL;
+ head = S_HEAD;
+ loop = S_LOOP;
+ break;
+ case false:
+ if (matchLambdas[selector]) { return matchLambdas[selector]; }
+ macro = M_BODY + (callback ? M_TEST : '') + M_TAIL;
+ head = M_HEAD;
+ loop = M_LOOP;
+ break;
+ case null:
+ if (selectLambdas[selector]) { return selectLambdas[selector]; }
+ macro = N_BODY + (callback ? N_TEST : '') + S_TAIL;
+ head = S_HEAD;
+ loop = N_LOOP;
+ break;
+ default:
+ break;
+ }
+
+ source = compileSelector(selector, macro, mode, callback);
+
+ loop += mode || mode === null ? '{' + source + '}' : source;
+
+ if (mode || mode === null && selector.includes(':nth')) {
+ loop += reNthElem.test(selector) ? 's.nthElement(null, 2);' : '';
+ loop += reNthType.test(selector) ? 's.nthOfType(null, 2);' : '';
+ }
+
+ if (S_VARS[0] || M_VARS[0]) {
+ vars = ',' + (S_VARS.join(',') || M_VARS.join(','));
+ S_VARS.length = 0;
+ M_VARS.length = 0;
+ }
+
+ factory = Function('s', F_INIT + '{' + head + vars + ';' + loop + 'return r;}')(Snapshot);
+
+ return mode || mode === null ? (selectLambdas[selector] = factory) : (matchLambdas[selector] = factory);
+ },
+
+ // build conditional code to check components of selector strings
+ compileSelector =
+ function(expression, source, mode, callback) {
+
+ // N is the negation pseudo-class flag
+ // D is the default inverted negation flag
+ var a, b, n, f, i, l, name, NS, N = '', D = '!',
+ compat, expr, match, result, status, symbol, test,
+ type, selector = expression, selector_string, vars;
+
+ // original 'select' or 'match' selector string before normalization
+ selector_string = mode ? lastSelected : lastMatched;
+
+ // isolate selector combinators/components and normalize whitespace
+ selector = selector.replace(STD.combinator, '$1');//.replace(STD.whitespace, ' ');
+
+ // javascript needs a label to break
+ // out of the while loops processing
+ selector_recursion_label:
+
+ while (selector) {
+
+ // get namespace prefix if present or get first char of selector
+ symbol = STD.apimethods.test(selector) ? '|' : selector[0];
+
+ switch (symbol) {
+
+ // universal resolver
+ case '*':
+ match = selector.match(Patterns.universal);
+ if (N == '!') {
+ source = 'if(' + N + 'true' +
+ '){' + source + '}';
+ }
+ break;
+
+ // id resolver
+ case '#':
+ match = selector.match(Patterns.id);
+ source = 'if(' + N + '(/^' + match[1] + '$/.test(e.getAttribute("id"))' +
+ ')){' + source + '}';
+ break;
+
+ // class name resolver
+ case '.':
+ match = selector.match(Patterns.className);
+ compat = (QUIRKS_MODE ? 'i' : '') + '.test(e.getAttribute("class"))';
+ source = 'if(' + N + '(/(^|\\s)' + match[1] + '(\\s|$)/' + compat +
+ ')){' + source + '}';
+ break;
+
+ // tag name resolver
+ case (/[_a-z]/i.test(symbol) ? symbol : undefined):
+ match = selector.match(Patterns.tagName);
+ source = 'if(' + N + '(e.localName' +
+ (Config.MIXEDCASE || hasMixedCaseTagNames(doc) ?
+ '=="' + match[1].toLowerCase() + '"' :
+ '=="' + match[1].toUpperCase() + '"') +
+ ')){' + source + '}';
+ break;
+
+ // namespace resolver
+ case '|':
+ match = selector.match(Patterns.namespace);
+ if (match[1] == '*') {
+ source = 'if(' + N + 'true){' + source + '}';
+ } else if (!match[1]) {
+ source = 'if(' + N + '(!e.namespaceURI)){' + source + '}';
+ } else if (typeof match[1] == 'string' && root.prefix == match[1]) {
+ source = 'if(' + N + '(e.namespaceURI=="' + NAMESPACE + '")){' + source + '}';
+ } else {
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ }
+ break;
+
+ // attributes resolver
+ case '[':
+ match = selector.match(Patterns.attribute);
+ NS = match[0].match(STD.namespaces);
+ name = match[1];
+ expr = name.split(':');
+ expr = expr.length == 2 ? expr[1] : expr[0];
+ if (match[2] && !(test = Operators[match[2]])) {
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ return '';
+ }
+ if (match[4] === '') {
+ test = match[2] == '~=' ?
+ { p1: '^\\s', p2: '+$', p3: 'true' } :
+ match[2] in ATTR_STD_OPS && match[2] != '~=' ?
+ { p1: '^', p2: '$', p3: 'true' } : test;
+ } else if (match[2] == '~=' && match[4].includes(' ')) {
+ // whitespace separated list but value contains space
+ source = 'if(' + N + 'false){' + source + '}';
+ break;
+ } else if (match[4]) {
+ match[4] = convertEscapes(match[4]).replace(REX.RegExpChar, '\\$&');
+ }
+ type = match[5] == 'i' || (HTML_DOCUMENT && HTML_TABLE[expr.toLowerCase()]) ? 'i' : '';
+ source = 'if(' + N + '(' +
+ (!match[2] ? (NS ? 's.hasAttributeNS(e,"' + name + '")' : 'e.hasAttribute&&e.hasAttribute("' + name + '")') :
+ !match[4] && ATTR_STD_OPS[match[2]] && match[2] != '~=' ? 'e.getAttribute&&e.getAttribute("' + name + '")==""' :
+ '(/' + test.p1 + match[4] + test.p2 + '/' + type + ').test(e.getAttribute&&e.getAttribute("' + name + '"))==' + test.p3) +
+ ')){' + source + '}';
+ break;
+
+ // *** General sibling combinator
+ // E ~ F (F relative sibling of E)
+ case '~':
+ match = selector.match(Patterns.relative);
+ source = 'n=e;while((e=e.previousElementSibling)){' + source + '}e=n;';
+ break;
+ // *** Adjacent sibling combinator
+ // E + F (F adiacent sibling of E)
+ case '+':
+ match = selector.match(Patterns.adjacent);
+ source = 'n=e;if((e=e.previousElementSibling)){' + source + '}e=n;';
+ break;
+ // *** Descendant combinator
+ // E F (E ancestor of F)
+ case '\x09':
+ case '\x20':
+ match = selector.match(Patterns.ancestor);
+ source = 'n=e;while((e=e.parentElement)){' + source + '}e=n;';
+ break;
+ // *** Child combinator
+ // E > F (F children of E)
+ case '>':
+ match = selector.match(Patterns.children);
+ source = 'n=e;if((e=e.parentElement)){' + source + '}e=n;';
+ break;
+
+ // *** user supplied combinators extensions
+ case (symbol in Combinators ? symbol : undefined):
+ // for other registered combinators extensions
+ match[match.length - 1] = '*';
+ source = Combinators[symbol](match) + source;
+ break;
+
+ // *** tree-structural pseudo-classes
+ // :root, :empty, :first-child, :last-child, :only-child, :first-of-type, :last-of-type, :only-of-type
+ case ':':
+ if ((match = selector.match(Patterns.structural))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'root':
+ // there can only be one :root element, so exit the loop once found
+ source = 'if(' + N + '(e===s.root)){' + source + (mode ? 'break main;' : '') + '}';
+ break;
+ case 'empty':
+ // matches elements that don't contain elements or text nodes
+ source = 'n=e.firstChild;while(n&&!(/1|3/).test(n.nodeType)){n=n.nextSibling}if(' + D + 'n){' + source + '}';
+ break;
+
+ // *** child-indexed pseudo-classes
+ // :first-child, :last-child, :only-child
+ case 'only-child':
+ source = 'if(' + N + '(!e.nextElementSibling&&!e.previousElementSibling)){' + source + '}';
+ break;
+ case 'last-child':
+ source = 'if(' + N + '(!e.nextElementSibling)){' + source + '}';
+ break;
+ case 'first-child':
+ source = 'if(' + N + '(!e.previousElementSibling)){' + source + '}';
+ break;
+
+ // *** typed child-indexed pseudo-classes
+ // :only-of-type, :last-of-type, :first-of-type
+ case 'only-of-type':
+ source = 'o=e.localName;' +
+ 'n=e;while((n=n.nextElementSibling)&&n.localName!=o);if(!n){' +
+ 'n=e;while((n=n.previousElementSibling)&&n.localName!=o);}if(' + D + 'n){' + source + '}';
+ break;
+ case 'last-of-type':
+ source = 'n=e;o=e.localName;while((n=n.nextElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}';
+ break;
+ case 'first-of-type':
+ source = 'n=e;o=e.localName;while((n=n.previousElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}';
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** child-indexed & typed child-indexed pseudo-classes
+ // :nth-child, :nth-of-type, :nth-last-child, :nth-last-of-type
+ else if ((match = selector.match(Patterns.treestruct))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'nth-child':
+ case 'nth-of-type':
+ case 'nth-last-child':
+ case 'nth-last-of-type':
+ expr = /-of-type/i.test(match[1]);
+ if (match[1] && match[2]) {
+ type = /last/i.test(match[1]);
+ if (match[2] == 'n') {
+ source = 'if(' + N + 'true){' + source + '}';
+ break;
+ } else if (match[2] == '1') {
+ test = type ? 'next' : 'previous';
+ source = expr ? 'n=e;o=e.localName;' +
+ 'while((n=n.' + test + 'ElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}' :
+ 'if(' + N + '!e.' + test + 'ElementSibling){' + source + '}';
+ break;
+ } else if (match[2] == 'even' || match[2] == '2n0' || match[2] == '2n+0' || match[2] == '2n') {
+ test = 'n%2==0';
+ } else if (match[2] == 'odd' || match[2] == '2n1' || match[2] == '2n+1') {
+ test = 'n%2==1';
+ } else {
+ f = /n/i.test(match[2]);
+ n = match[2].split('n');
+ a = parseInt(n[0], 10) || 0;
+ b = parseInt(n[1], 10) || 0;
+ if (n[0] == '-') { a = -1; }
+ if (n[0] == '+') { a = +1; }
+ test = (b ? '(n' + (b > 0 ? '-' : '+') + Math.abs(b) + ')' : 'n') + '%' + a + '==0' ;
+ test =
+ a >= +1 ? (f ? 'n>' + (b - 1) + (Math.abs(a) != 1 ? '&&' + test : '') : 'n==' + a) :
+ a <= -1 ? (f ? 'n<' + (b + 1) + (Math.abs(a) != 1 ? '&&' + test : '') : 'n==' + a) :
+ a === 0 ? (n[0] ? 'n==' + b : 'n>' + (b - 1)) : 'false';
+ }
+ expr = expr ? 'OfType' : 'Element';
+ type = type ? 'true' : 'false';
+ source = 'n=s.nth' + expr + '(e,' + type + ');if(' + N + '(' + test + ')){' + source + '}';
+ } else {
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ }
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** logical combination pseudo-classes
+ // :is( s1, [ s2, ... ]), :not( s1, [ s2, ... ])
+ else if ((match = selector.match(Patterns.logicalsel))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'is':
+ case 'where':
+ case 'matches':
+ expr = match[2].replace(REX.CommaGroup, ',').replace(REX.TrimSpaces, '');
+ source = 'if(s.match("' + expr.replace(/\x22/g, '\\"') + '",e)){' + source + '}';
+ break;
+ case 'not':
+ expr = match[2].replace(REX.CommaGroup, ',').replace(REX.TrimSpaces, '');
+ source = 'if(!s.match("' + expr.replace(/\x22/g, '\\"') + '",e)){' + source + '}';
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** linguistic pseudo-classes
+ // :dir( ltr / rtl ), :lang( en )
+ else if ((match = selector.match(Patterns.linguistic))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'dir':
+ source = 'var p;if(' + N + '(' +
+ '(/' + match[2] + '/i.test(e.dir))||(p=s.ancestor("[dir]", e))&&' +
+ '(/' + match[2] + '/i.test(p.dir))||(e.dir==""||e.dir=="auto")&&' +
+ '(' + (match[2] == 'ltr' ? '!':'')+ RTL +'.test(e.textContent)))' +
+ '){' + source + '};';
+ break;
+ case 'lang':
+ expr = '(?:^|-)' + match[2] + '(?:-|$)';
+ source = 'var p;if(' + N + '(' +
+ '(e.isConnected&&(e.lang==""&&(p=s.ancestor("[lang]",e)))&&' +
+ '(p.lang=="' + match[2] + '")||/'+ expr +'/i.test(e.lang)))' +
+ '){' + source + '};';
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** location pseudo-classes
+ // :any-link, :link, :visited, :target
+ else if ((match = selector.match(Patterns.locationpc))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'any-link':
+ source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href")||e.visited)){' + source + '}';
+ break;
+ case 'link':
+ source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href"))){' + source + '}';
+ break;
+ case 'visited':
+ source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href")&&e.visited)){' + source + '}';
+ break;
+ case 'target':
+ source = 'if(' + N + '((s.doc.compareDocumentPosition(e)&16)&&s.doc.location.hash&&e.id==s.doc.location.hash.slice(1))){' + source + '}';
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** user actions pseudo-classes
+ // :hover, :active, :focus
+ else if ((match = selector.match(Patterns.useraction))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'hover':
+ source = 'hasFocus' in doc && doc.hasFocus() ?
+ 'if(' + N + '(e===s.doc.hoverElement)){' + source + '}' :
+ 'if(' + D + 'true){' + source + '}';
+ break;
+ case 'active':
+ source = 'hasFocus' in doc && doc.hasFocus() ?
+ 'if(' + N + '(e===s.doc.activeElement)){' + source + '}' :
+ 'if(' + D + 'true){' + source + '}';
+ break;
+ case 'focus':
+ source = 'hasFocus' in doc ?
+ 'if(' + N + '(e===s.doc.activeElement&&s.doc.hasFocus()&&(e.type||e.href||typeof e.tabIndex=="number"))){' + source + '}' :
+ 'if(' + N + '(e===s.doc.activeElement&&(e.type||e.href))){' + source + '}';
+ break;
+ case 'focus-within':
+ source = 'hasFocus' in doc ?
+ 'n=s.doc.activeElement;while(e){if(e===n||e.parentNode===n)break;}' +
+ 'if(' + N + '(e===n&&s.doc.hasFocus()&&(e.type||e.href||typeof e.tabIndex=="number"))){' + source + '}' : source;
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** user interface and form pseudo-classes
+ // :enabled, :disabled, :read-only, :read-write, :placeholder-shown, :default
+ else if ((match = selector.match(Patterns.inputstate))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'enabled':
+ source = 'if(' + N + '(("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e &&e.disabled===false' +
+ ')){' + source + '}';
+ break;
+ case 'disabled':
+ // https://www.w3.org/TR/html5/forms.html#enabling-and-disabling-form-controls:-the-disabled-attribute
+ source = 'if(' + N + '(("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e&&' +
+ '(e.disabled===true||(n=s.ancestor("fieldset",e))&&(n=s.first("legend",n))&&!n.contains(e))' +
+ ')){' + source + '}';
+ break;
+ case 'read-only':
+ source =
+ 'if(' + N + '(' +
+ '(/^textarea$/i.test(e.localName)&&(e.readOnly||e.disabled))||' +
+ '("|password|text|".includes("|"+e.type+"|")&&e.readOnly)' +
+ ')){' + source + '}';
+ break;
+ case 'read-write':
+ source =
+ 'if(' + N + '(' +
+ '((/^textarea$/i.test(e.localName)&&!e.readOnly&&!e.disabled)||' +
+ '("|password|text|".includes("|"+e.type+"|")&&!e.readOnly&&!e.disabled))||' +
+ '(e.hasAttribute("contenteditable")||(s.doc.designMode=="on"))' +
+ ')){' + source + '}';
+ break;
+ case 'placeholder-shown':
+ source =
+ 'if(' + N + '(' +
+ '(/^input|textarea$/i.test(e.localName))&&e.hasAttribute("placeholder")&&' +
+ '("|textarea|password|number|search|email|text|tel|url|".includes("|"+e.type+"|"))&&' +
+ '(!s.match(":focus",e))' +
+ ')){' + source + '}';
+ break;
+ case 'default':
+ source =
+ 'if(' + N + '("form" in e && e.form)){' +
+ 'var x=0;n=[];' +
+ 'if(e.type=="image")n=e.form.getElementsByTagName("input");' +
+ 'if(e.type=="submit")n=e.form.elements;' +
+ 'while(n[x]&&e!==n[x]){' +
+ 'if(n[x].type=="image")break;' +
+ 'if(n[x].type=="submit")break;' +
+ 'x++;' +
+ '}' +
+ '}' +
+ 'if(' + N + '(e.form&&(e===n[x]&&"|image|submit|".includes("|"+e.type+"|"))||' +
+ '((/^option$/i.test(e.localName))&&e.defaultSelected)||' +
+ '(("|radio|checkbox|".includes("|"+e.type+"|"))&&e.defaultChecked)' +
+ ')){' + source + '}';
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // *** input pseudo-classes (for form validation)
+ // :checked, :indeterminate, :valid, :invalid, :in-range, :out-of-range, :required, :optional
+ else if ((match = selector.match(Patterns.inputvalue))) {
+ match[1] = match[1].toLowerCase();
+ switch (match[1]) {
+ case 'checked':
+ source = 'if(' + N + '(/^input$/i.test(e.localName)&&' +
+ '("|radio|checkbox|".includes("|"+e.type+"|")&&e.checked)||' +
+ '(/^option$/i.test(e.localName)&&(e.selected||e.checked))' +
+ ')){' + source + '}';
+ break;
+ case 'indeterminate':
+ source =
+ 'if(' + N + '(/^progress$/i.test(e.localName)&&!e.hasAttribute("value"))||' +
+ '(/^input$/i.test(e.localName)&&("checkbox"==e.type&&e.indeterminate)||' +
+ '("radio"==e.type&&e.name&&!s.first("input[name="+e.name+"]:checked",e.form))' +
+ ')){' + source + '}';
+ break;
+ case 'required':
+ source =
+ 'if(' + N +
+ '(/^input|select|textarea$/i.test(e.localName)&&e.required)' +
+ '){' + source + '}';
+ break;
+ case 'optional':
+ source =
+ 'if(' + N +
+ '(/^input|select|textarea$/i.test(e.localName)&&!e.required)' +
+ '){' + source + '}';
+ break;
+ case 'invalid':
+ source =
+ 'if(' + N + '((' +
+ '(/^form$/i.test(e.localName)&&!e.noValidate)||' +
+ '(e.willValidate&&!e.formNoValidate))&&!e.checkValidity())||' +
+ '(/^fieldset$/i.test(e.localName)&&s.first(":invalid",e))' +
+ '){' + source + '}';
+ break;
+ case 'valid':
+ source =
+ 'if(' + N + '((' +
+ '(/^form$/i.test(e.localName)&&!e.noValidate)||' +
+ '(e.willValidate&&!e.formNoValidate))&&e.checkValidity())||' +
+ '(/^fieldset$/i.test(e.localName)&&s.first(":valid",e))' +
+ '){' + source + '}';
+ break;
+ case 'in-range':
+ source =
+ 'if(' + N +
+ '(/^input$/i.test(e.localName))&&' +
+ '(e.willValidate&&!e.formNoValidate)&&' +
+ '(!e.validity.rangeUnderflow&&!e.validity.rangeOverflow)&&' +
+ '("|date|datetime-local|month|number|range|time|week|".includes("|"+e.type+"|"))&&' +
+ '("range"==e.type||e.getAttribute("min")||e.getAttribute("max"))' +
+ '){' + source + '}';
+ break;
+ case 'out-of-range':
+ source =
+ 'if(' + N +
+ '(/^input$/i.test(e.localName))&&' +
+ '(e.willValidate&&!e.formNoValidate)&&' +
+ '(e.validity.rangeUnderflow||e.validity.rangeOverflow)&&' +
+ '("|date|datetime-local|month|number|range|time|week|".includes("|"+e.type+"|"))&&' +
+ '("range"==e.type||e.getAttribute("min")||e.getAttribute("max"))' +
+ '){' + source + '}';
+ break;
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break;
+ }
+ }
+
+ // allow pseudo-elements starting with single colon (:)
+ // :after, :before, :first-letter, :first-line
+ // assert: e.type is in double-colon format, like ::after
+ else if ((match = selector.match(Patterns.pseudo_sng))) {
+ source = 'if(e.element&&e.type.toLowerCase()=="' +
+ ':' + match[0].toLowerCase() + '"){e=e.element;' + source + '}';
+ }
+
+ // allow pseudo-elements starting with double colon (::)
+ // ::after, ::before, ::marker, ::placeholder, ::inactive-selection, ::selection, ::-webkit-<foo-bar>
+ // assert: e.type is in double-colon format, like ::after
+ else if ((match = selector.match(Patterns.pseudo_dbl))) {
+ source = 'if(e.element&&e.type.toLowerCase()=="' +
+ match[0].toLowerCase() + '"){e=e.element;' + source + '}';
+ }
+
+ // placeholder for parsed only no-op selectors
+ else if ((match = selector.match(Patterns.pseudo_nop))) {
+ source = 'if(' + N + 'false' + '){' + source + '}';
+ }
+
+ else {
+
+ // reset
+ expr = false;
+ status = false;
+
+ // process registered selector extensions
+ for (expr in Selectors) {
+ if ((match = selector.match(Selectors[expr].Expression))) {
+ result = Selectors[expr].Callback(match, source, mode, callback);
+ if ('match' in result) { match = result.match; }
+ vars = result.modvar;
+ if (mode) {
+ // add extra select() vars
+ vars && S_VARS.indexOf(vars) < 0 && (S_VARS[S_VARS.length] = vars);
+ } else {
+ // add extra match() vars
+ vars && M_VARS.indexOf(vars) < 0 && (M_VARS[M_VARS.length] = vars);
+ }
+ // extension source code
+ source = result.source;
+ // extension status code
+ status = result.status;
+ // break on status error
+ if (status) { break; }
+ }
+ }
+
+ if (!status) {
+ emit('unknown pseudo-class selector \'' + selector + '\'');
+ return '';
+ }
+
+ if (!expr) {
+ emit('unknown token in selector \'' + selector + '\'');
+ return '';
+ }
+
+ }
+ break;
+
+ default:
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ break selector_recursion_label;
+
+ }
+ // end of switch symbol
+
+ if (!match) {
+ emit('\'' + selector_string + '\'' + qsInvalid);
+ return '';
+ }
+
+ // pop last component
+ selector = match.pop();
+ }
+ // end of while selector
+
+ return source;
+ },
+
+ // replace ':scope' pseudo-class with element references
+ makeref =
+ function(selectors, element) {
+ return selectors.replace(/:scope/ig,
+ element.localName +
+ (element.id ? '#' + element.id : '') +
+ (element.className ? '.' + element.classList[0] : ''));
+ },
+
+ // equivalent of w3c 'closest' method
+ ancestor =
+ function _closest(selectors, element, callback) {
+
+ if ((/:scope/i).test(selectors)) {
+ selectors = makeref(selectors, element);
+ }
+
+ while (element) {
+ if (match(selectors, element, callback)) break;
+ element = element.parentElement;
+ }
+ return element;
+ },
+
+ match_assert =
+ function(f, element, callback) {
+ for (var i = 0, l = f.length, r = false; l > i; ++i)
+ f[i](element, callback, null, false) && (r = true);
+ return r;
+ },
+
+ match_collect =
+ function(selectors, callback) {
+ for (var i = 0, l = selectors.length, f = [ ]; l > i; ++i)
+ f[i] = compile(selectors[i], false, callback);
+ return { factory: f };
+ },
+
+ // equivalent of w3c 'matches' method
+ match =
+ function _matches(selectors, element, callback) {
+
+ var expressions, parsed;
+
+ if (element && matchResolvers[selectors]) {
+ return match_assert(matchResolvers[selectors].factory, element, callback);
+ }
+
+ lastMatched = selectors;
+
+ // arguments validation
+ if (arguments.length === 0) {
+ emit(qsNotArgs, TypeError);
+ return Config.VERBOSITY ? undefined : false;
+ } else if (arguments[0] === '') {
+ emit('\'\'' + qsInvalid);
+ return Config.VERBOSITY ? undefined : false;
+ }
+
+ // input NULL or UNDEFINED
+ if (typeof selectors != 'string') {
+ selectors = '' + selectors;
+ }
+
+ if ((/:scope/i).test(selectors)) {
+ selectors = makeref(selectors, element);
+ }
+
+ // normalize input string
+ parsed = selectors.
+ replace(/\x00|\\$/g, '\ufffd').
+ replace(REX.CombineWSP, '\x20').
+ replace(REX.PseudosWSP, '$1').
+ replace(REX.TabCharWSP, '\t').
+ replace(REX.CommaGroup, ',').
+ replace(REX.TrimSpaces, '');
+
+ // parse, validate and split possible compound selectors
+ if ((expressions = parsed.match(reValidator)) && expressions.join('') == parsed) {
+ expressions = parsed.match(REX.SplitGroup);
+ if (parsed[parsed.length - 1] == ',') {
+ emit(qsInvalid);
+ return Config.VERBOSITY ? undefined : false;
+ }
+ } else {
+ emit('\'' + selectors + '\'' + qsInvalid);
+ return Config.VERBOSITY ? undefined : false;
+ }
+
+ matchResolvers[selectors] = match_collect(expressions, callback);
+
+ return match_assert(matchResolvers[selectors].factory, element, callback);
+ },
+
+ // equivalent of w3c 'querySelector' method
+ first =
+ function _querySelector(selectors, context, callback) {
+ if (arguments.length === 0) {
+ emit(qsNotArgs, TypeError);
+ }
+ return select(selectors, context,
+ typeof callback == 'function' ?
+ function firstMatch(element) {
+ callback(element);
+ return false;
+ } :
+ function firstMatch() {
+ return false;
+ }
+ )[0] || null;
+ },
+
+ // equivalent of w3c 'querySelectorAll' method
+ select =
+ function _querySelectorAll(selectors, context, callback) {
+
+ var expressions, nodes = [ ], parsed, resolver;
+
+ context || (context = doc);
+
+ if (selectors) {
+ if ((resolver = selectResolvers[selectors])) {
+ if (resolver.context === context && resolver.callback === callback) {
+ var f = resolver.factory, h = resolver.htmlset, n = resolver.nodeset;
+ if (n.length > 1) {
+ for (var i = 0, l = n.length, list; l > i; ++i) {
+ list = compat[n[i][0]](context, n[i].slice(1))();
+ if (f[i] !== null) {
+ f[i](list, callback, context, nodes);
+ } else {
+ nodes = nodes.concat(list);
+ }
+ }
+ if (l > 1 && nodes.length > 1) {
+ nodes.sort(documentOrder);
+ hasDupes && (nodes = unique(nodes));
+ }
+ } else {
+ if (f[0]) {
+ nodes = f[0](h[0](), callback, context, nodes);
+ } else {
+ nodes = h[0]();
+ }
+ }
+ return typeof callback == 'function' ?
+ concatCall(nodes, callback) : nodes;
+ }
+ }
+ }
+
+ lastSelected = selectors;
+
+ // arguments validation
+ if (arguments.length === 0) {
+ emit(qsNotArgs, TypeError);
+ return Config.VERBOSITY ? undefined : none;
+ } else if (arguments[0] === '') {
+ emit('\'\'' + qsInvalid);
+ return Config.VERBOSITY ? undefined : none;
+ } else if (lastContext !== context) {
+ lastContext = switchContext(context);
+ }
+
+ // input NULL or UNDEFINED
+ if (typeof selectors != 'string') {
+ selectors = '' + selectors;
+ }
+
+ if ((/:scope/i).test(selectors)) {
+ selectors = makeref(selectors, context);
+ }
+
+ // normalize input string
+ parsed = selectors.
+ replace(/\x00|\\$/g, '\ufffd').
+ replace(REX.CombineWSP, '\x20').
+ replace(REX.PseudosWSP, '$1').
+ replace(REX.TabCharWSP, '\t').
+ replace(REX.CommaGroup, ',').
+ replace(REX.TrimSpaces, '');
+
+ // parse, validate and split possible compound selectors
+ if ((expressions = parsed.match(reValidator)) && expressions.join('') == parsed) {
+ expressions = parsed.match(REX.SplitGroup);
+ if (parsed[parsed.length - 1] == ',') {
+ emit(qsInvalid);
+ return Config.VERBOSITY ? undefined : false;
+ }
+ } else {
+ emit('\'' + selectors + '\'' + qsInvalid);
+ return Config.VERBOSITY ? undefined : false;
+ }
+
+ // save/reuse factory and closure collection
+ selectResolvers[selectors] = collect(expressions, context, callback);
+
+ nodes = selectResolvers[selectors].results;
+
+ return typeof callback == 'function' ?
+ concatCall(nodes, callback) : nodes;
+ },
+
+ // optimize selectors avoiding duplicated checks
+ optimize =
+ function(selector, token) {
+ var index = token.index,
+ length = token[1].length + token[2].length;
+ return selector.slice(0, index) +
+ (' >+~'.indexOf(selector.charAt(index - 1)) > -1 ?
+ (':['.indexOf(selector.charAt(index + length + 1)) > -1 ?
+ '*' : '') : '') + selector.slice(index + length - (token[1] == '*' ? 1 : 0));
+ },
+
+ // prepare factory resolvers and closure collections
+ collect =
+ function(selectors, context, callback) {
+
+ var i, l, seen = { }, token = ['', '*', '*'], optimized = selectors,
+ factory = [ ], htmlset = [ ], nodeset = [ ], results = [ ], type;
+
+ for (i = 0, l = selectors.length; l > i; ++i) {
+
+ if (!seen[selectors[i]] && (seen[selectors[i]] = true)) {
+ type = selectors[i].match(reOptimizer);
+ if (type && type[1] != ':' && (token = type)) {
+ token[1] || (token[1] = '*');
+ optimized[i] = optimize(optimized[i], token);
+ } else {
+ token = ['', '*', '*'];
+ }
+ }
+
+ nodeset[i] = token[1] + token[2];
+ htmlset[i] = compat[token[1]](context, token[2]);
+ factory[i] = compile(optimized[i], true, null);
+
+ factory[i] ?
+ factory[i](htmlset[i](), callback, context, results) :
+ result.concat(htmlset[i]());
+ }
+
+ if (l > 1) {
+ results.sort(documentOrder);
+ hasDupes && (results = unique(results));
+ }
+
+ return {
+ callback: callback,
+ context: context,
+ factory: factory,
+ htmlset: htmlset,
+ nodeset: nodeset,
+ results: results
+ };
+
+ },
+
+ // QSA placeholders to native references
+ _closest, _matches, _querySelector, _querySelectorAll,
+
+ // overrides QSA methods (only for browsers)
+ install =
+ function(all) {
+
+ // save native QSA references
+ _closest = Element.prototype.closest;
+ _matches = Element.prototype.matches;
+ _querySelector = Document.prototype.querySelector;
+ _querySelectorAll = Document.prototype.querySelectorAll;
+
+ Element.prototype.closest =
+ function closest() {
+ var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
+ if (!('nodeType' in this)) { emit('\'closest\' called on an object that does not implement interface ' + ctor + '.', TypeError); }
+ return arguments.length < 1 ? ancestor.apply(this, [ ]) :
+ arguments.length < 2 ? ancestor.apply(this, [ arguments[0], this ]) :
+ ancestor.apply(this, [ arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined ]);
+ };
+
+ Element.prototype.matches =
+ function matches() {
+ var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
+ if (!('nodeType' in this)) { emit('\'matches\' called on an object that does not implement interface ' + ctor + '.', TypeError); }
+ return arguments.length < 1 ? match.apply(this, [ ]) :
+ arguments.length < 2 ? match.apply(this, [ arguments[0], this ]) :
+ match.apply(this, [ arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined ]);
+ };
+
+ Element.prototype.querySelector =
+ Document.prototype.querySelector =
+ DocumentFragment.prototype.querySelector =
+ function querySelector() {
+ var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
+ if (!('nodeType' in this)) { emit('\'querySelector\' called on an object that does not implement interface ' + ctor + '.', TypeError); }
+ return arguments.length < 1 ? first.apply(this, [ ]) :
+ arguments.length < 2 ? first.apply(this, [ arguments[0], this ]) :
+ first.apply(this, [ arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined ]);
+ };
+
+ Element.prototype.querySelectorAll =
+ Document.prototype.querySelectorAll =
+ DocumentFragment.prototype.querySelectorAll =
+ function querySelectorAll() {
+ var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
+ if (!('nodeType' in this)) { emit('\'querySelectorAll\' called on an object that does not implement interface ' + ctor + '.', TypeError); }
+ return arguments.length < 1 ? select.apply(this, [ ]) :
+ arguments.length < 2 ? select.apply(this, [ arguments[0], this ]) :
+ select.apply(this, [ arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined ]);
+ };
+
+ if (all) {
+ document.addEventListener('load', function(e) {
+ var c, d, r, s, t = e.target;
+ if (/iframe/i.test(t.localName)) {
+ c = '(' + Export + ')(this, ' + Factory + ');'; d = t.contentDocument;
+ s = d.createElement('script'); s.textContent = c + 'NW.Dom.install()';
+ r = d.documentElement; r.removeChild(r.insertBefore(s, r.firstChild));
+ }
+ }, true);
+ }
+
+ },
+
+ // restore QSA methods (only for browsers)
+ uninstall =
+ function() {
+ // reinstates QSA native references
+ Element.prototype.closest = _closest;
+ Element.prototype.matches = _matches;
+ Element.prototype.querySelector =
+ Document.prototype.querySelector =
+ DocumentFragment.prototype.querySelector = _querySelector;
+ Element.prototype.querySelectorAll =
+ Document.prototype.querySelectorAll =
+ DocumentFragment.prototype.querySelectorAll = _querySelectorAll;
+ },
+
+ // empty set
+ none = Array(),
+
+ // context
+ lastContext,
+
+ // selector
+ lastMatched,
+ lastSelected,
+
+ // cached lambdas
+ matchLambdas = { },
+ selectLambdas = { },
+
+ // cached resolvers
+ matchResolvers = { },
+ selectResolvers = { },
+
+ // passed to resolvers
+ Snapshot = {
+
+ doc: doc,
+ from: doc,
+ root: root,
+
+ byTag: byTag,
+
+ first: first,
+ match: match,
+
+ ancestor: ancestor,
+
+ nthOfType: nthOfType,
+ nthElement: nthElement,
+
+ hasAttributeNS: hasAttributeNS
+ },
+
+ // public exported methods/objects
+ Dom = {
+
+ // exported cache objects
+
+ lastMatched: lastMatched,
+ lastSelected: lastSelected,
+
+ matchLambdas: matchLambdas,
+ selectLambdas: selectLambdas,
+
+ matchResolvers: matchResolvers,
+ selectResolvers: selectResolvers,
+
+ // exported compiler macros
+
+ CFG: CFG,
+
+ M_BODY: M_BODY,
+ S_BODY: S_BODY,
+ M_TEST: M_TEST,
+ S_TEST: S_TEST,
+
+ // exported engine methods
+
+ byId: byId,
+ byTag: byTag,
+ byClass: byClass,
+
+ match: match,
+ first: first,
+ select: select,
+ closest: ancestor,
+
+ compile: compile,
+ configure: configure,
+
+ emit: emit,
+ Config: Config,
+ Snapshot: Snapshot,
+
+ Version: version,
+
+ install: install,
+ uninstall: uninstall,
+
+ Operators: Operators,
+ Selectors: Selectors,
+
+ // register a new selector combinator symbol and its related function resolver
+ registerCombinator:
+ function(combinator, resolver) {
+ var i = 0, l = combinator.length, symbol;
+ for (; l > i; ++i) {
+ if (combinator[i] != '=') {
+ symbol = combinator[i];
+ break;
+ }
+ }
+ if (CFG.combinators.indexOf(symbol) < 0) {
+ CFG.combinators = CFG.combinators.replace('](', symbol + '](');
+ CFG.combinators = CFG.combinators.replace('])', symbol + '])');
+ Combinators[combinator] = resolver;
+ setIdentifierSyntax();
+ } else {
+ console.warn('Warning: the \'' + combinator + '\' combinator is already registered.');
+ }
+ },
+
+ // register a new attribute operator symbol and its related function resolver
+ registerOperator:
+ function(operator, resolver) {
+ var i = 0, l = operator.length, symbol;
+ for (; l > i; ++i) {
+ if (operator[i] != '=') {
+ symbol = operator[i];
+ break;
+ }
+ }
+ if (CFG.operators.indexOf(symbol) < 0 && !Operators[operator]) {
+ CFG.operators = CFG.operators.replace(']=', symbol + ']=');
+ Operators[operator] = resolver;
+ setIdentifierSyntax();
+ } else {
+ console.warn('Warning: the \'' + operator + '\' operator is already registered.');
+ }
+ },
+
+ // register a new selector symbol and its related function resolver
+ registerSelector:
+ function(name, rexp, func) {
+ Selectors[name] || (Selectors[name] = {
+ Expression: rexp,
+ Callback: func
+ });
+ }
+
+ };
+
+ initialize(doc);
+
+ return Dom;
+
+});