netscape-bookmark-parser 1.1.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +2 -2
  2. package/README-ja.md +108 -98
  3. package/README.md +108 -98
  4. package/dist/index.d.ts +240 -0
  5. package/dist/index.js +333 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/web.d.ts +241 -0
  8. package/dist/web.js +330 -0
  9. package/dist/web.js.map +1 -0
  10. package/package.json +58 -15
  11. package/esm/_dnt.polyfills.d.ts +0 -101
  12. package/esm/_dnt.polyfills.d.ts.map +0 -1
  13. package/esm/_dnt.polyfills.js +0 -127
  14. package/esm/_dnt.shims.d.ts +0 -6
  15. package/esm/_dnt.shims.d.ts.map +0 -1
  16. package/esm/_dnt.shims.js +0 -61
  17. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/build/deno-wasm/deno-wasm.d.ts +0 -14
  18. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/build/deno-wasm/deno-wasm.d.ts.map +0 -1
  19. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/build/deno-wasm/deno-wasm.js +0 -151
  20. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.d.ts +0 -23
  21. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.d.ts.map +0 -1
  22. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js +0 -26
  23. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/api.d.ts +0 -24
  24. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/api.d.ts.map +0 -1
  25. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/api.js +0 -48
  26. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/constructor-lock.d.ts +0 -5
  27. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/constructor-lock.d.ts.map +0 -1
  28. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/constructor-lock.js +0 -4
  29. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/deserialize.d.ts +0 -4
  30. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/deserialize.d.ts.map +0 -1
  31. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/deserialize.js +0 -61
  32. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document-fragment.d.ts +0 -19
  33. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document-fragment.d.ts.map +0 -1
  34. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document-fragment.js +0 -110
  35. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document.d.ts +0 -68
  36. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document.d.ts.map +0 -1
  37. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document.js +0 -322
  38. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/dom-parser.d.ts +0 -6
  39. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/dom-parser.d.ts.map +0 -1
  40. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/dom-parser.js +0 -46
  41. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/element.d.ts +0 -127
  42. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/element.d.ts.map +0 -1
  43. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/element.js +0 -1068
  44. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/elements/html-template-element.d.ts +0 -29
  45. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/elements/html-template-element.d.ts.map +0 -1
  46. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/elements/html-template-element.js +0 -94
  47. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/html-collection.d.ts +0 -21
  48. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/html-collection.d.ts.map +0 -1
  49. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/html-collection.js +0 -80
  50. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node-list.d.ts +0 -23
  51. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node-list.d.ts.map +0 -1
  52. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node-list.js +0 -159
  53. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node.d.ts +0 -127
  54. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node.d.ts.map +0 -1
  55. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node.js +0 -629
  56. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/custom-api.d.ts +0 -6
  57. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/custom-api.d.ts.map +0 -1
  58. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/custom-api.js +0 -5
  59. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi-types.d.ts +0 -12
  60. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi-types.d.ts.map +0 -1
  61. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi-types.js +0 -2
  62. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi.d.ts +0 -90
  63. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi.d.ts.map +0 -1
  64. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi.js +0 -1611
  65. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/selectors.d.ts +0 -16
  66. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/selectors.d.ts.map +0 -1
  67. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/selectors.js +0 -28
  68. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle-types.d.ts +0 -8
  69. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle-types.d.ts.map +0 -1
  70. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle-types.js +0 -2
  71. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle.d.ts +0 -7
  72. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle.d.ts.map +0 -1
  73. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle.js +0 -2061
  74. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.d.ts +0 -3
  75. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.d.ts.map +0 -1
  76. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.js +0 -10
  77. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.d.ts +0 -13
  78. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.d.ts.map +0 -1
  79. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.js +0 -8
  80. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.d.ts +0 -31
  81. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.d.ts.map +0 -1
  82. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.js +0 -239
  83. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.d.ts +0 -5
  84. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.d.ts.map +0 -1
  85. package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.js +0 -20
  86. package/esm/mod.d.ts +0 -10
  87. package/esm/mod.d.ts.map +0 -1
  88. package/esm/mod.js +0 -9
  89. package/esm/mod_web.d.ts +0 -9
  90. package/esm/mod_web.d.ts.map +0 -1
  91. package/esm/mod_web.js +0 -8
  92. package/esm/package.json +0 -3
  93. package/esm/src/BookmarksParser/BookmarksParser.d.ts +0 -130
  94. package/esm/src/BookmarksParser/BookmarksParser.d.ts.map +0 -1
  95. package/esm/src/BookmarksParser/BookmarksParser.js +0 -142
  96. package/esm/src/BookmarksParser/index.d.ts +0 -8
  97. package/esm/src/BookmarksParser/index.d.ts.map +0 -1
  98. package/esm/src/BookmarksParser/index.js +0 -7
  99. package/esm/src/BookmarksTree/BookmarksTree.d.ts +0 -118
  100. package/esm/src/BookmarksTree/BookmarksTree.d.ts.map +0 -1
  101. package/esm/src/BookmarksTree/BookmarksTree.js +0 -225
  102. package/esm/src/BookmarksTree/index.d.ts +0 -8
  103. package/esm/src/BookmarksTree/index.d.ts.map +0 -1
  104. package/esm/src/BookmarksTree/index.js +0 -7
  105. package/esm/src/deps.d.ts +0 -9
  106. package/esm/src/deps.d.ts.map +0 -1
  107. package/esm/src/deps.js +0 -7
  108. package/esm/src/web/BookmarksParser/BookmarksParser.d.ts +0 -130
  109. package/esm/src/web/BookmarksParser/BookmarksParser.d.ts.map +0 -1
  110. package/esm/src/web/BookmarksParser/BookmarksParser.js +0 -142
  111. package/esm/src/web/BookmarksParser/index.d.ts +0 -8
  112. package/esm/src/web/BookmarksParser/index.d.ts.map +0 -1
  113. package/esm/src/web/BookmarksParser/index.js +0 -7
  114. package/esm/src/web/BookmarksTree/BookmarksTree.d.ts +0 -118
  115. package/esm/src/web/BookmarksTree/BookmarksTree.d.ts.map +0 -1
  116. package/esm/src/web/BookmarksTree/BookmarksTree.js +0 -225
  117. package/esm/src/web/BookmarksTree/index.d.ts +0 -8
  118. package/esm/src/web/BookmarksTree/index.d.ts.map +0 -1
  119. package/esm/src/web/BookmarksTree/index.js +0 -7
  120. package/esm/src/web/deps.d.ts +0 -10
  121. package/esm/src/web/deps.d.ts.map +0 -1
  122. package/esm/src/web/deps.js +0 -9
