wpa_cli_web 0.0.5 → 0.0.6
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.
- data/.bowerrc +3 -0
- data/lib/wpa_cli_web.rb +19 -31
- data/lib/wpa_cli_web/public/bower_components/house-style/.bower.json +14 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/.bowerrc +3 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/.gitignore +2 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/Gemfile +6 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/Gruntfile.js +99 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/Guardfile +19 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/bower.json +7 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/bower_components/normalize-css/LICENSE.md +19 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/bower_components/normalize-css/README.md +49 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/bower_components/normalize-css/bower.json +23 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/bower_components/normalize-css/normalize.css +396 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/house-style.css +860 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/house-style.min.css +1 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/base/base.css +37 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/button/button.css +26 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/grid/grid.css +151 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/grid/grid.png +0 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/grid/images.html +208 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/grid/index.html +141 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/loading/index.html +22 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/loading/loading.css +41 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/loading/spinner.svg +11 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/masthead/bbc-blocks-white.png +0 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/masthead/index.html +20 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/masthead/masthead.css +23 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/panel/panel.css +71 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/project-header/index.html +22 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/project-header/project-header.css +37 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/table/index.html +26 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/table/table.css +6 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/modules/transitions/transitions.css +11 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/package.json +21 -0
- data/lib/wpa_cli_web/public/bower_components/house-style/vendor/prefixfree.min.js +5 -0
- data/lib/wpa_cli_web/public/bower_components/normalize-css/.bower.json +21 -0
- data/lib/wpa_cli_web/public/bower_components/normalize-css/LICENSE.md +19 -0
- data/lib/wpa_cli_web/public/bower_components/normalize-css/README.md +49 -0
- data/lib/wpa_cli_web/public/bower_components/normalize-css/bower.json +12 -0
- data/lib/wpa_cli_web/public/bower_components/normalize-css/normalize.css +396 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/.bower.json +14 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/.gitignore +3 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/.travis.yml +10 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/LICENSE +7 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/Makefile +6 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/README.md +167 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/config/smoosh.json +35 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/integration/ender.js +1033 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/integration/integration.html +26 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/mobile/ender.js +62 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/mobile/package.json +14 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/mobile/qwery-mobile.js +79 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/mobile/qwery-mobile.min.js +7 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/mobile/src/mobile.js +72 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/package.json +25 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/pseudos/package.json +17 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/pseudos/qwery-pseudos.js +106 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/pseudos/qwery-pseudos.min.js +7 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/pseudos/src/pseudos.js +99 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/qwery.js +369 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/qwery.min.js +7 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/src/copyright.js +6 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/src/ender.js +62 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/src/qwery.js +362 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/W3C-Selector-tests.html +1372 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/benchmarks.html +220 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/index.html +132 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/mobile.html +58 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/phantom.js +43 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/test-env.js +25 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/tests/tests.js +533 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/vendor/nw.js +1680 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/vendor/sink.css +79 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/vendor/sink.js +181 -0
- data/lib/wpa_cli_web/public/bower_components/qwery/vendor/sizzle.js +1400 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/.bower.json +14 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/.gitignore +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/.jshintrc +61 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/Makefile +8 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/README.md +308 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/build.json +74 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/make/tests.js +89 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/package.json +27 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/reqwest.js +565 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/reqwest.min.js +7 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/src/copyright.js +6 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/src/ender.js +26 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/src/reqwest.js +559 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/ender.js +117 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/badfixtures.xml +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures.html +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures.js +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures.json +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures.xml +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_jsonp.jsonp +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_jsonp2.jsonp +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_jsonp3.jsonp +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_jsonp_multi.jsonp +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_jsonp_multi_b.jsonp +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_jsonp_multi_c.jsonp +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/fixtures_with_prefix.json +1 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/fixtures/invalidJSON.json +5 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/tests.html +105 -0
- data/lib/wpa_cli_web/public/bower_components/reqwest/tests/tests.js +1723 -0
- data/lib/wpa_cli_web/views/access_points.erb +5 -0
- data/lib/wpa_cli_web/views/access_points_list.erb +19 -0
- data/lib/wpa_cli_web/views/layout.erb +141 -0
- data/lib/wpa_cli_web/views/networks_edit.erb +15 -0
- data/lib/wpa_cli_web/views/restart.erb +7 -0
- data/lib/wpa_cli_web/views/restarting.erb +14 -0
- data/wpa_cli_web.gemspec +1 -1
- metadata +111 -2
|
@@ -0,0 +1,1680 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2007-2010 Diego Perini
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* nwmatcher.js - A fast CSS selector engine and matcher
|
|
6
|
+
*
|
|
7
|
+
* Author: Diego Perini <diego.perini at gmail com>
|
|
8
|
+
* Version: 1.2.4beta
|
|
9
|
+
* Created: 20070722
|
|
10
|
+
* Release: 20110116
|
|
11
|
+
*
|
|
12
|
+
* License:
|
|
13
|
+
* http://javascript.nwbox.com/NWMatcher/MIT-LICENSE
|
|
14
|
+
* Download:
|
|
15
|
+
* http://javascript.nwbox.com/NWMatcher/nwmatcher.js
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
(function(global) {
|
|
19
|
+
|
|
20
|
+
var version = 'nwmatcher-1.2.4beta',
|
|
21
|
+
|
|
22
|
+
// processing context
|
|
23
|
+
doc = global.document,
|
|
24
|
+
|
|
25
|
+
// context root element
|
|
26
|
+
root = doc.documentElement,
|
|
27
|
+
|
|
28
|
+
// save method reference
|
|
29
|
+
slice = Array.prototype.slice,
|
|
30
|
+
|
|
31
|
+
// persist last selector/matcher parsing data
|
|
32
|
+
lastError = '',
|
|
33
|
+
lastSlice = '',
|
|
34
|
+
lastPosition = 0,
|
|
35
|
+
lastMatcher = '',
|
|
36
|
+
lastSelector = '',
|
|
37
|
+
isSingleMatch = false,
|
|
38
|
+
isSingleSelect = false,
|
|
39
|
+
|
|
40
|
+
// initialize selector/matcher loading context
|
|
41
|
+
lastMatchContext = doc,
|
|
42
|
+
lastSelectContext = doc,
|
|
43
|
+
|
|
44
|
+
// prefixes identifying id, class & pseudo-class
|
|
45
|
+
prefixes = '[.:#]?',
|
|
46
|
+
|
|
47
|
+
// attributes operators
|
|
48
|
+
// ! invalid but compat !
|
|
49
|
+
operators = '([~*^$|!]?={1})',
|
|
50
|
+
|
|
51
|
+
// whitespace characters
|
|
52
|
+
whitespace = '[\\x20\\t\\n\\r\\f]*',
|
|
53
|
+
|
|
54
|
+
// 4 combinators F E, F>E, F+E, F~E
|
|
55
|
+
combinators = '[\\x20]|[>+~][^>+~]',
|
|
56
|
+
|
|
57
|
+
// an+b format params for psuedo-classes
|
|
58
|
+
pseudoparms = '[-+]?\\d*n?[-+]?\\d*',
|
|
59
|
+
|
|
60
|
+
// CSS quoted string values
|
|
61
|
+
quotedvalue = '"[^"]*"' + "|'[^']*'",
|
|
62
|
+
|
|
63
|
+
// http://www.w3.org/TR/css3-syntax/#characters
|
|
64
|
+
// unicode/ISO 10646 characters 161 and higher
|
|
65
|
+
// NOTE: Safari 2.0.x crashes with escaped (\\)
|
|
66
|
+
// Unicode ranges in regular expressions so we
|
|
67
|
+
// use a negated character range class instead
|
|
68
|
+
encoding = '(?:[-\\w]|[^\\x00-\\xa0]|\\\\.)',
|
|
69
|
+
|
|
70
|
+
// CSS identifier syntax
|
|
71
|
+
identifier = '(?:-?[_a-zA-Z]{1}[-\\w]*|[^\\x00-\\xa0]+|\\\\.+)+',
|
|
72
|
+
|
|
73
|
+
// build attribute string
|
|
74
|
+
attributes =
|
|
75
|
+
whitespace + '(' + encoding + '+:?' + encoding + '+)' +
|
|
76
|
+
whitespace + '(?:' + operators + whitespace + '(' +
|
|
77
|
+
quotedvalue + '|' + identifier + '))?' + whitespace,
|
|
78
|
+
|
|
79
|
+
// build pseudoclass string
|
|
80
|
+
pseudoclass = '((?:' +
|
|
81
|
+
// an+b parameters or quoted string
|
|
82
|
+
pseudoparms + '|' + quotedvalue + '|' +
|
|
83
|
+
// id, class, pseudo-class selector
|
|
84
|
+
prefixes + '|' + encoding + '+|' +
|
|
85
|
+
// nested HTML attribute selector
|
|
86
|
+
'\\[' + attributes + '\\]|' +
|
|
87
|
+
// nested pseudo-class selector
|
|
88
|
+
'\\(.+\\)|' + whitespace + '|' +
|
|
89
|
+
// nested pseudos/separators
|
|
90
|
+
',)+)',
|
|
91
|
+
|
|
92
|
+
// placeholder for extensions
|
|
93
|
+
extensions = '.+',
|
|
94
|
+
|
|
95
|
+
// CSS3: syntax scanner and
|
|
96
|
+
// one pass validation only
|
|
97
|
+
// using regular expression
|
|
98
|
+
standardValidator =
|
|
99
|
+
// discard start
|
|
100
|
+
'(?=\s*[^>+~(){}<>])' +
|
|
101
|
+
// open match group
|
|
102
|
+
'(' +
|
|
103
|
+
//universal selector
|
|
104
|
+
'\\*' +
|
|
105
|
+
// id/class/tag/pseudo-class identifier
|
|
106
|
+
'|(?:' + prefixes + identifier + ')' +
|
|
107
|
+
// combinator selector
|
|
108
|
+
'|' + combinators +
|
|
109
|
+
// HTML attribute selector
|
|
110
|
+
'|\\[' + attributes + '\\]' +
|
|
111
|
+
// pseudo-classes parameters
|
|
112
|
+
'|\\(' + pseudoclass + '\\)' +
|
|
113
|
+
// dom properties selector (extension)
|
|
114
|
+
'|\\{' + extensions + '\\}' +
|
|
115
|
+
// selector group separator (comma)
|
|
116
|
+
'|,' +
|
|
117
|
+
// close match group
|
|
118
|
+
')+',
|
|
119
|
+
|
|
120
|
+
// validator for standard selectors as default
|
|
121
|
+
reValidator = new RegExp(standardValidator, 'g'),
|
|
122
|
+
|
|
123
|
+
// validator for complex selectors in ':not()' pseudo-classes
|
|
124
|
+
extendedValidator = standardValidator.replace(pseudoclass, '.*'),
|
|
125
|
+
|
|
126
|
+
// whitespace is any combination of these 5 character [\x20\t\n\r\f]
|
|
127
|
+
// http://www.w3.org/TR/css3-selectors/#selector-syntax
|
|
128
|
+
reTrimSpaces = new RegExp('^' +
|
|
129
|
+
whitespace + '|' + whitespace + '$', 'g'),
|
|
130
|
+
|
|
131
|
+
// only allow simple selectors nested in ':not()' pseudo-classes
|
|
132
|
+
reSimpleNot = new RegExp('^(' +
|
|
133
|
+
'(?!:not)' +
|
|
134
|
+
'(' + prefixes +
|
|
135
|
+
'|' + identifier +
|
|
136
|
+
'|\\([^()]*\\))+' +
|
|
137
|
+
'|\\[' + attributes + '\\]' +
|
|
138
|
+
')$'),
|
|
139
|
+
|
|
140
|
+
// skip group of round brackets
|
|
141
|
+
skipround = '\\([^()]+\\)|\\(.*\\)',
|
|
142
|
+
// skip group of curly brackets
|
|
143
|
+
skipcurly = '\\{[^{}]+\\}|\\{.*\\}',
|
|
144
|
+
// skip group of square brackets
|
|
145
|
+
skipsquare = '\\[[^[\\]]*\\]|\\[.*\\]',
|
|
146
|
+
|
|
147
|
+
// skip [ ], ( ), { } groups in token tails
|
|
148
|
+
skipgroup = '\\[.*\\]|\\(.*\\)|\\{.*\\}',
|
|
149
|
+
|
|
150
|
+
// split comma groups, exclude commas from
|
|
151
|
+
// quotes '' "" and from brackets () [] {}
|
|
152
|
+
reSplitGroup = new RegExp('(' +
|
|
153
|
+
'[^(,)\\\\\\[\\]]+' +
|
|
154
|
+
'|\\[(?:' + skipsquare +
|
|
155
|
+
'|' + quotedvalue +
|
|
156
|
+
'|[^\\[\\]]+)+\\]' +
|
|
157
|
+
'|' + skipround +
|
|
158
|
+
'|' + skipcurly +
|
|
159
|
+
'|\\\\.' +
|
|
160
|
+
')+', 'g'),
|
|
161
|
+
|
|
162
|
+
// split last, right most, selector group token
|
|
163
|
+
reSplitToken = new RegExp('(' +
|
|
164
|
+
'\\(' + pseudoclass + '\\)|' +
|
|
165
|
+
'\\[' + attributes + '\\]|' +
|
|
166
|
+
'[^\x20>+~]|\\\\.)+', 'g'),
|
|
167
|
+
|
|
168
|
+
// for pseudos, ids and in excess whitespace removal
|
|
169
|
+
reClassValue = new RegExp('(' + identifier + ')'),
|
|
170
|
+
reIdSelector = new RegExp('#(' + identifier + ')'),
|
|
171
|
+
reWhiteSpace = /[\x20\t\n\r\f]+/g,
|
|
172
|
+
|
|
173
|
+
// match missing R/L context
|
|
174
|
+
reLeftContext = /^\s*[>+~]{1}/,
|
|
175
|
+
reRightContext = /[>+~]{1}\s*$/,
|
|
176
|
+
|
|
177
|
+
reOptimizeSelector = new RegExp(identifier + '|^$'),
|
|
178
|
+
|
|
179
|
+
/*----------------------------- FEATURE TESTING ----------------------------*/
|
|
180
|
+
|
|
181
|
+
// detect native methods
|
|
182
|
+
isNative = (function() {
|
|
183
|
+
var s = (global.toString + '').replace(/toString/g, '');
|
|
184
|
+
return function(object, method) {
|
|
185
|
+
var m = object ? object[method] : false, r = new RegExp(method, 'g');
|
|
186
|
+
return !!(m && typeof m != 'string' && s === (m + '').replace(r, ''));
|
|
187
|
+
};
|
|
188
|
+
})(),
|
|
189
|
+
|
|
190
|
+
// Safari 2 missing document.compatMode property
|
|
191
|
+
// makes harder to detect Quirks vs. Strict mode
|
|
192
|
+
isQuirks =
|
|
193
|
+
function(document) {
|
|
194
|
+
return typeof document.compatMode == 'string' ?
|
|
195
|
+
document.compatMode.indexOf('CSS') < 0 :
|
|
196
|
+
(function() {
|
|
197
|
+
var div = document.createElement('div'),
|
|
198
|
+
isStrict = div.style &&
|
|
199
|
+
(div.style.width = 1) &&
|
|
200
|
+
div.style.width != '1px';
|
|
201
|
+
div = null;
|
|
202
|
+
return !isStrict;
|
|
203
|
+
})();
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
// XML is functional in W3C browsers
|
|
207
|
+
isXML = 'xmlVersion' in doc ?
|
|
208
|
+
function(document) {
|
|
209
|
+
return !!document.xmlVersion ||
|
|
210
|
+
(/xml$/).test(document.contentType) ||
|
|
211
|
+
!(/html/i).test(document.documentElement.nodeName);
|
|
212
|
+
} :
|
|
213
|
+
function(document) {
|
|
214
|
+
return document.firstChild.nodeType == 7 &&
|
|
215
|
+
(/xml/i).test(document.firstChild.nodeName) ||
|
|
216
|
+
!(/html/i).test(document.documentElement.nodeName);
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
// initialized with the loading context
|
|
220
|
+
// and reset for each selection query
|
|
221
|
+
isQuirksMode = isQuirks(doc),
|
|
222
|
+
isXMLDocument = isXML(doc),
|
|
223
|
+
|
|
224
|
+
// NATIVE_XXXXX true if method exist and is callable
|
|
225
|
+
// detect if DOM methods are native in browsers
|
|
226
|
+
NATIVE_FOCUS = isNative(doc, 'hasFocus'),
|
|
227
|
+
NATIVE_QSAPI = isNative(doc, 'querySelector'),
|
|
228
|
+
NATIVE_GEBID = isNative(doc, 'getElementById'),
|
|
229
|
+
NATIVE_GEBTN = isNative(root, 'getElementsByTagName'),
|
|
230
|
+
NATIVE_GEBCN = isNative(root, 'getElementsByClassName'),
|
|
231
|
+
|
|
232
|
+
// detect native getAttribute/hasAttribute methods,
|
|
233
|
+
// frameworks extend these to elements, but it seems
|
|
234
|
+
// this does not work for XML namespaced attributes,
|
|
235
|
+
// used to check both getAttribute/hasAttribute in IE
|
|
236
|
+
NATIVE_GET_ATTRIBUTE = isNative(root, 'getAttribute'),
|
|
237
|
+
NATIVE_HAS_ATTRIBUTE = isNative(root, 'hasAttribute'),
|
|
238
|
+
|
|
239
|
+
// check if slice() can convert nodelist to array
|
|
240
|
+
// see http://yura.thinkweb2.com/cft/
|
|
241
|
+
NATIVE_SLICE_PROTO =
|
|
242
|
+
(function() {
|
|
243
|
+
var isBuggy = false, id = root.id;
|
|
244
|
+
root.id = 'length';
|
|
245
|
+
try {
|
|
246
|
+
isBuggy = !!slice.call(doc.childNodes, 0)[0];
|
|
247
|
+
} catch(e) { }
|
|
248
|
+
root.id = id;
|
|
249
|
+
return isBuggy;
|
|
250
|
+
})(),
|
|
251
|
+
|
|
252
|
+
// supports the new traversal API
|
|
253
|
+
NATIVE_TRAVERSAL_API =
|
|
254
|
+
'nextElementSibling' in root && 'previousElementSibling' in root,
|
|
255
|
+
|
|
256
|
+
// select Matches Selector API to use if available
|
|
257
|
+
NATIVE_MATCHES_SELECTOR =
|
|
258
|
+
isNative(root, 'matchesSelector') ? 'matchesSelector' :
|
|
259
|
+
isNative(root, 'msMatchesSelector') ? 'msMatchesSelector' :
|
|
260
|
+
isNative(root, 'mozMatchesSelector') ? 'mozMatchesSelector' :
|
|
261
|
+
isNative(root, 'webkitMatchesSelector') ? 'webkitMatchesSelector' : null,
|
|
262
|
+
|
|
263
|
+
// BUGGY_XXXXX true if method is feature tested and has known bugs
|
|
264
|
+
// detect buggy gEBID
|
|
265
|
+
BUGGY_GEBID = NATIVE_GEBID ?
|
|
266
|
+
(function() {
|
|
267
|
+
var isBuggy = true, x = 'x' + String(+new Date),
|
|
268
|
+
a = doc.createElementNS ? 'a' : '<a name="' + x + '">';
|
|
269
|
+
(a = doc.createElement(a)).name = x;
|
|
270
|
+
root.insertBefore(a, root.firstChild);
|
|
271
|
+
isBuggy = !!doc.getElementById(x);
|
|
272
|
+
root.removeChild(a);
|
|
273
|
+
a = null;
|
|
274
|
+
return isBuggy;
|
|
275
|
+
})() :
|
|
276
|
+
true,
|
|
277
|
+
|
|
278
|
+
// detect IE gEBTN comment nodes bug
|
|
279
|
+
BUGGY_GEBTN = NATIVE_GEBTN ?
|
|
280
|
+
(function() {
|
|
281
|
+
var isBuggy, div = doc.createElement('div');
|
|
282
|
+
div.appendChild(doc.createComment(''));
|
|
283
|
+
isBuggy = div.getElementsByTagName('*')[0];
|
|
284
|
+
div.removeChild(div.firstChild);
|
|
285
|
+
div = null;
|
|
286
|
+
return !!isBuggy;
|
|
287
|
+
})() :
|
|
288
|
+
true,
|
|
289
|
+
|
|
290
|
+
// detect Opera gEBCN second class and/or UTF8 bugs as well as Safari 3.2
|
|
291
|
+
// caching class name results and not detecting when changed,
|
|
292
|
+
// tests are based on the jQuery selector test suite
|
|
293
|
+
BUGGY_GEBCN = NATIVE_GEBCN ?
|
|
294
|
+
(function() {
|
|
295
|
+
var isBuggy, div = doc.createElement('div'), test = '\u53f0\u5317';
|
|
296
|
+
|
|
297
|
+
// Opera tests
|
|
298
|
+
div.appendChild(doc.createElement('span')).
|
|
299
|
+
setAttribute('class', test + 'abc ' + test);
|
|
300
|
+
div.appendChild(doc.createElement('span')).
|
|
301
|
+
setAttribute('class', 'x');
|
|
302
|
+
|
|
303
|
+
isBuggy = !div.getElementsByClassName(test)[0];
|
|
304
|
+
|
|
305
|
+
// Safari test
|
|
306
|
+
div.lastChild.className = test;
|
|
307
|
+
if (!isBuggy)
|
|
308
|
+
isBuggy = div.getElementsByClassName(test).length !== 2;
|
|
309
|
+
|
|
310
|
+
div.removeChild(div.firstChild);
|
|
311
|
+
div.removeChild(div.firstChild);
|
|
312
|
+
div = null;
|
|
313
|
+
return isBuggy;
|
|
314
|
+
})() :
|
|
315
|
+
true,
|
|
316
|
+
|
|
317
|
+
// detect IE bug with dynamic attributes
|
|
318
|
+
BUGGY_GET_ATTRIBUTE = NATIVE_GET_ATTRIBUTE ?
|
|
319
|
+
(function() {
|
|
320
|
+
var isBuggy, input;
|
|
321
|
+
(input = doc.createElement('input')).setAttribute('value', '5');
|
|
322
|
+
return isBuggy = input.defaultValue != 5;
|
|
323
|
+
})() :
|
|
324
|
+
true,
|
|
325
|
+
|
|
326
|
+
// detect IE bug with non-standard boolean attributes
|
|
327
|
+
BUGGY_HAS_ATTRIBUTE = NATIVE_HAS_ATTRIBUTE ?
|
|
328
|
+
(function() {
|
|
329
|
+
var isBuggy, option = doc.createElement('option');
|
|
330
|
+
option.setAttribute('selected', 'selected');
|
|
331
|
+
isBuggy = !option.hasAttribute('selected');
|
|
332
|
+
return isBuggy;
|
|
333
|
+
})() :
|
|
334
|
+
true,
|
|
335
|
+
|
|
336
|
+
// detect matchesSelector correctly throw errors
|
|
337
|
+
BUGGY_PSEUDOS = NATIVE_MATCHES_SELECTOR ?
|
|
338
|
+
(function() {
|
|
339
|
+
var isBuggy = false;
|
|
340
|
+
try {
|
|
341
|
+
root[NATIVE_MATCHES_SELECTOR](':buggy');
|
|
342
|
+
isBuggy = true;
|
|
343
|
+
} catch(e) { }
|
|
344
|
+
return isBuggy;
|
|
345
|
+
})() :
|
|
346
|
+
true,
|
|
347
|
+
|
|
348
|
+
// detect Safari bug with selected option elements
|
|
349
|
+
BUGGY_SELECTED =
|
|
350
|
+
(function() {
|
|
351
|
+
var isBuggy, select = doc.createElement('select');
|
|
352
|
+
select.appendChild(doc.createElement('option'));
|
|
353
|
+
isBuggy = !select.firstChild.selected;
|
|
354
|
+
return isBuggy;
|
|
355
|
+
})(),
|
|
356
|
+
|
|
357
|
+
// check Seletor API implementations
|
|
358
|
+
RE_BUGGY_QSAPI = NATIVE_QSAPI ?
|
|
359
|
+
(function() {
|
|
360
|
+
var pattern = [ ], div = doc.createElement('div'), element;
|
|
361
|
+
|
|
362
|
+
// In quirks mode css class names are case insensitive.
|
|
363
|
+
// In standards mode they are case sensitive. See docs:
|
|
364
|
+
// https://developer.mozilla.org/en/Mozilla_Quirks_Mode_Behavior
|
|
365
|
+
// http://www.whatwg.org/specs/web-apps/current-work/#selectors
|
|
366
|
+
|
|
367
|
+
// Safari 3.2 QSA doesn't work with mixedcase in quirksmode
|
|
368
|
+
// https://bugs.webkit.org/show_bug.cgi?id=19047
|
|
369
|
+
// must test the attribute selector '[class~=xxx]'
|
|
370
|
+
// before '.xXx' or the bug may not present itself
|
|
371
|
+
div.appendChild(doc.createElement('p')).setAttribute('class', 'xXx');
|
|
372
|
+
div.appendChild(doc.createElement('p')).setAttribute('class', 'xxx');
|
|
373
|
+
if (isQuirks(doc) &&
|
|
374
|
+
(div.querySelectorAll('[class~=xxx]').length != 2 ||
|
|
375
|
+
div.querySelectorAll('.xXx').length != 2)) {
|
|
376
|
+
pattern.push('(?:\\[[\\x20\\t\\n\\r\\f]*class\\b|\\.' + identifier + ')');
|
|
377
|
+
}
|
|
378
|
+
div.removeChild(div.firstChild);
|
|
379
|
+
div.removeChild(div.firstChild);
|
|
380
|
+
|
|
381
|
+
// ^= $= *= operators bugs whith empty values (Opera 10 / IE8)
|
|
382
|
+
div.appendChild(doc.createElement('p')).setAttribute('class', '');
|
|
383
|
+
try {
|
|
384
|
+
div.querySelectorAll('[class^=""]').length == 1 &&
|
|
385
|
+
pattern.push('\\[\\s*.*(?=\\^=|\\$=|\\*=).*]');
|
|
386
|
+
} catch(e) { }
|
|
387
|
+
div.removeChild(div.firstChild);
|
|
388
|
+
|
|
389
|
+
// :checked bugs whith checkbox elements (Opera 10 to 10.53)
|
|
390
|
+
element = doc.createElement('input');
|
|
391
|
+
element.setAttribute('type', 'checkbox');
|
|
392
|
+
element.setAttribute('checked', 'checked');
|
|
393
|
+
div.appendChild(element);
|
|
394
|
+
try {
|
|
395
|
+
div.querySelectorAll(':checked').length == 1 ||
|
|
396
|
+
pattern.push(':checked');
|
|
397
|
+
} catch(e) { }
|
|
398
|
+
div.removeChild(div.firstChild);
|
|
399
|
+
|
|
400
|
+
// :checked bug with option elements (Firefox 3.6.x)
|
|
401
|
+
// it wrongly includes 'selected' options elements
|
|
402
|
+
element = doc.createElement('option');
|
|
403
|
+
element.setAttribute('selected', 'selected');
|
|
404
|
+
div.appendChild(element);
|
|
405
|
+
try {
|
|
406
|
+
div.querySelectorAll(':checked').length == 1 &&
|
|
407
|
+
pattern.push(':checked');
|
|
408
|
+
} catch(e) { }
|
|
409
|
+
div.removeChild(div.firstChild);
|
|
410
|
+
|
|
411
|
+
// :enabled :disabled bugs with hidden fields (Firefox 3.5 QSA bug)
|
|
412
|
+
// http://www.w3.org/TR/html5/interactive-elements.html#selector-enabled
|
|
413
|
+
// IE8 QSA has problems too and throws error with these dynamic pseudos
|
|
414
|
+
(element = doc.createElement('input')).setAttribute('type', 'hidden');
|
|
415
|
+
div.appendChild(element);
|
|
416
|
+
try {
|
|
417
|
+
div.querySelectorAll(':enabled').length === 1 &&
|
|
418
|
+
pattern.push(':enabled', ':disabled');
|
|
419
|
+
} catch(e) { }
|
|
420
|
+
div.removeChild(div.firstChild);
|
|
421
|
+
|
|
422
|
+
// :link bugs with hyperlinks matching (Firefox/Safari)
|
|
423
|
+
div.appendChild(doc.createElement('a')).setAttribute('href', 'x');
|
|
424
|
+
div.querySelectorAll(':link').length !== 1 && pattern.push(':link');
|
|
425
|
+
div.removeChild(div.firstChild);
|
|
426
|
+
|
|
427
|
+
// avoid following selectors for IE QSA
|
|
428
|
+
if (BUGGY_HAS_ATTRIBUTE) {
|
|
429
|
+
pattern.push(
|
|
430
|
+
// IE fails reading original values for input/textarea
|
|
431
|
+
'\\[\\s*value',
|
|
432
|
+
// IE fails reading original boolean value for controls
|
|
433
|
+
'\\[\\s*ismap',
|
|
434
|
+
'\\[\\s*checked',
|
|
435
|
+
'\\[\\s*disabled',
|
|
436
|
+
'\\[\\s*multiple',
|
|
437
|
+
'\\[\\s*readonly',
|
|
438
|
+
'\\[\\s*selected');
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
div = null;
|
|
442
|
+
return pattern.length ?
|
|
443
|
+
new RegExp(pattern.join('|')) :
|
|
444
|
+
{ 'test': function() { return false; } };
|
|
445
|
+
})() :
|
|
446
|
+
true,
|
|
447
|
+
|
|
448
|
+
// matches pseudo-classes
|
|
449
|
+
RE_PSEUDOS = new RegExp(':[-\\w]+'),
|
|
450
|
+
|
|
451
|
+
// matches simple id, tag & class selectors
|
|
452
|
+
RE_SIMPLE_SELECTOR = new RegExp(
|
|
453
|
+
!(BUGGY_GEBTN && BUGGY_GEBCN) ?
|
|
454
|
+
'^(?:\\*|[.#]?-?[_a-zA-Z]{1}' + encoding + '*)$' :
|
|
455
|
+
'^#?-?[_a-zA-Z]{1}' + encoding + '*$'),
|
|
456
|
+
|
|
457
|
+
/*----------------------------- LOOKUP OBJECTS -----------------------------*/
|
|
458
|
+
|
|
459
|
+
LINK_NODES = { 'a': 1, 'A': 1, 'area': 1, 'AREA': 1, 'link': 1, 'LINK': 1 },
|
|
460
|
+
|
|
461
|
+
QSA_NODE_TYPES = { '9': 1, '11': 1 },
|
|
462
|
+
|
|
463
|
+
// boolean attributes should return attribute name instead of true/false
|
|
464
|
+
ATTR_BOOLEAN = {
|
|
465
|
+
checked: 1, disabled: 1, ismap: 1, multiple: 1, readonly: 1, selected: 1
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
// dynamic attributes that needs to be checked against original HTML value
|
|
469
|
+
ATTR_DEFAULT = {
|
|
470
|
+
value: 'defaultValue',
|
|
471
|
+
checked: 'defaultChecked',
|
|
472
|
+
selected: 'defaultSelected'
|
|
473
|
+
},
|
|
474
|
+
|
|
475
|
+
// HTML to DOM namespace mapping for special case attributes (IE engines)
|
|
476
|
+
ATTR_MAPPING = {
|
|
477
|
+
'class': 'className', 'for': 'htmlFor'
|
|
478
|
+
},
|
|
479
|
+
|
|
480
|
+
// attribute referencing URI data values need special treatment in IE
|
|
481
|
+
ATTR_URIDATA = {
|
|
482
|
+
'action': 2, 'cite': 2, 'codebase': 2, 'data': 2, 'href': 2,
|
|
483
|
+
'longdesc': 2, 'lowsrc': 2, 'src': 2, 'usemap': 2
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
// HTML 5 draft specifications
|
|
487
|
+
// http://www.whatwg.org/specs/web-apps/current-work/#selectors
|
|
488
|
+
HTML_TABLE = {
|
|
489
|
+
// class attribute must be treated case-insensitive in HTML quirks mode
|
|
490
|
+
// initialized by default to Standard Mode (case-sensitive),
|
|
491
|
+
// set dynamically by the attribute resolver
|
|
492
|
+
'class': 0,
|
|
493
|
+
'accept': 1, 'accept-charset': 1, 'align': 1, 'alink': 1, 'axis': 1,
|
|
494
|
+
'bgcolor': 1, 'charset': 1, 'checked': 1, 'clear': 1, 'codetype': 1, 'color': 1,
|
|
495
|
+
'compact': 1, 'declare': 1, 'defer': 1, 'dir': 1, 'direction': 1, 'disabled': 1,
|
|
496
|
+
'enctype': 1, 'face': 1, 'frame': 1, 'hreflang': 1, 'http-equiv': 1, 'lang': 1,
|
|
497
|
+
'language': 1, 'link': 1, 'media': 1, 'method': 1, 'multiple': 1, 'nohref': 1,
|
|
498
|
+
'noresize': 1, 'noshade': 1, 'nowrap': 1, 'readonly': 1, 'rel': 1, 'rev': 1,
|
|
499
|
+
'rules': 1, 'scope': 1, 'scrolling': 1, 'selected': 1, 'shape': 1, 'target': 1,
|
|
500
|
+
'text': 1, 'type': 1, 'valign': 1, 'valuetype': 1, 'vlink': 1
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
// the following attributes must be treated case-insensitive in XHTML mode
|
|
504
|
+
// Niels Leenheer http://rakaz.nl/item/css_selector_bugs_case_sensitivity
|
|
505
|
+
XHTML_TABLE = {
|
|
506
|
+
'accept': 1, 'accept-charset': 1, 'alink': 1, 'axis': 1,
|
|
507
|
+
'bgcolor': 1, 'charset': 1, 'codetype': 1, 'color': 1,
|
|
508
|
+
'enctype': 1, 'face': 1, 'hreflang': 1, 'http-equiv': 1,
|
|
509
|
+
'lang': 1, 'language': 1, 'link': 1, 'media': 1, 'rel': 1,
|
|
510
|
+
'rev': 1, 'target': 1, 'text': 1, 'type': 1, 'vlink': 1
|
|
511
|
+
},
|
|
512
|
+
|
|
513
|
+
/*-------------------------- REGULAR EXPRESSIONS ---------------------------*/
|
|
514
|
+
|
|
515
|
+
// placeholder to add functionalities
|
|
516
|
+
Selectors = {
|
|
517
|
+
// as a simple example this will check
|
|
518
|
+
// for chars not in standard ascii table
|
|
519
|
+
//
|
|
520
|
+
// 'mySpecialSelector': {
|
|
521
|
+
// 'Expression': /\u0080-\uffff/,
|
|
522
|
+
// 'Callback': mySelectorCallback
|
|
523
|
+
// }
|
|
524
|
+
//
|
|
525
|
+
// 'mySelectorCallback' will be invoked
|
|
526
|
+
// only after passing all other standard
|
|
527
|
+
// checks and only if none of them worked
|
|
528
|
+
},
|
|
529
|
+
|
|
530
|
+
// attribute operators
|
|
531
|
+
Operators = {
|
|
532
|
+
'=': "n=='%m'",
|
|
533
|
+
'^=': "n.indexOf('%m')==0",
|
|
534
|
+
'*=': "n.indexOf('%m')>-1",
|
|
535
|
+
'|=': "(n+'-').indexOf('%m-')==0",
|
|
536
|
+
'~=': "(' '+n+' ').indexOf(' %m ')>-1",
|
|
537
|
+
'$=': "n.substr(n.length-'%m'.length)=='%m'"
|
|
538
|
+
},
|
|
539
|
+
|
|
540
|
+
// optimization expressions
|
|
541
|
+
Optimize = {
|
|
542
|
+
ID: new RegExp('^\\*?#(' + encoding + '+)|' + skipgroup),
|
|
543
|
+
TAG: new RegExp('^(' + encoding + '+)|' + skipgroup),
|
|
544
|
+
CLASS: new RegExp('^\\*?\\.(' + encoding + '+$)|' + skipgroup),
|
|
545
|
+
NAME: /\[\s*name\s*=\s*((["']*)([^'"()]*?)\2)?\s*\]/
|
|
546
|
+
},
|
|
547
|
+
|
|
548
|
+
// precompiled Regular Expressions
|
|
549
|
+
Patterns = {
|
|
550
|
+
// structural pseudo-classes and child selectors
|
|
551
|
+
spseudos: /^\:(root|empty|nth)?-?(first|last|only)?-?(child)?-?(of-type)?(?:\(([^\x29]*)\))?(.*)/,
|
|
552
|
+
// uistates + dynamic + negation pseudo-classes
|
|
553
|
+
dpseudos: /^\:([\w]+|[^\x00-\xa0]+)(?:\((["']*)(.*?(\(.*\))?[^'"()]*?)\2\))?(.*)/,
|
|
554
|
+
// element attribute matcher
|
|
555
|
+
attribute: new RegExp('^\\[' + attributes + '\\](.*)'),
|
|
556
|
+
// E > F
|
|
557
|
+
children: /^[\x20\t\n\r\f]*\>[\x20\t\n\r\f]*(.*)/,
|
|
558
|
+
// E + F
|
|
559
|
+
adjacent: /^[\x20\t\n\r\f]*\+[\x20\t\n\r\f]*(.*)/,
|
|
560
|
+
// E ~ F
|
|
561
|
+
relative: /^[\x20\t\n\r\f]*\~[\x20\t\n\r\f]*(.*)/,
|
|
562
|
+
// E F
|
|
563
|
+
ancestor: /^[\x20\t\n\r\f]+(.*)/,
|
|
564
|
+
// all
|
|
565
|
+
universal: /^\*(.*)/,
|
|
566
|
+
// id
|
|
567
|
+
id: new RegExp('^#(' + encoding + '+)(.*)'),
|
|
568
|
+
// tag
|
|
569
|
+
tagName: new RegExp('^(' + encoding + '+)(.*)'),
|
|
570
|
+
// class
|
|
571
|
+
className: new RegExp('^\\.(' + encoding + '+)(.*)')
|
|
572
|
+
},
|
|
573
|
+
|
|
574
|
+
// current CSS3 grouping of Pseudo-Classes
|
|
575
|
+
// they allow implementing extensions
|
|
576
|
+
// and improve error notifications;
|
|
577
|
+
// the assigned value represent current spec status:
|
|
578
|
+
// 3 = CSS3, 2 = CSS2, '?' = maybe implemented
|
|
579
|
+
CSS3PseudoClasses = {
|
|
580
|
+
Structural: {
|
|
581
|
+
'root': 3, 'empty': 3,
|
|
582
|
+
'nth-child': 3, 'nth-last-child': 3,
|
|
583
|
+
'nth-of-type': 3, 'nth-last-of-type': 3,
|
|
584
|
+
'first-child': 3, 'last-child': 3, 'only-child': 3,
|
|
585
|
+
'first-of-type': 3, 'last-of-type': 3, 'only-of-type': 3
|
|
586
|
+
},
|
|
587
|
+
Others: {
|
|
588
|
+
'link': 3, 'visited': 3,
|
|
589
|
+
'target': 3, 'lang': 3, 'not': 3,
|
|
590
|
+
'active': 3, 'focus': 3, 'hover': 3,
|
|
591
|
+
'checked': 3, 'disabled': 3, 'enabled': 3, 'selected': 2
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
|
|
595
|
+
/*------------------------------ DOM METHODS -------------------------------*/
|
|
596
|
+
|
|
597
|
+
// concat elements to data
|
|
598
|
+
concatList =
|
|
599
|
+
function(data, elements) {
|
|
600
|
+
var i = -1, element;
|
|
601
|
+
if (data.length === 0 && Array.slice)
|
|
602
|
+
return Array.slice(elements);
|
|
603
|
+
while ((element = elements[++i]))
|
|
604
|
+
data[data.length] = element;
|
|
605
|
+
return data;
|
|
606
|
+
},
|
|
607
|
+
|
|
608
|
+
// concat elements to data and callback
|
|
609
|
+
concatCall =
|
|
610
|
+
function(data, elements, callback) {
|
|
611
|
+
var i = -1, element;
|
|
612
|
+
while ((element = elements[++i]))
|
|
613
|
+
callback(data[data.length] = element);
|
|
614
|
+
return data;
|
|
615
|
+
},
|
|
616
|
+
|
|
617
|
+
// element by id (raw)
|
|
618
|
+
byIdRaw =
|
|
619
|
+
function(id, elements) {
|
|
620
|
+
var i = -1, element = null;
|
|
621
|
+
while ((element = elements[++i])) {
|
|
622
|
+
if (element.getAttribute('id') == id) {
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return element;
|
|
627
|
+
},
|
|
628
|
+
|
|
629
|
+
// element by id
|
|
630
|
+
// @return element reference or null
|
|
631
|
+
byId = !BUGGY_GEBID ?
|
|
632
|
+
function(id, from) {
|
|
633
|
+
from || (from = doc);
|
|
634
|
+
id = id.replace(/\\/g, '');
|
|
635
|
+
if (isXMLDocument || from.nodeType != 9) {
|
|
636
|
+
return byIdRaw(id, from.getElementsByTagName('*'));
|
|
637
|
+
}
|
|
638
|
+
return from.getElementById(id);
|
|
639
|
+
} :
|
|
640
|
+
function(id, from) {
|
|
641
|
+
var element = null;
|
|
642
|
+
from || (from = doc);
|
|
643
|
+
id = id.replace(/\\/g, '');
|
|
644
|
+
if (isXMLDocument || from.nodeType != 9) {
|
|
645
|
+
return byIdRaw(id, from.getElementsByTagName('*'));
|
|
646
|
+
}
|
|
647
|
+
if ((element = from.getElementById(id)) &&
|
|
648
|
+
element.name == id && from.getElementsByName) {
|
|
649
|
+
return byIdRaw(id, from.getElementsByName(id));
|
|
650
|
+
}
|
|
651
|
+
return element;
|
|
652
|
+
},
|
|
653
|
+
|
|
654
|
+
// elements by tag (raw)
|
|
655
|
+
// @return array
|
|
656
|
+
byTagRaw = function(tag, from) {
|
|
657
|
+
var any = tag == '*', element = from, elements = [ ], next = element.firstChild;
|
|
658
|
+
any || (tag = tag.toUpperCase());
|
|
659
|
+
while ((element = next)) {
|
|
660
|
+
if (element.tagName > '@' && (any || element.tagName.toUpperCase() == tag)) {
|
|
661
|
+
elements[elements.length] = element;
|
|
662
|
+
}
|
|
663
|
+
if (next = element.firstChild || element.nextSibling) continue;
|
|
664
|
+
while (!next && (element = element.parentNode) && element != from) {
|
|
665
|
+
next = element.nextSibling;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return elements;
|
|
669
|
+
},
|
|
670
|
+
|
|
671
|
+
// elements by tag
|
|
672
|
+
// @return array
|
|
673
|
+
byTag = !BUGGY_GEBTN && NATIVE_SLICE_PROTO ?
|
|
674
|
+
function(tag, from) {
|
|
675
|
+
from || (from = doc);
|
|
676
|
+
return slice.call(from.getElementsByTagName ?
|
|
677
|
+
from.getElementsByTagName(tag) :
|
|
678
|
+
byTagRaw(tag, from), 0);
|
|
679
|
+
} :
|
|
680
|
+
function(tag, from) {
|
|
681
|
+
var i = -1, data = [ ],
|
|
682
|
+
element, elements = (from || doc).getElementsByTagName(tag);
|
|
683
|
+
if (tag == '*') {
|
|
684
|
+
var j = -1;
|
|
685
|
+
while ((element = elements[++i])) {
|
|
686
|
+
if (element.nodeName > '@')
|
|
687
|
+
data[++j] = element;
|
|
688
|
+
}
|
|
689
|
+
} else {
|
|
690
|
+
while ((element = elements[++i])) {
|
|
691
|
+
data[i] = element;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return data;
|
|
695
|
+
},
|
|
696
|
+
|
|
697
|
+
// elements by name
|
|
698
|
+
// @return array
|
|
699
|
+
byName =
|
|
700
|
+
function(name, from) {
|
|
701
|
+
return select('[name="' + name.replace(/\\/g, '') + '"]', from || doc);
|
|
702
|
+
},
|
|
703
|
+
|
|
704
|
+
// elements by class
|
|
705
|
+
// @return array
|
|
706
|
+
byClass = !BUGGY_GEBCN && NATIVE_SLICE_PROTO ?
|
|
707
|
+
function(className, from) {
|
|
708
|
+
return slice.call((from || doc).
|
|
709
|
+
getElementsByClassName(className.replace(/\\/g, '')), 0);
|
|
710
|
+
} :
|
|
711
|
+
function(className, from) {
|
|
712
|
+
from || (from = doc);
|
|
713
|
+
var i = -1, j = i,
|
|
714
|
+
data = [ ], element,
|
|
715
|
+
elements = byTag('*', from),
|
|
716
|
+
host = from.ownerDocument || from,
|
|
717
|
+
quirks = isQuirks(host), xml = isXML(host),
|
|
718
|
+
n = quirks ? className.toLowerCase() : className;
|
|
719
|
+
className = ' ' + n.replace(/\\/g, '') + ' ';
|
|
720
|
+
while ((element = elements[++i])) {
|
|
721
|
+
n = xml ? element.getAttribute('class') : element.className;
|
|
722
|
+
if (n && n.length && (' ' + (quirks ? n.toLowerCase() : n).
|
|
723
|
+
replace(reWhiteSpace, ' ') + ' ').indexOf(className) > -1) {
|
|
724
|
+
data[++j] = element;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return data;
|
|
728
|
+
},
|
|
729
|
+
|
|
730
|
+
// check if an element is a descendant of container
|
|
731
|
+
contains = 'compareDocumentPosition' in root ?
|
|
732
|
+
function(container, element) {
|
|
733
|
+
return (container.compareDocumentPosition(element) & 16) == 16;
|
|
734
|
+
} : 'contains' in root ?
|
|
735
|
+
function(container, element) {
|
|
736
|
+
return container !== element && container.contains(element);
|
|
737
|
+
} :
|
|
738
|
+
function(container, element) {
|
|
739
|
+
while ((element = element.parentNode)) {
|
|
740
|
+
if (element === container) return true;
|
|
741
|
+
}
|
|
742
|
+
return false;
|
|
743
|
+
},
|
|
744
|
+
|
|
745
|
+
// attribute value
|
|
746
|
+
// @return string
|
|
747
|
+
getAttribute = !BUGGY_GET_ATTRIBUTE ?
|
|
748
|
+
function(node, attribute) {
|
|
749
|
+
return node.getAttribute(attribute) || '';
|
|
750
|
+
} :
|
|
751
|
+
function(node, attribute) {
|
|
752
|
+
attribute = attribute.toLowerCase();
|
|
753
|
+
if (ATTR_DEFAULT[attribute] in node) {
|
|
754
|
+
return node[ATTR_DEFAULT[attribute]] || '';
|
|
755
|
+
}
|
|
756
|
+
return (
|
|
757
|
+
// specific URI data attributes (parameter 2 to fix IE bug)
|
|
758
|
+
ATTR_URIDATA[attribute] ? node.getAttribute(attribute, 2) || '' :
|
|
759
|
+
// boolean attributes should return name instead of true/false
|
|
760
|
+
ATTR_BOOLEAN[attribute] ? node.getAttribute(attribute) ? attribute : '' :
|
|
761
|
+
((node = node.getAttributeNode(attribute)) && node.value) || '');
|
|
762
|
+
},
|
|
763
|
+
|
|
764
|
+
// attribute presence
|
|
765
|
+
// @return boolean
|
|
766
|
+
hasAttribute = !BUGGY_HAS_ATTRIBUTE ?
|
|
767
|
+
function(node, attribute) {
|
|
768
|
+
return node.hasAttribute(attribute);
|
|
769
|
+
} :
|
|
770
|
+
function(node, attribute) {
|
|
771
|
+
attribute = attribute.toLowerCase();
|
|
772
|
+
// older IE engines requires DOM mapping
|
|
773
|
+
// see NetFront/Playstation as an example
|
|
774
|
+
attribute = attribute in ATTR_MAPPING ?
|
|
775
|
+
ATTR_MAPPING[attribute] : attribute;
|
|
776
|
+
if (ATTR_DEFAULT[attribute] in node) {
|
|
777
|
+
return !!node[ATTR_DEFAULT[attribute]];
|
|
778
|
+
}
|
|
779
|
+
// need to get at AttributeNode first on IE
|
|
780
|
+
node = node.getAttributeNode(attribute);
|
|
781
|
+
// use both "specified" & "nodeValue" properties
|
|
782
|
+
return !!(node && (node.specified || node.nodeValue));
|
|
783
|
+
},
|
|
784
|
+
|
|
785
|
+
// check node emptyness
|
|
786
|
+
isEmpty =
|
|
787
|
+
function(node) {
|
|
788
|
+
node = node.firstChild;
|
|
789
|
+
while (node) {
|
|
790
|
+
if (node.nodeType == 3 || node.nodeName > '@') return false;
|
|
791
|
+
node = node.nextSibling;
|
|
792
|
+
}
|
|
793
|
+
return true;
|
|
794
|
+
},
|
|
795
|
+
|
|
796
|
+
// check if element matches the :link pseudo
|
|
797
|
+
// @return boolean
|
|
798
|
+
isLink =
|
|
799
|
+
function(element) {
|
|
800
|
+
return hasAttribute(element,'href') && LINK_NODES[element.nodeName];
|
|
801
|
+
},
|
|
802
|
+
|
|
803
|
+
// child position by nodeType
|
|
804
|
+
// @return number
|
|
805
|
+
nthElement =
|
|
806
|
+
function(element, last) {
|
|
807
|
+
var count = 1, succ = last ? 'nextSibling' : 'previousSibling';
|
|
808
|
+
while ((element = element[succ])) {
|
|
809
|
+
if (element.nodeName > '@') ++count;
|
|
810
|
+
}
|
|
811
|
+
return count;
|
|
812
|
+
},
|
|
813
|
+
|
|
814
|
+
// child position by nodeName
|
|
815
|
+
// @return number
|
|
816
|
+
nthOfType =
|
|
817
|
+
function(element, last) {
|
|
818
|
+
var count = 1, succ = last ? 'nextSibling' : 'previousSibling', type = element.nodeName;
|
|
819
|
+
while ((element = element[succ])) {
|
|
820
|
+
if (element.nodeName == type) ++count;
|
|
821
|
+
}
|
|
822
|
+
return count;
|
|
823
|
+
},
|
|
824
|
+
|
|
825
|
+
/*------------------------------- DEBUGGING --------------------------------*/
|
|
826
|
+
|
|
827
|
+
// compile selectors to ad-hoc functions resolvers
|
|
828
|
+
// @selector string
|
|
829
|
+
// @mode boolean
|
|
830
|
+
// false = select resolvers
|
|
831
|
+
// true = match resolvers
|
|
832
|
+
compile =
|
|
833
|
+
function(selector, mode) {
|
|
834
|
+
return compileGroup(selector, '', mode || false);
|
|
835
|
+
},
|
|
836
|
+
|
|
837
|
+
// set working mode
|
|
838
|
+
configure =
|
|
839
|
+
function(options) {
|
|
840
|
+
for (var i in options) {
|
|
841
|
+
if (i == 'VERBOSITY') {
|
|
842
|
+
VERBOSITY = !!options[i];
|
|
843
|
+
} else if (i == 'SIMPLENOT') {
|
|
844
|
+
SIMPLENOT = !!options[i];
|
|
845
|
+
HTMLResolvers = { };
|
|
846
|
+
XMLResolvers = { };
|
|
847
|
+
HTMLMatchers = { };
|
|
848
|
+
XMLMatchers = { };
|
|
849
|
+
USE_QSAPI = false;
|
|
850
|
+
reValidator = new RegExp(extendedValidator, 'g');
|
|
851
|
+
} else if (i == 'SHORTCUTS') {
|
|
852
|
+
SHORTCUTS = !!options[i];
|
|
853
|
+
} else if (i == 'USE_QSAPI') {
|
|
854
|
+
USE_QSAPI = !!options[i] && NATIVE_QSAPI;
|
|
855
|
+
reValidator = new RegExp(standardValidator, 'g');
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
},
|
|
859
|
+
|
|
860
|
+
// control user notifications
|
|
861
|
+
emit =
|
|
862
|
+
function(message) {
|
|
863
|
+
if (VERBOSITY) {
|
|
864
|
+
// FF/Safari/Opera DOMException.SYNTAX_ERR = 12
|
|
865
|
+
if (typeof global.DOMException !== 'undefined') {
|
|
866
|
+
var err = new Error();
|
|
867
|
+
err.name = 'SYNTAX_ERR';
|
|
868
|
+
err.message = '(Selectors) ' + message;
|
|
869
|
+
err.code = 12;
|
|
870
|
+
throw err;
|
|
871
|
+
} else {
|
|
872
|
+
throw new Error(12, 'SYNTAX_ERR: (Selectors) ' + message);
|
|
873
|
+
}
|
|
874
|
+
} else {
|
|
875
|
+
var console = global.console;
|
|
876
|
+
if (console && console.log) {
|
|
877
|
+
console.log(message);
|
|
878
|
+
} else {
|
|
879
|
+
if (/exception/i.test(message)) {
|
|
880
|
+
global.status = message;
|
|
881
|
+
global.defaultStatus = message;
|
|
882
|
+
} else {
|
|
883
|
+
global.status += message;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
},
|
|
888
|
+
|
|
889
|
+
// by default disable complex selectors nested in
|
|
890
|
+
// ':not()' pseudo-classes, as for specifications
|
|
891
|
+
SIMPLENOT = true,
|
|
892
|
+
|
|
893
|
+
// by default do not add missing left/right context
|
|
894
|
+
// to selector string shortcuts like "+div" or "ul>"
|
|
895
|
+
SHORTCUTS = false,
|
|
896
|
+
|
|
897
|
+
// controls the engine error/warning notifications
|
|
898
|
+
VERBOSITY = true,
|
|
899
|
+
|
|
900
|
+
// controls enabling the Query Selector API branch
|
|
901
|
+
USE_QSAPI = NATIVE_QSAPI,
|
|
902
|
+
|
|
903
|
+
/*---------------------------- COMPILER METHODS ----------------------------*/
|
|
904
|
+
|
|
905
|
+
// do not change this, it is searched & replaced
|
|
906
|
+
// in multiple places to build compiled functions
|
|
907
|
+
ACCEPT_NODE = 'f&&f(c[k]);r[r.length]=c[k];continue main;',
|
|
908
|
+
|
|
909
|
+
// checks if nodeName comparisons need to be uppercased
|
|
910
|
+
TO_UPPER_CASE = doc.createElement('nAv').nodeName == 'nAv' ?
|
|
911
|
+
'.toUpperCase()' : '',
|
|
912
|
+
|
|
913
|
+
// compile a comma separated group of selector
|
|
914
|
+
// @mode boolean true for select, false for match
|
|
915
|
+
// return a compiled function
|
|
916
|
+
compileGroup =
|
|
917
|
+
function(selector, source, mode) {
|
|
918
|
+
|
|
919
|
+
var i = -1, seen = { }, token,
|
|
920
|
+
parts = typeof selector == 'string' ?
|
|
921
|
+
selector.match(reSplitGroup) : selector;
|
|
922
|
+
|
|
923
|
+
// for each selector in the group
|
|
924
|
+
while ((token = parts[++i])) {
|
|
925
|
+
token = token.replace(reTrimSpaces, '');
|
|
926
|
+
// avoid repeating the same token
|
|
927
|
+
// in comma separated group (p, p)
|
|
928
|
+
if (!seen[token]) {
|
|
929
|
+
seen[token] = true;
|
|
930
|
+
source += (i > 0 ? (mode ? 'e=c[k];': 'e=k;') : '') +
|
|
931
|
+
compileSelector(token, mode ? ACCEPT_NODE : 'f&&f(k);return true;');
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
if (mode) {
|
|
936
|
+
// for select method
|
|
937
|
+
return new Function('c,s,r,d,h,g,f',
|
|
938
|
+
'var N,n,x=0,k=-1,e;main:while(e=c[++k]){' + source + '}return r;');
|
|
939
|
+
} else {
|
|
940
|
+
// for match method
|
|
941
|
+
return new Function('e,s,r,d,h,g,f',
|
|
942
|
+
'var N,n,x=0,k=e;' + source + 'return false;');
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
|
|
946
|
+
// compile a CSS3 string selector into ad-hoc javascript matching function
|
|
947
|
+
// @return string (to be compiled)
|
|
948
|
+
compileSelector =
|
|
949
|
+
function(selector, source) {
|
|
950
|
+
|
|
951
|
+
var i, a, b, n, k, expr, match, result, status, test, type;
|
|
952
|
+
|
|
953
|
+
k = 0;
|
|
954
|
+
|
|
955
|
+
while (selector) {
|
|
956
|
+
|
|
957
|
+
// *** Universal selector
|
|
958
|
+
// * match all (empty block, do not remove)
|
|
959
|
+
if ((match = selector.match(Patterns.universal))) {
|
|
960
|
+
// do nothing, handled in the compiler where
|
|
961
|
+
// BUGGY_GEBTN return comment nodes (ex: IE)
|
|
962
|
+
i = true;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// *** ID selector
|
|
966
|
+
// #Foo Id case sensitive
|
|
967
|
+
else if ((match = selector.match(Patterns.id))) {
|
|
968
|
+
// document can contain conflicting elements (id/name)
|
|
969
|
+
// prototype selector unit need this method to recover bad HTML forms
|
|
970
|
+
source = 'if(' + (isXMLDocument ?
|
|
971
|
+
's.getAttribute(e,"id")' :
|
|
972
|
+
'(e.submit?s.getAttribute(e,"id"):e.id)') +
|
|
973
|
+
'=="' + match[1] + '"' +
|
|
974
|
+
'){' + source + '}';
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// *** Type selector
|
|
978
|
+
// Foo Tag (case insensitive)
|
|
979
|
+
else if ((match = selector.match(Patterns.tagName))) {
|
|
980
|
+
// both tagName and nodeName properties may be upper/lower case
|
|
981
|
+
// depending on their creation NAMESPACE in createElementNS()
|
|
982
|
+
source = 'if(e.nodeName' + (isXMLDocument ?
|
|
983
|
+
'=="' + match[1] + '"' : TO_UPPER_CASE +
|
|
984
|
+
'=="' + match[1].toUpperCase() + '"') +
|
|
985
|
+
'){' + source + '}';
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// *** Class selector
|
|
989
|
+
// .Foo Class (case sensitive)
|
|
990
|
+
else if ((match = selector.match(Patterns.className))) {
|
|
991
|
+
// W3C CSS3 specs: element whose "class" attribute has been assigned a
|
|
992
|
+
// list of whitespace-separated values, see section 6.4 Class selectors
|
|
993
|
+
// and notes at the bottom; explicitly non-normative in this specification.
|
|
994
|
+
source = 'if((n=' + (isXMLDocument ?
|
|
995
|
+
's.getAttribute(e,"class")' : 'e.className') +
|
|
996
|
+
')&&n.length&&(" "+' + (isQuirksMode ? 'n.toLowerCase()' : 'n') +
|
|
997
|
+
'.replace(' + reWhiteSpace + '," ")+" ").indexOf(" ' +
|
|
998
|
+
(isQuirksMode ? match[1].toLowerCase() : match[1]) + ' ")>-1' +
|
|
999
|
+
'){' + source + '}';
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// *** Attribute selector
|
|
1003
|
+
// [attr] [attr=value] [attr="value"] [attr='value'] and !=, *=, ~=, |=, ^=, $=
|
|
1004
|
+
// case sensitivity is treated differently depending on the document type (see map)
|
|
1005
|
+
else if ((match = selector.match(Patterns.attribute))) {
|
|
1006
|
+
if (match[3]) match[3] = match[3].replace(/^\x22|\x22$/g, '').replace(/^\x27|\x27$/g, '');
|
|
1007
|
+
|
|
1008
|
+
// xml namespaced attribute ?
|
|
1009
|
+
expr = match[1].split(':');
|
|
1010
|
+
expr = expr.length == 2 ? expr[1] : expr[0] + '';
|
|
1011
|
+
|
|
1012
|
+
if (match[2] && !Operators[match[2]]) {
|
|
1013
|
+
emit('Unsupported operator in attribute selectors "' + selector + '"');
|
|
1014
|
+
return '';
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
// replace Operators parameter if needed
|
|
1018
|
+
if (match[2] && match[3] && (type = Operators[match[2]])) {
|
|
1019
|
+
// case treatment depends on document
|
|
1020
|
+
HTML_TABLE['class'] = isQuirksMode ? 1 : 0;
|
|
1021
|
+
// replace escaped values and HTML entities
|
|
1022
|
+
match[3] = match[3].replace(/\\([0-9a-f]{2,2})/, '\\x$1');
|
|
1023
|
+
test = (isXMLDocument ? XHTML_TABLE : HTML_TABLE)[expr.toLowerCase()];
|
|
1024
|
+
type = type.replace(/\%m/g, test ? match[3].toLowerCase() : match[3]);
|
|
1025
|
+
} else {
|
|
1026
|
+
test = false;
|
|
1027
|
+
// handle empty values
|
|
1028
|
+
type = match[2] == '=' ? 'n==""' : 'false';
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// build expression for has/getAttribute
|
|
1032
|
+
expr = 'n=s.' + (match[2] ? 'get' : 'has') +
|
|
1033
|
+
'Attribute(e,"' + match[1] + '")' +
|
|
1034
|
+
(test ? '.toLowerCase();' : ';');
|
|
1035
|
+
|
|
1036
|
+
source = expr + 'if(' + (match[2] ? type : 'n') + '){' + source + '}';
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// *** Adjacent sibling combinator
|
|
1040
|
+
// E + F (F adiacent sibling of E)
|
|
1041
|
+
else if ((match = selector.match(Patterns.adjacent))) {
|
|
1042
|
+
k++;
|
|
1043
|
+
source = NATIVE_TRAVERSAL_API ?
|
|
1044
|
+
'var N' + k + '=e;if(e&&(e=e.previousElementSibling)){' + source + '}e=N' + k + ';' :
|
|
1045
|
+
'var N' + k + '=e;while(e&&(e=e.previousSibling)){if(e.nodeName>"@"){' + source + 'break;}}e=N' + k + ';';
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// *** General sibling combinator
|
|
1049
|
+
// E ~ F (F relative sibling of E)
|
|
1050
|
+
else if ((match = selector.match(Patterns.relative))) {
|
|
1051
|
+
k++;
|
|
1052
|
+
source = NATIVE_TRAVERSAL_API ?
|
|
1053
|
+
('var N' + k + '=e;e=e.parentNode.firstElementChild;' +
|
|
1054
|
+
'while(e&&e!=N' + k + '){' + source + 'e=e.nextElementSibling;}e=N' + k + ';') :
|
|
1055
|
+
('var N' + k + '=e;e=e.parentNode.firstChild;' +
|
|
1056
|
+
'while(e&&e!=N' + k + '){if(e.nodeName>"@"){' + source + '}e=e.nextSibling;}e=N' + k + ';');
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// *** Child combinator
|
|
1060
|
+
// E > F (F children of E)
|
|
1061
|
+
else if ((match = selector.match(Patterns.children))) {
|
|
1062
|
+
k++;
|
|
1063
|
+
source = 'var N' + k + '=e;if(e&&e!==h&&e!==g&&(e=e.parentNode)){' + source + '}e=N' + k + ';';
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
// *** Descendant combinator
|
|
1067
|
+
// E F (E ancestor of F)
|
|
1068
|
+
else if ((match = selector.match(Patterns.ancestor))) {
|
|
1069
|
+
k++;
|
|
1070
|
+
source = 'var N' + k + '=e;while(e&&e!==h&&e!==g&&(e=e.parentNode)){' + source + '}e=N' + k + ';';
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
// *** Structural pseudo-classes
|
|
1074
|
+
// :root, :empty,
|
|
1075
|
+
// :first-child, :last-child, :only-child,
|
|
1076
|
+
// :first-of-type, :last-of-type, :only-of-type,
|
|
1077
|
+
// :nth-child(), :nth-last-child(), :nth-of-type(), :nth-last-of-type()
|
|
1078
|
+
else if ((match = selector.match(Patterns.spseudos)) &&
|
|
1079
|
+
CSS3PseudoClasses.Structural[selector.match(reClassValue)[0]]) {
|
|
1080
|
+
|
|
1081
|
+
switch (match[1]) {
|
|
1082
|
+
case 'root':
|
|
1083
|
+
// element root of the document
|
|
1084
|
+
if (match[6]) {
|
|
1085
|
+
source = 'if(s.contains(e.ownerDocument.documentElement,e)){' + source + '}';
|
|
1086
|
+
} else {
|
|
1087
|
+
source = 'if(e===h){' + source + '}';
|
|
1088
|
+
}
|
|
1089
|
+
break;
|
|
1090
|
+
|
|
1091
|
+
case 'empty':
|
|
1092
|
+
// element that has no children
|
|
1093
|
+
source = 'if(s.isEmpty(e)){' + source + '}';
|
|
1094
|
+
break;
|
|
1095
|
+
|
|
1096
|
+
default:
|
|
1097
|
+
if (match[1] && match[5]) {
|
|
1098
|
+
if (match[5] == 'n') {
|
|
1099
|
+
source = 'if(e!==h){' + source + '}';
|
|
1100
|
+
break;
|
|
1101
|
+
} else if (match[5] == 'even') {
|
|
1102
|
+
a = 2;
|
|
1103
|
+
b = 0;
|
|
1104
|
+
} else if (match[5] == 'odd') {
|
|
1105
|
+
a = 2;
|
|
1106
|
+
b = 1;
|
|
1107
|
+
} else {
|
|
1108
|
+
// assumes correct "an+b" format, "b" before "a" to keep "n" values
|
|
1109
|
+
b = ((n = match[5].match(/(-?\d+)$/)) ? parseInt(n[1], 10) : 0);
|
|
1110
|
+
a = ((n = match[5].match(/(-?\d*)n/)) ? parseInt(n[1], 10) : 0);
|
|
1111
|
+
if (n && n[1] == '-') a = -1;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
// build test expression out of structural pseudo (an+b) parameters
|
|
1115
|
+
// see here: http://www.w3.org/TR/css3-selectors/#nth-child-pseudo
|
|
1116
|
+
test = b < 1 && a > 1 ? '(n-(' + b + '))%' + a + '==0' : a > +1 ?
|
|
1117
|
+
(match[2] == 'last') ? '(n-(' + b + '))%' + a + '==0' :
|
|
1118
|
+
'n>=' + b + '&&(n-(' + b + '))%' + a + '==0' : a < -1 ?
|
|
1119
|
+
(match[2] == 'last') ? '(n-(' + b + '))%' + a + '==0' :
|
|
1120
|
+
'n<=' + b + '&&(n-(' + b + '))%' + a + '==0' : a=== 0 ?
|
|
1121
|
+
'n==' + b :
|
|
1122
|
+
(match[2] == 'last') ?
|
|
1123
|
+
a == -1 ? 'n>=' + b : 'n<=' + b :
|
|
1124
|
+
a == -1 ? 'n<=' + b : 'n>=' + b;
|
|
1125
|
+
|
|
1126
|
+
// 4 cases: 1 (nth) x 4 (child, of-type, last-child, last-of-type)
|
|
1127
|
+
source =
|
|
1128
|
+
'if(e!==h){' +
|
|
1129
|
+
'n=s[' + (match[4] ? '"nthOfType"' : '"nthElement"') + ']' +
|
|
1130
|
+
'(e,' + (match[2] == 'last' ? 'true' : 'false') + ');' +
|
|
1131
|
+
'if(' + test + '){' + source + '}' +
|
|
1132
|
+
'}';
|
|
1133
|
+
|
|
1134
|
+
} else {
|
|
1135
|
+
// 6 cases: 3 (first, last, only) x 1 (child) x 2 (-of-type)
|
|
1136
|
+
a = match[2] == 'first' ? 'previous' : 'next';
|
|
1137
|
+
n = match[2] == 'only' ? 'previous' : 'next';
|
|
1138
|
+
b = match[2] == 'first' || match[2] == 'last';
|
|
1139
|
+
|
|
1140
|
+
type = match[4] ? '&&n.nodeName!=e.nodeName' : '&&n.nodeName<"@"';
|
|
1141
|
+
|
|
1142
|
+
source = 'if(e!==h){' +
|
|
1143
|
+
( 'n=e;while((n=n.' + a + 'Sibling)' + type + ');if(!n){' + (b ? source :
|
|
1144
|
+
'n=e;while((n=n.' + n + 'Sibling)' + type + ');if(!n){' + source + '}') + '}' ) + '}';
|
|
1145
|
+
}
|
|
1146
|
+
break;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// *** negation, user action and target pseudo-classes
|
|
1151
|
+
// *** UI element states and dynamic pseudo-classes
|
|
1152
|
+
// CSS3 :not, :checked, :enabled, :disabled, :target
|
|
1153
|
+
// CSS3 :active, :hover, :focus
|
|
1154
|
+
// CSS3 :link, :visited
|
|
1155
|
+
else if ((match = selector.match(Patterns.dpseudos)) &&
|
|
1156
|
+
CSS3PseudoClasses.Others[selector.match(reClassValue)[0]]) {
|
|
1157
|
+
|
|
1158
|
+
switch (match[1]) {
|
|
1159
|
+
// CSS3 negation pseudo-class
|
|
1160
|
+
case 'not':
|
|
1161
|
+
// compile nested selectors, DO NOT pass the callback parameter
|
|
1162
|
+
// SIMPLENOT allow disabling complex selectors nested
|
|
1163
|
+
// in ':not()' pseudo-classes, breaks some test units
|
|
1164
|
+
expr = match[3].replace(reTrimSpaces, '');
|
|
1165
|
+
|
|
1166
|
+
if (SIMPLENOT && !reSimpleNot.test(expr)) {
|
|
1167
|
+
// see above, log error but continue execution
|
|
1168
|
+
emit('Negation pseudo-class only accepts simple selectors "' + selector + '"');
|
|
1169
|
+
return '';
|
|
1170
|
+
} else {
|
|
1171
|
+
if ('compatMode' in doc) {
|
|
1172
|
+
source = 'if(!' + compileGroup(expr, '', false) + '(e,s,r,d,h,g)){' + source + '}';
|
|
1173
|
+
} else {
|
|
1174
|
+
source = 'if(!s.match(e, "' + expr.replace(/\x22/g, '\\"') + '",r)){' + source +'}';
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
break;
|
|
1178
|
+
|
|
1179
|
+
// CSS3 UI element states
|
|
1180
|
+
case 'checked':
|
|
1181
|
+
// only available for radio buttons and checkboxes
|
|
1182
|
+
source = 'if(typeof e.form!=="undefined"&&(/radio|checkbox/i).test(e.type)&&e.checked){' + source + '}';
|
|
1183
|
+
break;
|
|
1184
|
+
case 'disabled':
|
|
1185
|
+
// does not consider hidden input fields
|
|
1186
|
+
source = 'if(((typeof e.form!=="undefined"&&!(/hidden/i).test(e.type))||s.isLink(e))&&e.disabled){' + source + '}';
|
|
1187
|
+
break;
|
|
1188
|
+
case 'enabled':
|
|
1189
|
+
// does not consider hidden input fields
|
|
1190
|
+
source = 'if(((typeof e.form!=="undefined"&&!(/hidden/i).test(e.type))||s.isLink(e))&&!e.disabled){' + source + '}';
|
|
1191
|
+
break;
|
|
1192
|
+
|
|
1193
|
+
// CSS3 lang pseudo-class
|
|
1194
|
+
case 'lang':
|
|
1195
|
+
test = '';
|
|
1196
|
+
if (match[3]) test = match[3].substr(0, 2) + '-';
|
|
1197
|
+
source = 'do{(n=e.lang||"").toLowerCase();' +
|
|
1198
|
+
'if((n==""&&h.lang=="' + match[3].toLowerCase() + '")||' +
|
|
1199
|
+
'(n&&(n=="' + match[3].toLowerCase() +
|
|
1200
|
+
'"||n.substr(0,3)=="' + test.toLowerCase() + '")))' +
|
|
1201
|
+
'{' + source + 'break;}}while((e=e.parentNode)&&e!==g);';
|
|
1202
|
+
break;
|
|
1203
|
+
|
|
1204
|
+
// CSS3 target pseudo-class
|
|
1205
|
+
case 'target':
|
|
1206
|
+
n = doc.location ? doc.location.hash : '';
|
|
1207
|
+
if (n) {
|
|
1208
|
+
source = 'if(e.id=="' + n.slice(1) + '"){' + source + '}';
|
|
1209
|
+
}
|
|
1210
|
+
break;
|
|
1211
|
+
|
|
1212
|
+
// CSS3 dynamic pseudo-classes
|
|
1213
|
+
case 'link':
|
|
1214
|
+
source = 'if(s.isLink(e)&&!e.visited){' + source + '}';
|
|
1215
|
+
break;
|
|
1216
|
+
case 'visited':
|
|
1217
|
+
source = 'if(s.isLink(e)&&e.visited){' + source + '}';
|
|
1218
|
+
break;
|
|
1219
|
+
|
|
1220
|
+
// CSS3 user action pseudo-classes IE & FF3 have native support
|
|
1221
|
+
// these capabilities may be emulated by some event managers
|
|
1222
|
+
case 'active':
|
|
1223
|
+
if (isXMLDocument) break;
|
|
1224
|
+
source = 'if(e===d.activeElement){' + source + '}';
|
|
1225
|
+
break;
|
|
1226
|
+
case 'hover':
|
|
1227
|
+
if (isXMLDocument) break;
|
|
1228
|
+
source = 'if(e===d.hoverElement){' + source + '}';
|
|
1229
|
+
break;
|
|
1230
|
+
case 'focus':
|
|
1231
|
+
if (isXMLDocument) break;
|
|
1232
|
+
source = NATIVE_FOCUS ?
|
|
1233
|
+
'if(e===d.activeElement&&d.hasFocus()&&(e.type||e.href)){' + source + '}' :
|
|
1234
|
+
'if(e===d.activeElement&&(e.type||e.href)){' + source + '}';
|
|
1235
|
+
break;
|
|
1236
|
+
|
|
1237
|
+
// CSS2 selected pseudo-classes, not part of current CSS3 drafts
|
|
1238
|
+
// the 'selected' property is only available for option elements
|
|
1239
|
+
case 'selected':
|
|
1240
|
+
// fix Safari selectedIndex property bug
|
|
1241
|
+
expr = BUGGY_SELECTED ? '||(n=e.parentNode)&&n.options[n.selectedIndex]===e' : '';
|
|
1242
|
+
source = 'if(e.nodeName=="OPTION"&&(e.selected' + expr + ')){' + source + '}';
|
|
1243
|
+
break;
|
|
1244
|
+
|
|
1245
|
+
default:
|
|
1246
|
+
break;
|
|
1247
|
+
}
|
|
1248
|
+
} else {
|
|
1249
|
+
|
|
1250
|
+
// this is where external extensions are
|
|
1251
|
+
// invoked if expressions match selectors
|
|
1252
|
+
expr = false;
|
|
1253
|
+
status = true;
|
|
1254
|
+
|
|
1255
|
+
for (expr in Selectors) {
|
|
1256
|
+
if ((match = selector.match(Selectors[expr].Expression))) {
|
|
1257
|
+
result = Selectors[expr].Callback(match, source);
|
|
1258
|
+
source = result.source;
|
|
1259
|
+
status = result.status;
|
|
1260
|
+
if (status) break;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
// if an extension fails to parse the selector
|
|
1265
|
+
// it must return a false boolean in "status"
|
|
1266
|
+
if (!status) {
|
|
1267
|
+
// log error but continue execution, don't throw real exceptions
|
|
1268
|
+
// because blocking following processes maybe is not a good idea
|
|
1269
|
+
emit('Unknown pseudo-class selector "' + selector + '"');
|
|
1270
|
+
return '';
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
if (!expr) {
|
|
1274
|
+
// see above, log error but continue execution
|
|
1275
|
+
emit('Unknown token in selector "' + selector + '"');
|
|
1276
|
+
return '';
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
// error if no matches found by the pattern scan
|
|
1282
|
+
if (!match) {
|
|
1283
|
+
emit('Invalid syntax in selector "' + selector + '"');
|
|
1284
|
+
return '';
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// ensure "match" is not null or empty since
|
|
1288
|
+
// we do not throw real DOMExceptions above
|
|
1289
|
+
selector = match && match[match.length - 1];
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
return source;
|
|
1293
|
+
},
|
|
1294
|
+
|
|
1295
|
+
/*----------------------------- QUERY METHODS ------------------------------*/
|
|
1296
|
+
|
|
1297
|
+
// match element with selector
|
|
1298
|
+
// @return boolean
|
|
1299
|
+
match =
|
|
1300
|
+
function(element, selector, from, callback) {
|
|
1301
|
+
|
|
1302
|
+
var changed, parts, resolver;
|
|
1303
|
+
|
|
1304
|
+
// ensures a valid element node was passed
|
|
1305
|
+
if (!(element && element.nodeName > '@')) {
|
|
1306
|
+
emit("Invalid element argument");
|
|
1307
|
+
return false;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
// ensures a valid selector string was passed
|
|
1311
|
+
if (!selector || typeof selector != 'string') {
|
|
1312
|
+
emit("Invalid selector argument");
|
|
1313
|
+
return false;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
// if passed, check context contains element
|
|
1317
|
+
if (from && from.nodeType == 1) {
|
|
1318
|
+
if (!contains(from, element)) return false;
|
|
1319
|
+
} else if (from) {
|
|
1320
|
+
emit("Invalid context argument");
|
|
1321
|
+
return false;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
selector = selector.replace(reTrimSpaces, '');
|
|
1325
|
+
|
|
1326
|
+
// ensure context is set
|
|
1327
|
+
from || (from = doc);
|
|
1328
|
+
|
|
1329
|
+
// extract context if changed
|
|
1330
|
+
if (lastMatchContext != from) {
|
|
1331
|
+
// save passed context
|
|
1332
|
+
lastMatchContext = from;
|
|
1333
|
+
// reference element ownerDocument and document root (HTML)
|
|
1334
|
+
root = (doc = element.ownerDocument || element).documentElement;
|
|
1335
|
+
isQuirksMode = isQuirks(doc);
|
|
1336
|
+
isXMLDocument = isXML(doc);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
if (changed = lastMatcher != selector) {
|
|
1340
|
+
// process valid selector strings
|
|
1341
|
+
if ((parts = selector.match(reValidator)) && parts[0] == selector) {
|
|
1342
|
+
// save passed selector
|
|
1343
|
+
lastMatcher = selector;
|
|
1344
|
+
isSingleMatch = (parts = selector.match(reSplitGroup)).length < 2;
|
|
1345
|
+
} else {
|
|
1346
|
+
emit('The string "' + selector + '", is not a valid CSS selector');
|
|
1347
|
+
return false;
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// use matchesSelector API if available
|
|
1352
|
+
if (USE_QSAPI && element[NATIVE_MATCHES_SELECTOR] &&
|
|
1353
|
+
!(BUGGY_PSEUDOS && RE_PSEUDOS.test(selector)) &&
|
|
1354
|
+
!RE_BUGGY_QSAPI.test(selector)) {
|
|
1355
|
+
try {
|
|
1356
|
+
if (element[NATIVE_MATCHES_SELECTOR](selector)) {
|
|
1357
|
+
if (typeof callback == 'function') {
|
|
1358
|
+
callback(element);
|
|
1359
|
+
}
|
|
1360
|
+
return true;
|
|
1361
|
+
}
|
|
1362
|
+
return false;
|
|
1363
|
+
} catch(e) { }
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
// compile matcher resolver if necessary
|
|
1367
|
+
resolver = (isXMLDocument && XMLMatchers[selector]) ?
|
|
1368
|
+
XMLMatchers[selector] : HTMLMatchers[selector] ?
|
|
1369
|
+
HTMLMatchers[selector] : (isXMLDocument ?
|
|
1370
|
+
XMLMatchers : HTMLMatchers)[selector] = isSingleMatch ?
|
|
1371
|
+
new Function('e,s,r,d,h,g,f', 'var N,n,x=0,k=e;' +
|
|
1372
|
+
compileSelector(selector, 'f&&f(k);return true;') + 'return false;') :
|
|
1373
|
+
compileGroup(parts || selector, '', false);
|
|
1374
|
+
|
|
1375
|
+
return resolver(element, snap, [ ], doc, root, from || doc, callback);
|
|
1376
|
+
},
|
|
1377
|
+
|
|
1378
|
+
// select elements matching selector
|
|
1379
|
+
// using new Query Selector API
|
|
1380
|
+
// or cross-browser client API
|
|
1381
|
+
// @return array
|
|
1382
|
+
select =
|
|
1383
|
+
function(selector, from, callback) {
|
|
1384
|
+
|
|
1385
|
+
var i, changed, element, elements, parts, resolver, token;
|
|
1386
|
+
|
|
1387
|
+
if (arguments.length === 0) {
|
|
1388
|
+
emit('Missing required selector parameters');
|
|
1389
|
+
return [ ];
|
|
1390
|
+
} else if (selector === '') {
|
|
1391
|
+
emit('Empty selector string');
|
|
1392
|
+
return [ ];
|
|
1393
|
+
} else if (typeof selector != 'string') {
|
|
1394
|
+
// QSA capable browsers do not throw
|
|
1395
|
+
return [ ];
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
// ensure context is set
|
|
1399
|
+
from || (from = doc);
|
|
1400
|
+
|
|
1401
|
+
if (RE_SIMPLE_SELECTOR.test(selector)) {
|
|
1402
|
+
switch (selector.charAt(0)) {
|
|
1403
|
+
case '#':
|
|
1404
|
+
if ((element = byId(selector.slice(1), from))) {
|
|
1405
|
+
callback && callback(element);
|
|
1406
|
+
return [ element ];
|
|
1407
|
+
}
|
|
1408
|
+
return [ ];
|
|
1409
|
+
case '.':
|
|
1410
|
+
elements = byClass(selector.slice(1), from);
|
|
1411
|
+
break;
|
|
1412
|
+
default:
|
|
1413
|
+
elements = byTag(selector, from);
|
|
1414
|
+
break;
|
|
1415
|
+
}
|
|
1416
|
+
return callback ?
|
|
1417
|
+
concatCall([ ], elements, callback) : elements;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
if (USE_QSAPI && !RE_BUGGY_QSAPI.test(selector) &&
|
|
1421
|
+
QSA_NODE_TYPES[from.nodeType]) {
|
|
1422
|
+
|
|
1423
|
+
// clear error state
|
|
1424
|
+
lastError = null;
|
|
1425
|
+
|
|
1426
|
+
try {
|
|
1427
|
+
elements = from.querySelectorAll(selector);
|
|
1428
|
+
} catch(e) {
|
|
1429
|
+
// remember last error
|
|
1430
|
+
lastError = e;
|
|
1431
|
+
if (selector === '') throw e;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
if (elements) {
|
|
1435
|
+
switch (elements.length) {
|
|
1436
|
+
case 0:
|
|
1437
|
+
return [ ];
|
|
1438
|
+
case 1:
|
|
1439
|
+
element = elements.item(0);
|
|
1440
|
+
callback && callback(element);
|
|
1441
|
+
return [ element ];
|
|
1442
|
+
default:
|
|
1443
|
+
return callback ?
|
|
1444
|
+
concatCall([ ], elements, callback) :
|
|
1445
|
+
NATIVE_SLICE_PROTO ?
|
|
1446
|
+
slice.call(elements) :
|
|
1447
|
+
concatList([ ], elements);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
selector = selector.replace(reTrimSpaces, '');
|
|
1453
|
+
|
|
1454
|
+
if (SHORTCUTS) {
|
|
1455
|
+
// add left context if missing
|
|
1456
|
+
if (reLeftContext.test(selector)) {
|
|
1457
|
+
selector = from.nodeType == 9 ? '* ' + selector :
|
|
1458
|
+
from.id ? '#' + from.id + ' ' + selector :
|
|
1459
|
+
selector;
|
|
1460
|
+
}
|
|
1461
|
+
// add right context if missing
|
|
1462
|
+
if (reRightContext.test(selector)) {
|
|
1463
|
+
selector = selector + ' *';
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// extract context if changed
|
|
1468
|
+
if (lastSelectContext != from) {
|
|
1469
|
+
// save passed context
|
|
1470
|
+
lastSelectContext = from;
|
|
1471
|
+
// reference context ownerDocument and document root (HTML)
|
|
1472
|
+
root = (doc = from.ownerDocument || from).documentElement;
|
|
1473
|
+
isQuirksMode = isQuirks(doc);
|
|
1474
|
+
isXMLDocument = isXML(doc);
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
if (changed = lastSelector != selector) {
|
|
1478
|
+
// process valid selector strings
|
|
1479
|
+
if ((parts = selector.match(reValidator)) && parts[0] == selector) {
|
|
1480
|
+
// save passed selector
|
|
1481
|
+
lastSelector = selector;
|
|
1482
|
+
isSingleSelect = (parts = selector.match(reSplitGroup)).length < 2;
|
|
1483
|
+
} else {
|
|
1484
|
+
emit('The string "' + selector + '", is not a valid CSS selector');
|
|
1485
|
+
return [ ];
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
// commas separators are treated sequentially to maintain order
|
|
1490
|
+
if (isSingleSelect && from.nodeType != 11) {
|
|
1491
|
+
|
|
1492
|
+
if (changed) {
|
|
1493
|
+
// get right most selector token
|
|
1494
|
+
parts = selector.match(reSplitToken);
|
|
1495
|
+
token = parts[parts.length - 1];
|
|
1496
|
+
|
|
1497
|
+
// position where token was found
|
|
1498
|
+
lastPosition = selector.length - token.length;
|
|
1499
|
+
|
|
1500
|
+
// only last slice before :not rules
|
|
1501
|
+
lastSlice = token.split(':not')[0];
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
// ID optimization RTL, to reduce number of elements to visit
|
|
1505
|
+
if ((parts = lastSlice.match(Optimize.ID)) && (token = parts[1])) {
|
|
1506
|
+
if ((element = byId(token, from))) {
|
|
1507
|
+
if (match(element, selector)) {
|
|
1508
|
+
callback && callback(element);
|
|
1509
|
+
return [ element ];
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return [ ];
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
// ID optimization LTR, to reduce selection context searches
|
|
1516
|
+
else if ((parts = selector.match(Optimize.ID)) && (token = parts[1])) {
|
|
1517
|
+
if ((element = byId(token, doc))) {
|
|
1518
|
+
if ('#' + token == selector) {
|
|
1519
|
+
callback && callback(element);
|
|
1520
|
+
return [ element ];
|
|
1521
|
+
}
|
|
1522
|
+
if (/[>+~]/.test(selector)) {
|
|
1523
|
+
from = element.parentNode;
|
|
1524
|
+
} else {
|
|
1525
|
+
selector = selector.replace('#' + token, '*');
|
|
1526
|
+
lastPosition -= token.length + 1;
|
|
1527
|
+
from = element;
|
|
1528
|
+
}
|
|
1529
|
+
} else return [ ];
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
if (!NATIVE_GEBCN && (parts = lastSlice.match(Optimize.TAG)) && (token = parts[1])) {
|
|
1533
|
+
if ((elements = byTag(token, from)).length === 0) { return [ ]; }
|
|
1534
|
+
selector = selector.slice(0, lastPosition) + selector.slice(lastPosition).replace(token, '*');
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
else if ((parts = lastSlice.match(Optimize.CLASS)) && (token = parts[1])) {
|
|
1538
|
+
if ((elements = byClass(token, from)).length === 0) { return [ ]; }
|
|
1539
|
+
if (reOptimizeSelector.test(selector.charAt(selector.indexOf(token) - 1))) {
|
|
1540
|
+
selector = selector.slice(0, lastPosition) + selector.slice(lastPosition).replace('.' + token, '');
|
|
1541
|
+
} else {
|
|
1542
|
+
selector = selector.slice(0, lastPosition) + selector.slice(lastPosition).replace('.' + token, '*');
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
else if ((parts = selector.match(Optimize.CLASS)) && (token = parts[1])) {
|
|
1547
|
+
if ((elements = byClass(token, from)).length === 0) { return [ ]; }
|
|
1548
|
+
for (var z = 0, els = [ ]; elements.length > z; ++z) {
|
|
1549
|
+
els = concatList(els, elements[z].getElementsByTagName('*'));
|
|
1550
|
+
}
|
|
1551
|
+
elements = els;
|
|
1552
|
+
if (reOptimizeSelector.test(selector.charAt(selector.indexOf(token) - 1))) {
|
|
1553
|
+
selector = selector.slice(0, lastPosition) + selector.slice(lastPosition).replace('.' + token, '');
|
|
1554
|
+
} else {
|
|
1555
|
+
selector = selector.slice(0, lastPosition) + selector.slice(lastPosition).replace('.' + token, '*');
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
else if (NATIVE_GEBCN && (parts = lastSlice.match(Optimize.TAG)) && (token = parts[1])) {
|
|
1560
|
+
if ((elements = byTag(token, from)).length === 0) { return [ ]; }
|
|
1561
|
+
selector = selector.slice(0, lastPosition) + selector.slice(lastPosition).replace(token, '*');
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
if (!elements) {
|
|
1567
|
+
elements = byTag('*', from);
|
|
1568
|
+
}
|
|
1569
|
+
// end of prefiltering pass
|
|
1570
|
+
|
|
1571
|
+
// compile selector resolver if necessary
|
|
1572
|
+
resolver = (isXMLDocument && XMLResolvers[selector]) ?
|
|
1573
|
+
XMLResolvers[selector] : HTMLResolvers[selector] ?
|
|
1574
|
+
HTMLResolvers[selector] : (isXMLDocument ?
|
|
1575
|
+
XMLResolvers : HTMLResolvers)[selector] = isSingleSelect ?
|
|
1576
|
+
new Function('c,s,r,d,h,g,f', 'var N,n,x=0,k=-1,e;main:while(e=c[++k]){' +
|
|
1577
|
+
compileSelector(selector, ACCEPT_NODE) + '}return r;') :
|
|
1578
|
+
compileGroup(parts || selector, '', true);
|
|
1579
|
+
|
|
1580
|
+
return resolver(elements, snap, [ ], doc, root, from, callback);
|
|
1581
|
+
},
|
|
1582
|
+
|
|
1583
|
+
/*-------------------------------- STORAGE ---------------------------------*/
|
|
1584
|
+
|
|
1585
|
+
// compiled select functions returning collections
|
|
1586
|
+
HTMLResolvers = { },
|
|
1587
|
+
XMLResolvers = { },
|
|
1588
|
+
|
|
1589
|
+
// compiled match functions returning booleans
|
|
1590
|
+
HTMLMatchers = { },
|
|
1591
|
+
XMLMatchers = { },
|
|
1592
|
+
|
|
1593
|
+
// used to pass methods to compiled functions
|
|
1594
|
+
snap = {
|
|
1595
|
+
|
|
1596
|
+
// element indexing methods
|
|
1597
|
+
nthElement: nthElement,
|
|
1598
|
+
nthOfType: nthOfType,
|
|
1599
|
+
|
|
1600
|
+
// element inspection methods
|
|
1601
|
+
getAttribute: getAttribute,
|
|
1602
|
+
hasAttribute: hasAttribute,
|
|
1603
|
+
|
|
1604
|
+
// element selection methods
|
|
1605
|
+
byClass: byClass,
|
|
1606
|
+
byName: byName,
|
|
1607
|
+
byTag: byTag,
|
|
1608
|
+
byId: byId,
|
|
1609
|
+
|
|
1610
|
+
// helper/check methods
|
|
1611
|
+
contains: contains,
|
|
1612
|
+
isEmpty: isEmpty,
|
|
1613
|
+
isLink: isLink,
|
|
1614
|
+
|
|
1615
|
+
// selection/matching
|
|
1616
|
+
select: select,
|
|
1617
|
+
match: match
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1620
|
+
/*------------------------------- PUBLIC API -------------------------------*/
|
|
1621
|
+
|
|
1622
|
+
global.NW || (global.NW = { });
|
|
1623
|
+
|
|
1624
|
+
NW.Dom = {
|
|
1625
|
+
|
|
1626
|
+
// retrieve element by id attr
|
|
1627
|
+
byId: byId,
|
|
1628
|
+
|
|
1629
|
+
// retrieve elements by tag name
|
|
1630
|
+
byTag: byTag,
|
|
1631
|
+
|
|
1632
|
+
// retrieve elements by name attr
|
|
1633
|
+
byName: byName,
|
|
1634
|
+
|
|
1635
|
+
// retrieve elements by class name
|
|
1636
|
+
byClass: byClass,
|
|
1637
|
+
|
|
1638
|
+
// read the value of the attribute
|
|
1639
|
+
// as was in the original HTML code
|
|
1640
|
+
getAttribute: getAttribute,
|
|
1641
|
+
|
|
1642
|
+
// check for the attribute presence
|
|
1643
|
+
// as was in the original HTML code
|
|
1644
|
+
hasAttribute: hasAttribute,
|
|
1645
|
+
|
|
1646
|
+
// element match selector, return boolean true/false
|
|
1647
|
+
match: match,
|
|
1648
|
+
|
|
1649
|
+
// elements matching selector, starting from element
|
|
1650
|
+
select: select,
|
|
1651
|
+
|
|
1652
|
+
// compile selector into ad-hoc javascript resolver
|
|
1653
|
+
compile: compile,
|
|
1654
|
+
|
|
1655
|
+
// check that two elements are ancestor/descendant
|
|
1656
|
+
contains: contains,
|
|
1657
|
+
|
|
1658
|
+
// handle selector engine configuration settings
|
|
1659
|
+
configure: configure,
|
|
1660
|
+
|
|
1661
|
+
// add or overwrite user defined operators
|
|
1662
|
+
registerOperator:
|
|
1663
|
+
function(symbol, resolver) {
|
|
1664
|
+
if (!Operators[symbol]) {
|
|
1665
|
+
Operators[symbol] = resolver;
|
|
1666
|
+
}
|
|
1667
|
+
},
|
|
1668
|
+
|
|
1669
|
+
// add selector patterns for user defined callbacks
|
|
1670
|
+
registerSelector:
|
|
1671
|
+
function(name, rexp, func) {
|
|
1672
|
+
if (!Selectors[name]) {
|
|
1673
|
+
Selectors[name] = { };
|
|
1674
|
+
Selectors[name].Expression = rexp;
|
|
1675
|
+
Selectors[name].Callback = func;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1680
|
+
})(this);
|