@@ -1,1611 +0,0 @@
1
- // @ts-nocheck: 3rd-party
2
- /*
3
- * Copyright (C) 2007-2019 Diego Perini
4
- * All rights reserved.
5
- *
6
- * nwsapi.js - Fast CSS Selectors API Engine
7
- *
8
- * Author: Diego Perini <diego.perini at gmail com>
9
- * Version: 2.2.0
10
- * Created: 20070722
11
- * Release: 20210622
12
- *
13
- * License:
14
- * http://javascript.nwbox.com/nwsapi/MIT-LICENSE
15
- * Download:
16
- * http://javascript.nwbox.com/nwsapi/nwsapi.js
17
- */
18
- export default document => {
19
- const NW = Factory({ document, DOMException }, "null");
20
- NW.configure({
21
- IDS_DUPES: false,
22
- LOGERRORS: false,
23
- });
24
- return NW;
25
- };
26
- function Factory(global, Export) {
27
- var version = 'nwsapi-2.2.0', doc = global.document, root = doc.documentElement, slice = Array.prototype.slice, WSP = '[\\x20\\t\\r\\n\\f]', CFG = {
28
- // extensions
29
- operators: '[~*^$|]=|=',
30
- combinators: '[\\x20\\t>+~](?=[^>+~])'
31
- }, NOT = {
32
- // not enclosed in double/single/parens/square
33
- double_enc: '(?=(?:[^"]*["][^"]*["])*[^"]*$)',
34
- single_enc: "(?=(?:[^']*['][^']*['])*[^']*$)",
35
- parens_enc: '(?![^\\x28]*\\x29)',
36
- square_enc: '(?![^\\x5b]*\\x5d)'
37
- }, REX = {
38
- // regular expressions
39
- HasEscapes: RegExp('\\\\'),
40
- HexNumbers: RegExp('^[0-9a-fA-F]'),
41
- EscOrQuote: RegExp('^\\\\|[\\x22\\x27]'),
42
- RegExpChar: RegExp('(?:(?!\\\\)[\\\\^$.*+?()[\\]{}|\\/])', 'g'),
43
- TrimSpaces: RegExp('[\\r\\n\\f]|^' + WSP + '+|' + WSP + '+$', 'g'),
44
- CommaGroup: RegExp('(\\s*,\\s*)' + NOT.square_enc + NOT.parens_enc, 'g'),
45
- SplitGroup: RegExp('((?:\\x28[^\\x29]*\\x29|\\[[^\\]]*\\]|\\\\.|[^,])+)', 'g'),
46
- FixEscapes: RegExp('\\\\([0-9a-fA-F]{1,6}' + WSP + '?|.)|([\\x22\\x27])', 'g'),
47
- CombineWSP: RegExp('[\\n\\r\\f\\x20]+' + NOT.single_enc + NOT.double_enc, 'g'),
48
- TabCharWSP: RegExp('(\\x20?\\t+\\x20?)' + NOT.single_enc + NOT.double_enc, 'g'),
49
- PseudosWSP: RegExp('\\s+([-+])\\s+' + NOT.square_enc, 'g')
50
- }, STD = {
51
- combinator: RegExp('\\s?([>+~])\\s?', 'g'),
52
- apimethods: RegExp('^(?:[a-z]+|\\*)\\|', 'i'),
53
- namespaces: RegExp('(\\*|[a-z]+)\\|[-a-z]+', 'i')
54
- }, GROUPS = {
55
- // pseudo-classes requiring parameters
56
- linguistic: '(dir|lang)\\x28\\s?([-\\w]{2,})\\s?(?:\\x29|$)',
57
- logicalsel: '(is|where|matches|not)\\x28\\s?([^()]*|[^\\x28]*\\x28[^\\x29]*\\x29)\\s?(?:\\x29|$)',
58
- treestruct: '(nth(?:-last)?(?:-child|-of-type))(?:\\x28\\s?(even|odd|(?:[-+]?\\d*)(?:n\\s?[-+]?\\s?\\d*)?)\\s?(?:\\x29|$))',
59
- // pseudo-classes not requiring parameters
60
- locationpc: '(any-link|link|visited|target)\\b',
61
- useraction: '(hover|active|focus|focus-within)\\b',
62
- structural: '(root|empty|(?:(?:first|last|only)(?:-child|-of-type)))\\b',
63
- inputstate: '(enabled|disabled|read-only|read-write|placeholder-shown|default)\\b',
64
- inputvalue: '(checked|indeterminate|required|optional|valid|invalid|in-range|out-of-range)\\b',
65
- // pseudo-elements starting with single colon (:)
66
- pseudo_sng: '(after|before|first-letter|first-line)\\b',
67
- // pseudo-elements starting with double colon (::)
68
- pseudo_dbl: ':(after|before|first-letter|first-line|selection|placeholder|-webkit-[-a-zA-Z0-9]{2,})\\b'
69
- }, Patterns = {
70
- // pseudo-classes
71
- treestruct: RegExp('^:(?:' + GROUPS.treestruct + ')(.*)', 'i'),
72
- structural: RegExp('^:(?:' + GROUPS.structural + ')(.*)', 'i'),
73
- linguistic: RegExp('^:(?:' + GROUPS.linguistic + ')(.*)', 'i'),
74
- useraction: RegExp('^:(?:' + GROUPS.useraction + ')(.*)', 'i'),
75
- inputstate: RegExp('^:(?:' + GROUPS.inputstate + ')(.*)', 'i'),
76
- inputvalue: RegExp('^:(?:' + GROUPS.inputvalue + ')(.*)', 'i'),
77
- locationpc: RegExp('^:(?:' + GROUPS.locationpc + ')(.*)', 'i'),
78
- logicalsel: RegExp('^:(?:' + GROUPS.logicalsel + ')(.*)', 'i'),
79
- pseudo_dbl: RegExp('^:(?:' + GROUPS.pseudo_dbl + ')(.*)', 'i'),
80
- pseudo_sng: RegExp('^:(?:' + GROUPS.pseudo_sng + ')(.*)', 'i'),
81
- // combinator symbols
82
- children: RegExp('^' + WSP + '?\\>' + WSP + '?(.*)'),
83
- adjacent: RegExp('^' + WSP + '?\\+' + WSP + '?(.*)'),
84
- relative: RegExp('^' + WSP + '?\\~' + WSP + '?(.*)'),
85
- ancestor: RegExp('^' + WSP + '+(.*)'),
86
- // universal & namespace
87
- universal: RegExp('^\\*(.*)'),
88
- namespace: RegExp('^(\\w+|\\*)?\\|(.*)')
89
- },
90
- // regexp to aproximate detection of RTL languages (Arabic)
91
- RTL = RegExp('^[\\u0591-\\u08ff\\ufb1d-\\ufdfd\\ufe70-\\ufefc ]+$'),
92
- // emulate firefox error strings
93
- qsNotArgs = 'Not enough arguments', qsInvalid = ' is not a valid selector',
94
- // detect structural pseudo-classes in selectors
95
- reNthElem = RegExp('(:nth(?:-last)?-child)', 'i'), reNthType = RegExp('(:nth(?:-last)?-of-type)', 'i'),
96
- // placeholder for global regexp
97
- reOptimizer, reValidator,
98
- // special handling configuration flags
99
- Config = {
100
- IDS_DUPES: true,
101
- MIXEDCASE: true,
102
- LOGERRORS: true,
103
- VERBOSITY: true
104
- }, NAMESPACE, QUIRKS_MODE, HTML_DOCUMENT, ATTR_STD_OPS = {
105
- '=': 1, '^=': 1, '$=': 1, '|=': 1, '*=': 1, '~=': 1
106
- }, HTML_TABLE = {
107
- 'accept': 1, 'accept-charset': 1, 'align': 1, 'alink': 1, 'axis': 1,
108
- 'bgcolor': 1, 'charset': 1, 'checked': 1, 'clear': 1, 'codetype': 1, 'color': 1,
109
- 'compact': 1, 'declare': 1, 'defer': 1, 'dir': 1, 'direction': 1, 'disabled': 1,
110
- 'enctype': 1, 'face': 1, 'frame': 1, 'hreflang': 1, 'http-equiv': 1, 'lang': 1,
111
- 'language': 1, 'link': 1, 'media': 1, 'method': 1, 'multiple': 1, 'nohref': 1,
112
- 'noresize': 1, 'noshade': 1, 'nowrap': 1, 'readonly': 1, 'rel': 1, 'rev': 1,
113
- 'rules': 1, 'scope': 1, 'scrolling': 1, 'selected': 1, 'shape': 1, 'target': 1,
114
- 'text': 1, 'type': 1, 'valign': 1, 'valuetype': 1, 'vlink': 1
115
- }, Combinators = {}, Selectors = {}, Operators = {
116
- '=': { p1: '^',
117
- p2: '$',
118
- p3: 'true' },
119
- '^=': { p1: '^',
120
- p2: '',
121
- p3: 'true' },
122
- '$=': { p1: '',
123
- p2: '$',
124
- p3: 'true' },
125
- '*=': { p1: '',
126
- p2: '',
127
- p3: 'true' },
128
- '|=': { p1: '^',
129
- p2: '(-|$)',
130
- p3: 'true' },
131
- '~=': { p1: '(^|\\s)',
132
- p2: '(\\s|$)',
133
- p3: 'true' }
134
- }, concatCall = function (nodes, callback) {
135
- var i = 0, l = nodes.length, list = Array(l);
136
- while (l > i) {
137
- if (false === callback(list[i] = nodes[i]))
138
- break;
139
- ++i;
140
- }
141
- return list;
142
- }, concatList = function (list, nodes) {
143
- var i = -1, l = nodes.length;
144
- while (l--) {
145
- list[list.length] = nodes[++i];
146
- }
147
- return list;
148
- }, documentOrder = function (a, b) {
149
- if (!hasDupes && a === b) {
150
- hasDupes = true;
151
- return 0;
152
- }
153
- return a.compareDocumentPosition(b) & 4 ? -1 : 1;
154
- }, hasDupes = false, unique = function (nodes) {
155
- var i = 0, j = -1, l = nodes.length + 1, list = [];
156
- while (--l) {
157
- if (nodes[i++] === nodes[i])
158
- continue;
159
- list[++j] = nodes[i - 1];
160
- }
161
- hasDupes = false;
162
- return list;
163
- },
164
- // check context for mixed content
165
- hasMixedCaseTagNames = function (context) {
166
- var ns, api = 'getElementsByTagNameNS';
167
- // current host context (ownerDocument)
168
- context = context.ownerDocument || context;
169
- // documentElement (root) element namespace or default html/xhtml namespace
170
- ns = context.documentElement.namespaceURI || 'http://www.w3.org/1999/xhtml';
171
- // checking the number of non HTML nodes in the document
172
- return (context[api]('*', '*').length - context[api](ns, '*').length) > 0;
173
- }, switchContext = function (context, force) {
174
- var oldDoc = doc;
175
- doc = context.ownerDocument || context;
176
- if (force || oldDoc !== doc) {
177
- // force a new check for each document change
178
- // performed before the next select operation
179
- root = doc.documentElement;
180
- HTML_DOCUMENT = isHTML(doc);
181
- QUIRKS_MODE = HTML_DOCUMENT &&
182
- doc.compatMode.indexOf('CSS') < 0;
183
- NAMESPACE = root && root.namespaceURI;
184
- Snapshot.doc = doc;
185
- Snapshot.root = root;
186
- }
187
- return (Snapshot.from = context);
188
- },
189
- // convert single codepoint to UTF-16 encoding
190
- codePointToUTF16 = function (codePoint) {
191
- // out of range, use replacement character
192
- if (codePoint < 1 || codePoint > 0x10ffff ||
193
- (codePoint > 0xd7ff && codePoint < 0xe000)) {
194
- return '\\ufffd';
195
- }
196
- // javascript strings are UTF-16 encoded
197
- if (codePoint < 0x10000) {
198
- var lowHex = '000' + codePoint.toString(16);
199
- return '\\u' + lowHex.substr(lowHex.length - 4);
200
- }
201
- // supplementary high + low surrogates
202
- return '\\u' + (((codePoint - 0x10000) >> 0x0a) + 0xd800).toString(16) +
203
- '\\u' + (((codePoint - 0x10000) % 0x400) + 0xdc00).toString(16);
204
- },
205
- // convert single codepoint to string
206
- stringFromCodePoint = function (codePoint) {
207
- // out of range, use replacement character
208
- if (codePoint < 1 || codePoint > 0x10ffff ||
209
- (codePoint > 0xd7ff && codePoint < 0xe000)) {
210
- return '\ufffd';
211
- }
212
- if (codePoint < 0x10000) {
213
- return String.fromCharCode(codePoint);
214
- }
215
- return String.fromCodePoint ?
216
- String.fromCodePoint(codePoint) :
217
- String.fromCharCode(((codePoint - 0x10000) >> 0x0a) + 0xd800, ((codePoint - 0x10000) % 0x400) + 0xdc00);
218
- },
219
- // convert escape sequence in a CSS string or identifier
220
- // to javascript string with javascript escape sequences
221
- convertEscapes = function (str) {
222
- return REX.HasEscapes.test(str) ?
223
- str.replace(REX.FixEscapes, function (substring, p1, p2) {
224
- // unescaped " or '
225
- return p2 ? '\\' + p2 :
226
- // javascript strings are UTF-16 encoded
227
- REX.HexNumbers.test(p1) ? codePointToUTF16(parseInt(p1, 16)) :
228
- // \' \"
229
- REX.EscOrQuote.test(p1) ? substring :
230
- // \g \h \. \# etc
231
- p1;
232
- }) : str;
233
- },
234
- // convert escape sequence in a CSS string or identifier
235
- // to javascript string with characters representations
236
- unescapeIdentifier = function (str) {
237
- return REX.HasEscapes.test(str) ?
238
- str.replace(REX.FixEscapes, function (substring, p1, p2) {
239
- // unescaped " or '
240
- return p2 ? p2 :
241
- // javascript strings are UTF-16 encoded
242
- REX.HexNumbers.test(p1) ? stringFromCodePoint(parseInt(p1, 16)) :
243
- // \' \"
244
- REX.EscOrQuote.test(p1) ? substring :
245
- // \g \h \. \# etc
246
- p1;
247
- }) : str;
248
- }, method = {
249
- '#': 'getElementById',
250
- '*': 'getElementsByTagNameNS',
251
- '.': 'getElementsByClassName'
252
- }, compat = {
253
- '#': function (c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function (e, f) { return byId(n, c); }; },
254
- '*': function (c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function (e, f) { return byTag(n, c); }; },
255
- '.': function (c, n) { REX.HasEscapes.test(n) && (n = unescapeIdentifier(n)); return function (e, f) { return byClass(n, c); }; }
256
- },
257
- // find duplicate ids using iterative walk
258
- byIdRaw = function (id, context) {
259
- var node = context, nodes = [], next = node.firstElementChild;
260
- while ((node = next)) {
261
- node.id == id && (nodes[nodes.length] = node);
262
- if ((next = node.firstElementChild || node.nextElementSibling))
263
- continue;
264
- while (!next && (node = node.parentElement) && node !== context) {
265
- next = node.nextElementSibling;
266
- }
267
- }
268
- return nodes;
269
- },
270
- // context agnostic getElementById
271
- byId = function (id, context) {
272
- var e, nodes, api = method['#'];
273
- // duplicates id allowed
274
- if (Config.IDS_DUPES === false) {
275
- if (api in context) {
276
- return (e = context[api](id)) ? [e] : none;
277
- }
278
- }
279
- else {
280
- if ('all' in context) {
281
- if ((e = context.all[id])) {
282
- if (e.nodeType == 1)
283
- return e.getAttribute('id') != id ? [] : [e];
284
- else if (id == 'length')
285
- return (e = context[api](id)) ? [e] : none;
286
- for (i = 0, l = e.length, nodes = []; l > i; ++i) {
287
- if (e[i].id == id)
288
- nodes[nodes.length] = e[i];
289
- }
290
- return nodes && nodes.length ? nodes : [nodes];
291
- }
292
- else
293
- return none;
294
- }
295
- }
296
- return byIdRaw(id, context);
297
- },
298
- // context agnostic getElementsByTagName
299
- byTag = function (tag, context) {
300
- var e, nodes, api = method['*'];
301
- // DOCUMENT_NODE (9) & ELEMENT_NODE (1)
302
- if (api in context) {
303
- return slice.call(context[api]('*', tag));
304
- }
305
- else {
306
- tag = tag.toLowerCase();
307
- // DOCUMENT_FRAGMENT_NODE (11)
308
- if ((e = context.firstElementChild)) {
309
- if (!(e.nextElementSibling || tag == '*' || e.localName == tag)) {
310
- return slice.call(e[api]('*', tag));
311
- }
312
- else {
313
- nodes = [];
314
- do {
315
- if (tag == '*' || e.localName == tag)
316
- nodes[nodes.length] = e;
317
- concatList(nodes, e[api]('*', tag));
318
- } while ((e = e.nextElementSibling));
319
- }
320
- }
321
- else
322
- nodes = none;
323
- }
324
- return nodes;
325
- },
326
- // context agnostic getElementsByClassName
327
- byClass = function (cls, context) {
328
- var e, nodes, api = method['.'], reCls;
329
- // DOCUMENT_NODE (9) & ELEMENT_NODE (1)
330
- if (api in context) {
331
- return slice.call(context[api](cls));
332
- }
333
- else {
334
- // DOCUMENT_FRAGMENT_NODE (11)
335
- if ((e = context.firstElementChild)) {
336
- reCls = RegExp('(^|\\s)' + cls + '(\\s|$)', QUIRKS_MODE ? 'i' : '');
337
- if (!(e.nextElementSibling || reCls.test(e.className))) {
338
- return slice.call(e[api](cls));
339
- }
340
- else {
341
- nodes = [];
342
- do {
343
- if (reCls.test(e.className))
344
- nodes[nodes.length] = e;
345
- concatList(nodes, e[api](cls));
346
- } while ((e = e.nextElementSibling));
347
- }
348
- }
349
- else
350
- nodes = none;
351
- }
352
- return nodes;
353
- },
354
- // namespace aware hasAttribute
355
- // helper for XML/XHTML documents
356
- hasAttributeNS = function (e, name) {
357
- var i, l, attr = e.getAttributeNames();
358
- name = RegExp(':?' + name + '$', HTML_DOCUMENT ? 'i' : '');
359
- for (i = 0, l = attr.length; l > i; ++i) {
360
- if (name.test(attr[i]))
361
- return true;
362
- }
363
- return false;
364
- },
365
- // fast resolver for the :nth-child() and :nth-last-child() pseudo-classes
366
- nthElement = (function () {
367
- var idx = 0, len = 0, set = 0, parent = undefined, parents = Array(), nodes = Array();
368
- return function (element, dir) {
369
- // ensure caches are emptied after each run, invoking with dir = 2
370
- if (dir == 2) {
371
- idx = 0;
372
- len = 0;
373
- set = 0;
374
- nodes.length = 0;
375
- parents.length = 0;
376
- parent = undefined;
377
- return -1;
378
- }
379
- var e, i, j, k, l;
380
- if (parent === element.parentElement) {
381
- i = set;
382
- j = idx;
383
- l = len;
384
- }
385
- else {
386
- l = parents.length;
387
- parent = element.parentElement;
388
- for (i = -1, j = 0, k = l - 1; l > j; ++j, --k) {
389
- if (parents[j] === parent) {
390
- i = j;
391
- break;
392
- }
393
- if (parents[k] === parent) {
394
- i = k;
395
- break;
396
- }
397
- }
398
- if (i < 0) {
399
- parents[i = l] = parent;
400
- l = 0;
401
- nodes[i] = Array();
402
- e = parent && parent.firstElementChild || element;
403
- while (e) {
404
- nodes[i][l] = e;
405
- if (e === element)
406
- j = l;
407
- e = e.nextElementSibling;
408
- ++l;
409
- }
410
- set = i;
411
- idx = 0;
412
- len = l;
413
- if (l < 2)
414
- return l;
415
- }
416
- else {
417
- l = nodes[i].length;
418
- set = i;
419
- }
420
- }
421
- if (element !== nodes[i][j] && element !== nodes[i][j = 0]) {
422
- for (j = 0, e = nodes[i], k = l - 1; l > j; ++j, --k) {
423
- if (e[j] === element) {
424
- break;
425
- }
426
- if (e[k] === element) {
427
- j = k;
428
- break;
429
- }
430
- }
431
- }
432
- idx = j + 1;
433
- len = l;
434
- return dir ? l - j : idx;
435
- };
436
- })(),
437
- // fast resolver for the :nth-of-type() and :nth-last-of-type() pseudo-classes
438
- nthOfType = (function () {
439
- var idx = 0, len = 0, set = 0, parent = undefined, parents = Array(), nodes = Array();
440
- return function (element, dir) {
441
- // ensure caches are emptied after each run, invoking with dir = 2
442
- if (dir == 2) {
443
- idx = 0;
444
- len = 0;
445
- set = 0;
446
- nodes.length = 0;
447
- parents.length = 0;
448
- parent = undefined;
449
- return -1;
450
- }
451
- var e, i, j, k, l, name = element.localName;
452
- if (nodes[set] && nodes[set][name] && parent === element.parentElement) {
453
- i = set;
454
- j = idx;
455
- l = len;
456
- }
457
- else {
458
- l = parents.length;
459
- parent = element.parentElement;
460
- for (i = -1, j = 0, k = l - 1; l > j; ++j, --k) {
461
- if (parents[j] === parent) {
462
- i = j;
463
- break;
464
- }
465
- if (parents[k] === parent) {
466
- i = k;
467
- break;
468
- }
469
- }
470
- if (i < 0 || !nodes[i][name]) {
471
- parents[i = l] = parent;
472
- nodes[i] || (nodes[i] = Object());
473
- l = 0;
474
- nodes[i][name] = Array();
475
- e = parent && parent.firstElementChild || element;
476
- while (e) {
477
- if (e === element)
478
- j = l;
479
- if (e.localName == name) {
480
- nodes[i][name][l] = e;
481
- ++l;
482
- }
483
- e = e.nextElementSibling;
484
- }
485
- set = i;
486
- idx = j;
487
- len = l;
488
- if (l < 2)
489
- return l;
490
- }
491
- else {
492
- l = nodes[i][name].length;
493
- set = i;
494
- }
495
- }
496
- if (element !== nodes[i][name][j] && element !== nodes[i][name][j = 0]) {
497
- for (j = 0, e = nodes[i][name], k = l - 1; l > j; ++j, --k) {
498
- if (e[j] === element) {
499
- break;
500
- }
501
- if (e[k] === element) {
502
- j = k;
503
- break;
504
- }
505
- }
506
- }
507
- idx = j + 1;
508
- len = l;
509
- return dir ? l - j : idx;
510
- };
511
- })(),
512
- // check if the document type is HTML
513
- isHTML = function (node) {
514
- var doc = node.ownerDocument || node;
515
- return doc.nodeType == 9 &&
516
- // contentType not in IE <= 11
517
- 'contentType' in doc ?
518
- doc.contentType.indexOf('/html') > 0 :
519
- doc.createElement('DiV').localName == 'div';
520
- },
521
- // configure the engine to use special handling
522
- configure = function (option, clear) {
523
- if (typeof option == 'string') {
524
- return !!Config[option];
525
- }
526
- if (typeof option != 'object') {
527
- return Config;
528
- }
529
- for (var i in option) {
530
- Config[i] = !!option[i];
531
- }
532
- // clear lambda cache
533
- if (clear) {
534
- matchResolvers = {};
535
- selectResolvers = {};
536
- }
537
- setIdentifierSyntax();
538
- return true;
539
- },
540
- // centralized error and exceptions handling
541
- emit = function (message, proto) {
542
- var err;
543
- if (Config.VERBOSITY) {
544
- if (proto) {
545
- err = new proto(message);
546
- }
547
- else {
548
- err = new global.DOMException(message, 'SyntaxError');
549
- }
550
- throw err;
551
- }
552
- if (Config.LOGERRORS && console && console.log) {
553
- console.log(message);
554
- }
555
- },
556
- // execute the engine initialization code
557
- initialize = function (doc) {
558
- setIdentifierSyntax();
559
- lastContext = switchContext(doc, true);
560
- },
561
- // build validation regexps used by the engine
562
- setIdentifierSyntax = function () {
563
- //
564
- // NOTE: SPECIAL CASES IN CSS SYNTAX PARSING RULES
565
- //
566
- // The <EOF-token> https://drafts.csswg.org/css-syntax/#typedef-eof-token
567
- // allow mangled|unclosed selector syntax at the end of selectors strings
568
- //
569
- // Literal equivalent hex representations of the characters: " ' ` ] )
570
- //
571
- // \\x22 = " - double quotes \\x5b = [ - open square bracket
572
- // \\x27 = ' - single quote \\x5d = ] - closed square bracket
573
- // \\x60 = ` - back tick \\x28 = ( - open round parens
574
- // \\x5c = \ - back slash \\x29 = ) - closed round parens
575
- //
576
- // using hex format prevents false matches of opened/closed instances
577
- // pairs, coloring breakage and other editors highlightning problems.
578
- //
579
- var identifier =
580
- // doesn't start with a digit
581
- '(?=[^0-9])' +
582
- // can start with double dash
583
- '(?:-{2}' +
584
- // may include ascii chars
585
- '|[a-zA-Z0-9-_]' +
586
- // non-ascii chars
587
- '|[^\\x00-\\x9f]' +
588
- // escaped chars
589
- '|\\\\[^\\r\\n\\f0-9a-fA-F]' +
590
- // unicode chars
591
- '|\\\\[0-9a-fA-F]{1,6}(?:\\r\\n|\\s)?' +
592
- // any escaped chars
593
- '|\\\\.' +
594
- ')+', pseudonames = '[-\\w]+', pseudoparms = '(?:[-+]?\\d*)(?:n\\s?[-+]?\\s?\\d*)', doublequote = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*(?:"|$)', singlequote = "'[^'\\\\]*(?:\\\\.[^'\\\\]*)*(?:'|$)", attrparser = identifier + '|' + doublequote + '|' + singlequote, attrvalues = '([\\x22\\x27]?)((?!\\3)*|(?:\\\\?.)*?)(?:\\3|$)', attributes = '\\[' +
595
- // attribute presence
596
- '(?:\\*\\|)?' +
597
- WSP + '?' +
598
- '(' + identifier + '(?::' + identifier + ')?)' +
599
- WSP + '?' +
600
- '(?:' +
601
- '(' + CFG.operators + ')' + WSP + '?' +
602
- '(?:' + attrparser + ')' +
603
- ')?' +
604
- // attribute case sensitivity
605
- WSP + '?' + '(i)?' + WSP + '?' +
606
- '(?:\\]|$)', attrmatcher = attributes.replace(attrparser, attrvalues), pseudoclass = '(?:\\x28' + WSP + '*' +
607
- '(?:' + pseudoparms + '?)?|' +
608
- // universal * &
609
- // namespace *|*
610
- '(?:\\*|\\|)|' +
611
- '(?:' +
612
- '(?::' + pseudonames +
613
- '(?:\\x28' + pseudoparms + '?(?:\\x29|$))?|' +
614
- ')|' +
615
- '(?:[.#]?' + identifier + ')|' +
616
- '(?:' + attributes + ')' +
617
- ')+|' +
618
- '(?:' + WSP + '?,' + WSP + '?)|' +
619
- '(?:' + WSP + '?)|' +
620
- '(?:\\x29|$))*', standardValidator = '(?=' + WSP + '?[^>+~(){}<>])' +
621
- '(?:' +
622
- // universal * &
623
- // namespace *|*
624
- '(?:\\*|\\|)|' +
625
- '(?:[.#]?' + identifier + ')+|' +
626
- '(?:' + attributes + ')+|' +
627
- '(?:::?' + pseudonames + pseudoclass + ')|' +
628
- '(?:' + WSP + '?' + CFG.combinators + WSP + '?)|' +
629
- '(?:' + WSP + '?,' + WSP + '?)|' +
630
- '(?:' + WSP + '?)' +
631
- ')+';
632
- // the following global RE is used to return the
633
- // deepest localName in selector strings and then
634
- // use it to retrieve all possible matching nodes
635
- // that will be filtered by compiled resolvers
636
- reOptimizer = RegExp('(?:([.:#*]?)' +
637
- '(' + identifier + ')' +
638
- '(?:' +
639
- ':[-\\w]+|' +
640
- '\\[[^\\]]+(?:\\]|$)|' +
641
- '\\x28[^\\x29]+(?:\\x29|$)' +
642
- ')*)$');
643
- // global
644
- reValidator = RegExp(standardValidator, 'g');
645
- Patterns.id = RegExp('^#(' + identifier + ')(.*)');
646
- Patterns.tagName = RegExp('^(' + identifier + ')(.*)');
647
- Patterns.className = RegExp('^\\.(' + identifier + ')(.*)');
648
- Patterns.attribute = RegExp('^(?:' + attrmatcher + ')(.*)');
649
- }, 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 = [],
650
- // compile groups or single selector strings into
651
- // executable functions for matching or selecting
652
- compile = function (selector, mode, callback) {
653
- var factory, token, head = '', loop = '', macro = '', source = '', vars = '';
654
- // 'mode' can be boolean or null
655
- // true = select / false = match
656
- // null to use collection.item()
657
- switch (mode) {
658
- case true:
659
- if (selectLambdas[selector]) {
660
- return selectLambdas[selector];
661
- }
662
- macro = S_BODY + (callback ? S_TEST : '') + S_TAIL;
663
- head = S_HEAD;
664
- loop = S_LOOP;
665
- break;
666
- case false:
667
- if (matchLambdas[selector]) {
668
- return matchLambdas[selector];
669
- }
670
- macro = M_BODY + (callback ? M_TEST : '') + M_TAIL;
671
- head = M_HEAD;
672
- loop = M_LOOP;
673
- break;
674
- case null:
675
- if (selectLambdas[selector]) {
676
- return selectLambdas[selector];
677
- }
678
- macro = N_BODY + (callback ? N_TEST : '') + S_TAIL;
679
- head = S_HEAD;
680
- loop = N_LOOP;
681
- break;
682
- default:
683
- break;
684
- }
685
- source = compileSelector(selector, macro, mode, callback, false);
686
- loop += mode || mode === null ? '{' + source + '}' : source;
687
- if (mode || mode === null && selector.includes(':nth')) {
688
- loop += reNthElem.test(selector) ? 's.nthElement(null, 2);' : '';
689
- loop += reNthType.test(selector) ? 's.nthOfType(null, 2);' : '';
690
- }
691
- if (S_VARS[0] || M_VARS[0]) {
692
- vars = ',' + (S_VARS.join(',') || M_VARS.join(','));
693
- S_VARS.length = 0;
694
- M_VARS.length = 0;
695
- }
696
- factory = Function('s', F_INIT + '{' + head + vars + ';' + loop + 'return r;}')(Snapshot);
697
- return mode || mode === null ? (selectLambdas[selector] = factory) : (matchLambdas[selector] = factory);
698
- },
699
- // build conditional code to check components of selector strings
700
- compileSelector = function (expression, source, mode, callback, not) {
701
- // N is the negation pseudo-class flag
702
- // D is the default inverted negation flag
703
- var a, b, n, f, i, l, name, NS, N = not ? '!' : '', D = not ? '' : '!', compat, expr, match, result, status, symbol, test, type, selector = expression, selector_string, vars;
704
- // original 'select' or 'match' selector string before normalization
705
- selector_string = mode ? lastSelected : lastMatched;
706
- // isolate selector combinators/components and normalize whitespace
707
- selector = selector.replace(STD.combinator, '$1'); //.replace(STD.whitespace, ' ');
708
- while (selector) {
709
- // get namespace prefix if present or get first char of selector
710
- symbol = STD.apimethods.test(selector) ? '|' : selector[0];
711
- switch (symbol) {
712
- // universal resolver
713
- case '*':
714
- match = selector.match(Patterns.universal);
715
- if (N == '!') {
716
- source = 'if(' + N + 'true' +
717
- '){' + source + '}';
718
- }
719
- break;
720
- // id resolver
721
- case '#':
722
- match = selector.match(Patterns.id);
723
- source = 'if(' + N + '(/^' + match[1] + '$/.test(e.getAttribute("id"))' +
724
- ')){' + source + '}';
725
- break;
726
- // class name resolver
727
- case '.':
728
- match = selector.match(Patterns.className);
729
- compat = (QUIRKS_MODE ? 'i' : '') + '.test(e.getAttribute("class"))';
730
- source = 'if(' + N + '(/(^|\\s)' + match[1] + '(\\s|$)/' + compat +
731
- ')){' + source + '}';
732
- break;
733
- // tag name resolver
734
- case (/[_a-z]/i.test(symbol) ? symbol : undefined):
735
- match = selector.match(Patterns.tagName);
736
- source = 'if(' + N + '(e.localName' +
737
- (Config.MIXEDCASE || hasMixedCaseTagNames(doc) ?
738
- '=="' + match[1].toLowerCase() + '"' :
739
- '=="' + match[1].toUpperCase() + '"') +
740
- ')){' + source + '}';
741
- break;
742
- // namespace resolver
743
- case '|':
744
- match = selector.match(Patterns.namespace);
745
- if (match[1] == '*') {
746
- source = 'if(' + N + 'true){' + source + '}';
747
- }
748
- else if (!match[1]) {
749
- source = 'if(' + N + '(!e.namespaceURI)){' + source + '}';
750
- }
751
- else if (typeof match[1] == 'string' && root.prefix == match[1]) {
752
- source = 'if(' + N + '(e.namespaceURI=="' + NAMESPACE + '")){' + source + '}';
753
- }
754
- else {
755
- emit('\'' + selector_string + '\'' + qsInvalid);
756
- }
757
- break;
758
- // attributes resolver
759
- case '[':
760
- match = selector.match(Patterns.attribute);
761
- NS = match[0].match(STD.namespaces);
762
- name = match[1];
763
- expr = name.split(':');
764
- expr = expr.length == 2 ? expr[1] : expr[0];
765
- if (match[2] && !(test = Operators[match[2]])) {
766
- emit('\'' + selector_string + '\'' + qsInvalid);
767
- return '';
768
- }
769
- if (match[4] === '') {
770
- test = match[2] == '~=' ?
771
- { p1: '^\\s', p2: '+$', p3: 'true' } :
772
- match[2] in ATTR_STD_OPS && match[2] != '~=' ?
773
- { p1: '^', p2: '$', p3: 'true' } : test;
774
- }
775
- else if (match[2] == '~=' && match[4].includes(' ')) {
776
- // whitespace separated list but value contains space
777
- source = 'if(' + N + 'false){' + source + '}';
778
- break;
779
- }
780
- else if (match[4]) {
781
- match[4] = convertEscapes(match[4]).replace(REX.RegExpChar, '\\$&');
782
- }
783
- type = match[5] == 'i' || (HTML_DOCUMENT && HTML_TABLE[expr.toLowerCase()]) ? 'i' : '';
784
- source = 'if(' + N + '(' +
785
- (!match[2] ? (NS ? 's.hasAttributeNS(e,"' + name + '")' : 'e.hasAttribute&&e.hasAttribute("' + name + '")') :
786
- !match[4] && ATTR_STD_OPS[match[2]] && match[2] != '~=' ? 'e.getAttribute&&e.getAttribute("' + name + '")==""' :
787
- '(/' + test.p1 + match[4] + test.p2 + '/' + type + ').test(e.getAttribute&&e.getAttribute("' + name + '"))==' + test.p3) +
788
- ')){' + source + '}';
789
- break;
790
- // *** General sibling combinator
791
- // E ~ F (F relative sibling of E)
792
- case '~':
793
- match = selector.match(Patterns.relative);
794
- source = 'n=e;while((e=e.previousElementSibling)){' + source + '}e=n;';
795
- break;
796
- // *** Adjacent sibling combinator
797
- // E + F (F adiacent sibling of E)
798
- case '+':
799
- match = selector.match(Patterns.adjacent);
800
- source = 'n=e;if((e=e.previousElementSibling)){' + source + '}e=n;';
801
- break;
802
- // *** Descendant combinator
803
- // E F (E ancestor of F)
804
- case '\x09':
805
- case '\x20':
806
- match = selector.match(Patterns.ancestor);
807
- source = 'n=e;while((e=e.parentElement)){' + source + '}e=n;';
808
- break;
809
- // *** Child combinator
810
- // E > F (F children of E)
811
- case '>':
812
- match = selector.match(Patterns.children);
813
- source = 'n=e;if((e=e.parentElement)){' + source + '}e=n;';
814
- break;
815
- // *** user supplied combinators extensions
816
- case (symbol in Combinators ? symbol : undefined):
817
- // for other registered combinators extensions
818
- match[match.length - 1] = '*';
819
- source = Combinators[symbol](match) + source;
820
- break;
821
- // *** tree-structural pseudo-classes
822
- // :root, :empty, :first-child, :last-child, :only-child, :first-of-type, :last-of-type, :only-of-type
823
- case ':':
824
- if ((match = selector.match(Patterns.structural))) {
825
- match[1] = match[1].toLowerCase();
826
- switch (match[1]) {
827
- case 'root':
828
- // there can only be one :root element, so exit the loop once found
829
- source = 'if(' + N + '(e===s.root)){' + source + (mode ? 'break main;' : '') + '}';
830
- break;
831
- case 'empty':
832
- // matches elements that don't contain elements or text nodes
833
- source = 'n=e.firstChild;while(n&&!(/1|3/).test(n.nodeType)){n=n.nextSibling}if(' + D + 'n){' + source + '}';
834
- break;
835
- // *** child-indexed pseudo-classes
836
- // :first-child, :last-child, :only-child
837
- case 'only-child':
838
- source = 'if(' + N + '(!e.nextElementSibling&&!e.previousElementSibling)){' + source + '}';
839
- break;
840
- case 'last-child':
841
- source = 'if(' + N + '(!e.nextElementSibling)){' + source + '}';
842
- break;
843
- case 'first-child':
844
- source = 'if(' + N + '(!e.previousElementSibling)){' + source + '}';
845
- break;
846
- // *** typed child-indexed pseudo-classes
847
- // :only-of-type, :last-of-type, :first-of-type
848
- case 'only-of-type':
849
- source = 'o=e.localName;' +
850
- 'n=e;while((n=n.nextElementSibling)&&n.localName!=o);if(!n){' +
851
- 'n=e;while((n=n.previousElementSibling)&&n.localName!=o);}if(' + D + 'n){' + source + '}';
852
- break;
853
- case 'last-of-type':
854
- source = 'n=e;o=e.localName;while((n=n.nextElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}';
855
- break;
856
- case 'first-of-type':
857
- source = 'n=e;o=e.localName;while((n=n.previousElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}';
858
- break;
859
- default:
860
- emit('\'' + selector_string + '\'' + qsInvalid);
861
- break;
862
- }
863
- }
864
- // *** child-indexed & typed child-indexed pseudo-classes
865
- // :nth-child, :nth-of-type, :nth-last-child, :nth-last-of-type
866
- else if ((match = selector.match(Patterns.treestruct))) {
867
- match[1] = match[1].toLowerCase();
868
- switch (match[1]) {
869
- case 'nth-child':
870
- case 'nth-of-type':
871
- case 'nth-last-child':
872
- case 'nth-last-of-type':
873
- expr = /-of-type/i.test(match[1]);
874
- if (match[1] && match[2]) {
875
- type = /last/i.test(match[1]);
876
- if (match[2] == 'n') {
877
- source = 'if(' + N + 'true){' + source + '}';
878
- break;
879
- }
880
- else if (match[2] == '1') {
881
- test = type ? 'next' : 'previous';
882
- source = expr ? 'n=e;o=e.localName;' +
883
- 'while((n=n.' + test + 'ElementSibling)&&n.localName!=o);if(' + D + 'n){' + source + '}' :
884
- 'if(' + N + '!e.' + test + 'ElementSibling){' + source + '}';
885
- break;
886
- }
887
- else if (match[2] == 'even' || match[2] == '2n0' || match[2] == '2n+0' || match[2] == '2n') {
888
- test = 'n%2==0';
889
- }
890
- else if (match[2] == 'odd' || match[2] == '2n1' || match[2] == '2n+1') {
891
- test = 'n%2==1';
892
- }
893
- else {
894
- f = /n/i.test(match[2]);
895
- n = match[2].split('n');
896
- a = parseInt(n[0], 10) || 0;
897
- b = parseInt(n[1], 10) || 0;
898
- if (n[0] == '-') {
899
- a = -1;
900
- }
901
- if (n[0] == '+') {
902
- a = +1;
903
- }
904
- test = (b ? '(n' + (b > 0 ? '-' : '+') + Math.abs(b) + ')' : 'n') + '%' + a + '==0';
905
- test =
906
- a >= +1 ? (f ? 'n>' + (b - 1) + (Math.abs(a) != 1 ? '&&' + test : '') : 'n==' + a) :
907
- a <= -1 ? (f ? 'n<' + (b + 1) + (Math.abs(a) != 1 ? '&&' + test : '') : 'n==' + a) :
908
- a === 0 ? (n[0] ? 'n==' + b : 'n>' + (b - 1)) : 'false';
909
- }
910
- expr = expr ? 'OfType' : 'Element';
911
- type = type ? 'true' : 'false';
912
- source = 'n=s.nth' + expr + '(e,' + type + ');if(' + N + '(' + test + ')){' + source + '}';
913
- }
914
- else {
915
- emit('\'' + selector_string + '\'' + qsInvalid);
916
- }
917
- break;
918
- default:
919
- emit('\'' + selector_string + '\'' + qsInvalid);
920
- break;
921
- }
922
- }
923
- // *** logical combination pseudo-classes
924
- // :is( s1, [ s2, ... ]), :not( s1, [ s2, ... ])
925
- else if ((match = selector.match(Patterns.logicalsel))) {
926
- match[1] = match[1].toLowerCase();
927
- switch (match[1]) {
928
- case 'is':
929
- case 'where':
930
- case 'matches':
931
- expr = match[2].replace(REX.CommaGroup, ',').replace(REX.TrimSpaces, '');
932
- source = 'if(s.match("' + expr.replace(/\x22/g, '\\"') + '",e)){' + source + '}';
933
- break;
934
- case 'not':
935
- expr = match[2].replace(REX.CommaGroup, ',').replace(REX.TrimSpaces, '');
936
- source = 'if(!s.match("' + expr.replace(/\x22/g, '\\"') + '",e)){' + source + '}';
937
- break;
938
- default:
939
- emit('\'' + selector_string + '\'' + qsInvalid);
940
- break;
941
- }
942
- }
943
- // *** linguistic pseudo-classes
944
- // :dir( ltr / rtl ), :lang( en )
945
- else if ((match = selector.match(Patterns.linguistic))) {
946
- match[1] = match[1].toLowerCase();
947
- switch (match[1]) {
948
- case 'dir':
949
- source = 'var p;if(' + N + '(' +
950
- '(/' + match[2] + '/i.test(e.dir))||(p=s.ancestor("[dir]", e))&&' +
951
- '(/' + match[2] + '/i.test(p.dir))||(e.dir==""||e.dir=="auto")&&' +
952
- '(' + (match[2] == 'ltr' ? '!' : '') + RTL + '.test(e.textContent)))' +
953
- '){' + source + '};';
954
- break;
955
- case 'lang':
956
- expr = '(?:^|-)' + match[2] + '(?:-|$)';
957
- source = 'var p;if(' + N + '(' +
958
- '(e.isConnected&&(e.lang==""&&(p=s.ancestor("[lang]",e)))&&' +
959
- '(p.lang=="' + match[2] + '")||/' + expr + '/i.test(e.lang)))' +
960
- '){' + source + '};';
961
- break;
962
- default:
963
- emit('\'' + selector_string + '\'' + qsInvalid);
964
- break;
965
- }
966
- }
967
- // *** location pseudo-classes
968
- // :any-link, :link, :visited, :target
969
- else if ((match = selector.match(Patterns.locationpc))) {
970
- match[1] = match[1].toLowerCase();
971
- switch (match[1]) {
972
- case 'any-link':
973
- source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href")||e.visited)){' + source + '}';
974
- break;
975
- case 'link':
976
- source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href"))){' + source + '}';
977
- break;
978
- case 'visited':
979
- source = 'if(' + N + '(/^a|area$/i.test(e.localName)&&e.hasAttribute("href")&&e.visited)){' + source + '}';
980
- break;
981
- case 'target':
982
- source = 'if(' + N + '((s.doc.compareDocumentPosition(e)&16)&&s.doc.location.hash&&e.id==s.doc.location.hash.slice(1))){' + source + '}';
983
- break;
984
- default:
985
- emit('\'' + selector_string + '\'' + qsInvalid);
986
- break;
987
- }
988
- }
989
- // *** user actions pseudo-classes
990
- // :hover, :active, :focus
991
- else if ((match = selector.match(Patterns.useraction))) {
992
- match[1] = match[1].toLowerCase();
993
- switch (match[1]) {
994
- case 'hover':
995
- source = 'hasFocus' in doc && doc.hasFocus() ?
996
- 'if(' + N + '(e===s.doc.hoverElement)){' + source + '}' :
997
- 'if(' + D + 'true){' + source + '}';
998
- break;
999
- case 'active':
1000
- source = 'hasFocus' in doc && doc.hasFocus() ?
1001
- 'if(' + N + '(e===s.doc.activeElement)){' + source + '}' :
1002
- 'if(' + D + 'true){' + source + '}';
1003
- break;
1004
- case 'focus':
1005
- source = 'hasFocus' in doc ?
1006
- 'if(' + N + '(e===s.doc.activeElement&&s.doc.hasFocus()&&(e.type||e.href||typeof e.tabIndex=="number"))){' + source + '}' :
1007
- 'if(' + N + '(e===s.doc.activeElement&&(e.type||e.href))){' + source + '}';
1008
- break;
1009
- case 'focus-within':
1010
- source = 'hasFocus' in doc ?
1011
- 'n=s.doc.activeElement;while(e){if(e===n||e.parentNode===n)break;}' +
1012
- 'if(' + N + '(e===n&&s.doc.hasFocus()&&(e.type||e.href||typeof e.tabIndex=="number"))){' + source + '}' : source;
1013
- break;
1014
- default:
1015
- emit('\'' + selector_string + '\'' + qsInvalid);
1016
- break;
1017
- }
1018
- }
1019
- // *** user interface and form pseudo-classes
1020
- // :enabled, :disabled, :read-only, :read-write, :placeholder-shown, :default
1021
- else if ((match = selector.match(Patterns.inputstate))) {
1022
- match[1] = match[1].toLowerCase();
1023
- switch (match[1]) {
1024
- case 'enabled':
1025
- source = 'if(' + N + '(("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e &&e.disabled===false' +
1026
- ')){' + source + '}';
1027
- break;
1028
- case 'disabled':
1029
- // https://www.w3.org/TR/html5/forms.html#enabling-and-disabling-form-controls:-the-disabled-attribute
1030
- source = 'if(' + N + '(("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e&&' +
1031
- '(e.disabled===true||(n=s.ancestor("fieldset",e))&&(n=s.first("legend",n))&&!n.contains(e))' +
1032
- ')){' + source + '}';
1033
- break;
1034
- case 'read-only':
1035
- source =
1036
- 'if(' + N + '(' +
1037
- '(/^textarea$/i.test(e.localName)&&(e.readOnly||e.disabled))||' +
1038
- '("|password|text|".includes("|"+e.type+"|")&&e.readOnly)' +
1039
- ')){' + source + '}';
1040
- break;
1041
- case 'read-write':
1042
- source =
1043
- 'if(' + N + '(' +
1044
- '((/^textarea$/i.test(e.localName)&&!e.readOnly&&!e.disabled)||' +
1045
- '("|password|text|".includes("|"+e.type+"|")&&!e.readOnly&&!e.disabled))||' +
1046
- '(e.hasAttribute("contenteditable")||(s.doc.designMode=="on"))' +
1047
- ')){' + source + '}';
1048
- break;
1049
- case 'placeholder-shown':
1050
- source =
1051
- 'if(' + N + '(' +
1052
- '(/^input|textarea$/i.test(e.localName))&&e.hasAttribute("placeholder")&&' +
1053
- '("|textarea|password|number|search|email|text|tel|url|".includes("|"+e.type+"|"))&&' +
1054
- '(!s.match(":focus",e))' +
1055
- ')){' + source + '}';
1056
- break;
1057
- case 'default':
1058
- source =
1059
- 'if(' + N + '("form" in e && e.form)){' +
1060
- 'var x=0;n=[];' +
1061
- 'if(e.type=="image")n=e.form.getElementsByTagName("input");' +
1062
- 'if(e.type=="submit")n=e.form.elements;' +
1063
- 'while(n[x]&&e!==n[x]){' +
1064
- 'if(n[x].type=="image")break;' +
1065
- 'if(n[x].type=="submit")break;' +
1066
- 'x++;' +
1067
- '}' +
1068
- '}' +
1069
- 'if(' + N + '(e.form&&(e===n[x]&&"|image|submit|".includes("|"+e.type+"|"))||' +
1070
- '((/^option$/i.test(e.localName))&&e.defaultSelected)||' +
1071
- '(("|radio|checkbox|".includes("|"+e.type+"|"))&&e.defaultChecked)' +
1072
- ')){' + source + '}';
1073
- break;
1074
- default:
1075
- emit('\'' + selector_string + '\'' + qsInvalid);
1076
- break;
1077
- }
1078
- }
1079
- // *** input pseudo-classes (for form validation)
1080
- // :checked, :indeterminate, :valid, :invalid, :in-range, :out-of-range, :required, :optional
1081
- else if ((match = selector.match(Patterns.inputvalue))) {
1082
- match[1] = match[1].toLowerCase();
1083
- switch (match[1]) {
1084
- case 'checked':
1085
- source = 'if(' + N + '(/^input$/i.test(e.localName)&&' +
1086
- '("|radio|checkbox|".includes("|"+e.type+"|")&&e.checked)||' +
1087
- '(/^option$/i.test(e.localName)&&(e.selected||e.checked))' +
1088
- ')){' + source + '}';
1089
- break;
1090
- case 'indeterminate':
1091
- source =
1092
- 'if(' + N + '(/^progress$/i.test(e.localName)&&!e.hasAttribute("value"))||' +
1093
- '(/^input$/i.test(e.localName)&&("checkbox"==e.type&&e.indeterminate)||' +
1094
- '("radio"==e.type&&e.name&&!s.first("input[name="+e.name+"]:checked",e.form))' +
1095
- ')){' + source + '}';
1096
- break;
1097
- case 'required':
1098
- source =
1099
- 'if(' + N +
1100
- '(/^input|select|textarea$/i.test(e.localName)&&e.required)' +
1101
- '){' + source + '}';
1102
- break;
1103
- case 'optional':
1104
- source =
1105
- 'if(' + N +
1106
- '(/^input|select|textarea$/i.test(e.localName)&&!e.required)' +
1107
- '){' + source + '}';
1108
- break;
1109
- case 'invalid':
1110
- source =
1111
- 'if(' + N + '((' +
1112
- '(/^form$/i.test(e.localName)&&!e.noValidate)||' +
1113
- '(e.willValidate&&!e.formNoValidate))&&!e.checkValidity())||' +
1114
- '(/^fieldset$/i.test(e.localName)&&s.first(":invalid",e))' +
1115
- '){' + source + '}';
1116
- break;
1117
- case 'valid':
1118
- source =
1119
- 'if(' + N + '((' +
1120
- '(/^form$/i.test(e.localName)&&!e.noValidate)||' +
1121
- '(e.willValidate&&!e.formNoValidate))&&e.checkValidity())||' +
1122
- '(/^fieldset$/i.test(e.localName)&&s.first(":valid",e))' +
1123
- '){' + source + '}';
1124
- break;
1125
- case 'in-range':
1126
- source =
1127
- 'if(' + N +
1128
- '(/^input$/i.test(e.localName))&&' +
1129
- '(e.willValidate&&!e.formNoValidate)&&' +
1130
- '(!e.validity.rangeUnderflow&&!e.validity.rangeOverflow)&&' +
1131
- '("|date|datetime-local|month|number|range|time|week|".includes("|"+e.type+"|"))&&' +
1132
- '("range"==e.type||e.getAttribute("min")||e.getAttribute("max"))' +
1133
- '){' + source + '}';
1134
- break;
1135
- case 'out-of-range':
1136
- source =
1137
- 'if(' + N +
1138
- '(/^input$/i.test(e.localName))&&' +
1139
- '(e.willValidate&&!e.formNoValidate)&&' +
1140
- '(e.validity.rangeUnderflow||e.validity.rangeOverflow)&&' +
1141
- '("|date|datetime-local|month|number|range|time|week|".includes("|"+e.type+"|"))&&' +
1142
- '("range"==e.type||e.getAttribute("min")||e.getAttribute("max"))' +
1143
- '){' + source + '}';
1144
- break;
1145
- default:
1146
- emit('\'' + selector_string + '\'' + qsInvalid);
1147
- break;
1148
- }
1149
- }
1150
- // allow pseudo-elements starting with single colon (:)
1151
- // :after, :before, :first-letter, :first-line
1152
- // assert: e.type is in double-colon format, like ::after
1153
- else if ((match = selector.match(Patterns.pseudo_sng))) {
1154
- source = 'if(e.element&&e.type.toLowerCase()=="' +
1155
- ':' + match[0].toLowerCase() + '"){e=e.element;' + source + '}';
1156
- }
1157
- // allow pseudo-elements starting with double colon (::)
1158
- // ::after, ::before, ::marker, ::placeholder, ::inactive-selection, ::selection, ::-webkit-<foo-bar>
1159
- // assert: e.type is in double-colon format, like ::after
1160
- else if ((match = selector.match(Patterns.pseudo_dbl))) {
1161
- source = 'if(e.element&&e.type.toLowerCase()=="' +
1162
- match[0].toLowerCase() + '"){e=e.element;' + source + '}';
1163
- }
1164
- else {
1165
- // reset
1166
- expr = false;
1167
- status = false;
1168
- // process registered selector extensions
1169
- for (expr in Selectors) {
1170
- if ((match = selector.match(Selectors[expr].Expression))) {
1171
- result = Selectors[expr].Callback(match, source, mode, callback);
1172
- if ('match' in result) {
1173
- match = result.match;
1174
- }
1175
- vars = result.modvar;
1176
- if (mode) {
1177
- // add extra select() vars
1178
- vars && S_VARS.indexOf(vars) < 0 && (S_VARS[S_VARS.length] = vars);
1179
- }
1180
- else {
1181
- // add extra match() vars
1182
- vars && M_VARS.indexOf(vars) < 0 && (M_VARS[M_VARS.length] = vars);
1183
- }
1184
- // extension source code
1185
- source = result.source;
1186
- // extension status code
1187
- status = result.status;
1188
- // break on status error
1189
- if (status) {
1190
- break;
1191
- }
1192
- }
1193
- }
1194
- if (!status) {
1195
- emit('unknown pseudo-class selector \'' + selector + '\'');
1196
- return '';
1197
- }
1198
- if (!expr) {
1199
- emit('unknown token in selector \'' + selector + '\'');
1200
- return '';
1201
- }
1202
- }
1203
- break;
1204
- default:
1205
- emit('\'' + selector_string + '\'' + qsInvalid);
1206
- break;
1207
- }
1208
- // end of switch symbol
1209
- if (!match) {
1210
- emit('\'' + selector_string + '\'' + qsInvalid);
1211
- return '';
1212
- }
1213
- // pop last component
1214
- selector = match.pop();
1215
- }
1216
- // end of while selector
1217
- return source;
1218
- },
1219
- // replace ':scope' pseudo-class with element references
1220
- makeref = function (selectors, element) {
1221
- return selectors.replace(/:scope/ig, element.localName +
1222
- (element.id ? '#' + element.id : '') +
1223
- (element.className ? '.' + element.classList[0] : ''));
1224
- },
1225
- // equivalent of w3c 'closest' method
1226
- ancestor = function _closest(selectors, element, callback) {
1227
- if ((/:scope/i).test(selectors)) {
1228
- selectors = makeref(selectors, element);
1229
- }
1230
- while (element) {
1231
- if (match(selectors, element, callback))
1232
- break;
1233
- element = element.parentElement;
1234
- }
1235
- return element;
1236
- }, match_assert = function (f, element, callback) {
1237
- for (var i = 0, l = f.length, r = false; l > i; ++i)
1238
- f[i](element, callback, null, false) && (r = true);
1239
- return r;
1240
- }, match_collect = function (selectors, callback) {
1241
- for (var i = 0, l = selectors.length, f = []; l > i; ++i)
1242
- f[i] = compile(selectors[i], false, callback);
1243
- return { factory: f };
1244
- },
1245
- // equivalent of w3c 'matches' method
1246
- match = function _matches(selectors, element, callback) {
1247
- var expressions, parsed;
1248
- if (element && matchResolvers[selectors]) {
1249
- return match_assert(matchResolvers[selectors].factory, element, callback);
1250
- }
1251
- lastMatched = selectors;
1252
- // arguments validation
1253
- if (arguments.length === 0) {
1254
- emit(qsNotArgs, TypeError);
1255
- return Config.VERBOSITY ? undefined : false;
1256
- }
1257
- else if (arguments[0] === '') {
1258
- emit('\'\'' + qsInvalid);
1259
- return Config.VERBOSITY ? undefined : false;
1260
- }
1261
- // input NULL or UNDEFINED
1262
- if (typeof selectors != 'string') {
1263
- selectors = '' + selectors;
1264
- }
1265
- if ((/:scope/i).test(selectors)) {
1266
- selectors = makeref(selectors, element);
1267
- }
1268
- // normalize input string
1269
- parsed = selectors.
1270
- replace(/\x00|\\$/g, '\ufffd').
1271
- replace(REX.CombineWSP, '\x20').
1272
- replace(REX.PseudosWSP, '$1').
1273
- replace(REX.TabCharWSP, '\t').
1274
- replace(REX.CommaGroup, ',').
1275
- replace(REX.TrimSpaces, '');
1276
- // parse, validate and split possible compound selectors
1277
- if ((expressions = parsed.match(reValidator)) && expressions.join('') == parsed) {
1278
- expressions = parsed.match(REX.SplitGroup);
1279
- if (parsed[parsed.length - 1] == ',') {
1280
- emit(qsInvalid);
1281
- return Config.VERBOSITY ? undefined : false;
1282
- }
1283
- }
1284
- else {
1285
- emit('\'' + selectors + '\'' + qsInvalid);
1286
- return Config.VERBOSITY ? undefined : false;
1287
- }
1288
- matchResolvers[selectors] = match_collect(expressions, callback);
1289
- return match_assert(matchResolvers[selectors].factory, element, callback);
1290
- },
1291
- // equivalent of w3c 'querySelector' method
1292
- first = function _querySelector(selectors, context, callback) {
1293
- if (arguments.length === 0) {
1294
- emit(qsNotArgs, TypeError);
1295
- }
1296
- return select(selectors, context, typeof callback == 'function' ?
1297
- function firstMatch(element) {
1298
- callback(element);
1299
- return false;
1300
- } :
1301
- function firstMatch() {
1302
- return false;
1303
- })[0] || null;
1304
- },
1305
- // equivalent of w3c 'querySelectorAll' method
1306
- select = function _querySelectorAll(selectors, context, callback) {
1307
- var expressions, nodes, parsed, resolver;
1308
- context || (context = doc);
1309
- if (selectors) {
1310
- if ((resolver = selectResolvers[selectors])) {
1311
- if (resolver.context === context && resolver.callback === callback) {
1312
- var f = resolver.factory, h = resolver.htmlset, n = resolver.nodeset, nodes = [];
1313
- if (n.length > 1) {
1314
- for (var i = 0, l = n.length, list; l > i; ++i) {
1315
- list = compat[n[i][0]](context, n[i].slice(1))();
1316
- if (f[i] !== null) {
1317
- f[i](list, callback, context, nodes);
1318
- }
1319
- else {
1320
- nodes = nodes.concat(list);
1321
- }
1322
- }
1323
- if (l > 1 && nodes.length > 1) {
1324
- nodes.sort(documentOrder);
1325
- hasDupes && (nodes = unique(nodes));
1326
- }
1327
- }
1328
- else {
1329
- if (f[0]) {
1330
- nodes = f[0](h[0](), callback, context, nodes);
1331
- }
1332
- else {
1333
- nodes = h[0]();
1334
- }
1335
- }
1336
- return typeof callback == 'function' ?
1337
- concatCall(nodes, callback) : nodes;
1338
- }
1339
- }
1340
- }
1341
- lastSelected = selectors;
1342
- // arguments validation
1343
- if (arguments.length === 0) {
1344
- emit(qsNotArgs, TypeError);
1345
- return Config.VERBOSITY ? undefined : none;
1346
- }
1347
- else if (arguments[0] === '') {
1348
- emit('\'\'' + qsInvalid);
1349
- return Config.VERBOSITY ? undefined : none;
1350
- }
1351
- else if (lastContext !== context) {
1352
- lastContext = switchContext(context);
1353
- }
1354
- // input NULL or UNDEFINED
1355
- if (typeof selectors != 'string') {
1356
- selectors = '' + selectors;
1357
- }
1358
- if ((/:scope/i).test(selectors)) {
1359
- selectors = makeref(selectors, context);
1360
- }
1361
- // normalize input string
1362
- parsed = selectors.
1363
- replace(/\x00|\\$/g, '\ufffd').
1364
- replace(REX.CombineWSP, '\x20').
1365
- replace(REX.PseudosWSP, '$1').
1366
- replace(REX.TabCharWSP, '\t').
1367
- replace(REX.CommaGroup, ',').
1368
- replace(REX.TrimSpaces, '');
1369
- // parse, validate and split possible compound selectors
1370
- if ((expressions = parsed.match(reValidator)) && expressions.join('') == parsed) {
1371
- expressions = parsed.match(REX.SplitGroup);
1372
- if (parsed[parsed.length - 1] == ',') {
1373
- emit(qsInvalid);
1374
- return Config.VERBOSITY ? undefined : false;
1375
- }
1376
- }
1377
- else {
1378
- emit('\'' + selectors + '\'' + qsInvalid);
1379
- return Config.VERBOSITY ? undefined : false;
1380
- }
1381
- // save/reuse factory and closure collection
1382
- selectResolvers[selectors] = collect(expressions, context, callback);
1383
- nodes = selectResolvers[selectors].results;
1384
- return typeof callback == 'function' ?
1385
- concatCall(nodes, callback) : nodes;
1386
- },
1387
- // optimize selectors avoiding duplicated checks
1388
- optimize = function (selector, token) {
1389
- var index = token.index, length = token[1].length + token[2].length;
1390
- return selector.slice(0, index) +
1391
- (' >+~'.indexOf(selector.charAt(index - 1)) > -1 ?
1392
- (':['.indexOf(selector.charAt(index + length + 1)) > -1 ?
1393
- '*' : '') : '') + selector.slice(index + length - (token[1] == '*' ? 1 : 0));
1394
- },
1395
- // prepare factory resolvers and closure collections
1396
- collect = function (selectors, context, callback) {
1397
- var i, l, seen = {}, token = ['', '*', '*'], optimized = selectors, factory = [], htmlset = [], nodeset = [], results = [], type;
1398
- for (i = 0, l = selectors.length; l > i; ++i) {
1399
- if (!seen[selectors[i]] && (seen[selectors[i]] = true)) {
1400
- type = selectors[i].match(reOptimizer);
1401
- if (type && type[1] != ':' && (token = type)) {
1402
- token[1] || (token[1] = '*');
1403
- optimized[i] = optimize(optimized[i], token);
1404
- }
1405
- else {
1406
- token = ['', '*', '*'];
1407
- }
1408
- }
1409
- nodeset[i] = token[1] + token[2];
1410
- htmlset[i] = compat[token[1]](context, token[2]);
1411
- factory[i] = compile(optimized[i], true, null);
1412
- factory[i] ?
1413
- factory[i](htmlset[i](), callback, context, results) :
1414
- result.concat(htmlset[i]());
1415
- }
1416
- if (l > 1) {
1417
- results.sort(documentOrder);
1418
- hasDupes && (results = unique(results));
1419
- }
1420
- return {
1421
- callback: callback,
1422
- context: context,
1423
- factory: factory,
1424
- htmlset: htmlset,
1425
- nodeset: nodeset,
1426
- results: results
1427
- };
1428
- },
1429
- // QSA placeholders to native references
1430
- _closest, _matches, _querySelector, _querySelectorAll,
1431
- // overrides QSA methods (only for browsers)
1432
- install = function (all) {
1433
- // save native QSA references
1434
- _closest = Element.prototype.closest;
1435
- _matches = Element.prototype.matches;
1436
- _querySelector = Document.prototype.querySelector;
1437
- _querySelectorAll = Document.prototype.querySelectorAll;
1438
- Element.prototype.closest =
1439
- function closest() {
1440
- var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
1441
- if (!('nodeType' in this)) {
1442
- emit('\'closest\' called on an object that does not implement interface ' + ctor + '.', TypeError);
1443
- }
1444
- return arguments.length < 1 ? ancestor.apply(this, []) :
1445
- arguments.length < 2 ? ancestor.apply(this, [arguments[0], this]) :
1446
- ancestor.apply(this, [arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined]);
1447
- };
1448
- Element.prototype.matches =
1449
- function matches() {
1450
- var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
1451
- if (!('nodeType' in this)) {
1452
- emit('\'matches\' called on an object that does not implement interface ' + ctor + '.', TypeError);
1453
- }
1454
- return arguments.length < 1 ? match.apply(this, []) :
1455
- arguments.length < 2 ? match.apply(this, [arguments[0], this]) :
1456
- match.apply(this, [arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined]);
1457
- };
1458
- Element.prototype.querySelector =
1459
- Document.prototype.querySelector =
1460
- DocumentFragment.prototype.querySelector =
1461
- function querySelector() {
1462
- var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
1463
- if (!('nodeType' in this)) {
1464
- emit('\'querySelector\' called on an object that does not implement interface ' + ctor + '.', TypeError);
1465
- }
1466
- return arguments.length < 1 ? first.apply(this, []) :
1467
- arguments.length < 2 ? first.apply(this, [arguments[0], this]) :
1468
- first.apply(this, [arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined]);
1469
- };
1470
- Element.prototype.querySelectorAll =
1471
- Document.prototype.querySelectorAll =
1472
- DocumentFragment.prototype.querySelectorAll =
1473
- function querySelectorAll() {
1474
- var ctor = Object.getPrototypeOf(this).__proto__.__proto__.constructor.name;
1475
- if (!('nodeType' in this)) {
1476
- emit('\'querySelectorAll\' called on an object that does not implement interface ' + ctor + '.', TypeError);
1477
- }
1478
- return arguments.length < 1 ? select.apply(this, []) :
1479
- arguments.length < 2 ? select.apply(this, [arguments[0], this]) :
1480
- select.apply(this, [arguments[0], this, typeof arguments[1] == 'function' ? arguments[1] : undefined]);
1481
- };
1482
- if (all) {
1483
- document.addEventListener('load', function (e) {
1484
- var c, d, r, s, t = e.target;
1485
- if (/iframe/i.test(t.localName)) {
1486
- c = '(' + Export + ')(this, ' + Factory + ');';
1487
- d = t.contentDocument;
1488
- s = d.createElement('script');
1489
- s.textContent = c + 'NW.Dom.install()';
1490
- r = d.documentElement;
1491
- r.removeChild(r.insertBefore(s, r.firstChild));
1492
- }
1493
- }, true);
1494
- }
1495
- },
1496
- // restore QSA methods (only for browsers)
1497
- uninstall = function () {
1498
- // reinstates QSA native references
1499
- Element.prototype.closest = _closest;
1500
- Element.prototype.matches = _matches;
1501
- Element.prototype.querySelector =
1502
- Document.prototype.querySelector =
1503
- DocumentFragment.prototype.querySelector = _querySelector;
1504
- Element.prototype.querySelectorAll =
1505
- Document.prototype.querySelectorAll =
1506
- DocumentFragment.prototype.querySelectorAll = _querySelectorAll;
1507
- },
1508
- // empty set
1509
- none = Array(),
1510
- // context
1511
- lastContext,
1512
- // selector
1513
- lastMatched, lastSelected,
1514
- // cached lambdas
1515
- matchLambdas = {}, selectLambdas = {},
1516
- // cached resolvers
1517
- matchResolvers = {}, selectResolvers = {},
1518
- // passed to resolvers
1519
- Snapshot = {
1520
- doc: doc,
1521
- from: doc,
1522
- root: root,
1523
- byTag: byTag,
1524
- first: first,
1525
- match: match,
1526
- ancestor: ancestor,
1527
- nthOfType: nthOfType,
1528
- nthElement: nthElement,
1529
- hasAttributeNS: hasAttributeNS
1530
- },
1531
- // public exported methods/objects
1532
- Dom = {
1533
- // exported cache objects
1534
- lastMatched: lastMatched,
1535
- lastSelected: lastSelected,
1536
- matchLambdas: matchLambdas,
1537
- selectLambdas: selectLambdas,
1538
- matchResolvers: matchResolvers,
1539
- selectResolvers: selectResolvers,
1540
- // exported compiler macros
1541
- CFG: CFG,
1542
- M_BODY: M_BODY,
1543
- S_BODY: S_BODY,
1544
- M_TEST: M_TEST,
1545
- S_TEST: S_TEST,
1546
- // exported engine methods
1547
- byId: byId,
1548
- byTag: byTag,
1549
- byClass: byClass,
1550
- match: match,
1551
- first: first,
1552
- select: select,
1553
- closest: ancestor,
1554
- compile: compile,
1555
- configure: configure,
1556
- emit: emit,
1557
- Config: Config,
1558
- Snapshot: Snapshot,
1559
- Version: version,
1560
- install: install,
1561
- uninstall: uninstall,
1562
- Operators: Operators,
1563
- Selectors: Selectors,
1564
- // register a new selector combinator symbol and its related function resolver
1565
- registerCombinator: function (combinator, resolver) {
1566
- var i = 0, l = combinator.length, symbol;
1567
- for (; l > i; ++i) {
1568
- if (combinator[i] != '=') {
1569
- symbol = combinator[i];
1570
- break;
1571
- }
1572
- }
1573
- if (CFG.combinators.indexOf(symbol) < 0) {
1574
- CFG.combinators = CFG.combinators.replace('](', symbol + '](');
1575
- CFG.combinators = CFG.combinators.replace('])', symbol + '])');
1576
- Combinators[combinator] = resolver;
1577
- setIdentifierSyntax();
1578
- }
1579
- else {
1580
- console.warn('Warning: the \'' + combinator + '\' combinator is already registered.');
1581
- }
1582
- },
1583
- // register a new attribute operator symbol and its related function resolver
1584
- registerOperator: function (operator, resolver) {
1585
- var i = 0, l = operator.length, symbol;
1586
- for (; l > i; ++i) {
1587
- if (operator[i] != '=') {
1588
- symbol = operator[i];
1589
- break;
1590
- }
1591
- }
1592
- if (CFG.operators.indexOf(symbol) < 0 && !Operators[operator]) {
1593
- CFG.operators = CFG.operators.replace(']=', symbol + ']=');
1594
- Operators[operator] = resolver;
1595
- setIdentifierSyntax();
1596
- }
1597
- else {
1598
- console.warn('Warning: the \'' + operator + '\' operator is already registered.');
1599
- }
1600
- },
1601
- // register a new selector symbol and its related function resolver
1602
- registerSelector: function (name, rexp, func) {
1603
- Selectors[name] || (Selectors[name] = {
1604
- Expression: rexp,
1605
- Callback: func
1606
- });
1607
- }
1608
- };
1609
- initialize(doc);
1610
- return Dom;
1611
- }