wpa_cli_web 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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,25 @@
|
|
1
|
+
// node_modules/serve/bin/serve .
|
2
|
+
// node_modules/phantomjs/bin/phantomjs tests/phantom.js
|
3
|
+
|
4
|
+
|
5
|
+
var childProcess = require('child_process')
|
6
|
+
var phantomjs = require('phantomjs')
|
7
|
+
var path = require('path')
|
8
|
+
var binPath = phantomjs.path
|
9
|
+
|
10
|
+
var childArgs = [
|
11
|
+
path.join(__dirname, 'phantom.js')
|
12
|
+
]
|
13
|
+
|
14
|
+
var server = childProcess.spawn('node_modules/serve/bin/serve', ['.'])
|
15
|
+
|
16
|
+
var phantomServer = childProcess.spawn(binPath, childArgs)
|
17
|
+
|
18
|
+
phantomServer.on('exit', function (code) {
|
19
|
+
if (code === 0) {
|
20
|
+
console.log('all tests pass. congratulations')
|
21
|
+
} else {
|
22
|
+
console.log('tests fail')
|
23
|
+
}
|
24
|
+
server.kill()
|
25
|
+
})
|
@@ -0,0 +1,533 @@
|
|
1
|
+
// silly custom pseudo just for tests
|
2
|
+
Q.pseudos.humanoid = function(e, v) { return Q.is(e, 'li:contains(human)') || Q.is(e, 'ol:contains(human)') }
|
3
|
+
var hasQSA = !!document.querySelectorAll
|
4
|
+
, sinkSuite = function (label, suite) {
|
5
|
+
sink(label + (hasQSA ? ' [qSA]' : ''), function () {
|
6
|
+
hasQSA && Q.configure({ useNativeQSA: true })
|
7
|
+
suite.apply(null, arguments)
|
8
|
+
})
|
9
|
+
hasQSA && sink(label + ' [non-QSA]', function () {
|
10
|
+
Q.configure({ useNativeQSA: false })
|
11
|
+
suite.apply(null, arguments)
|
12
|
+
})
|
13
|
+
}
|
14
|
+
|
15
|
+
sinkSuite('Contexts', function (test, ok) {
|
16
|
+
|
17
|
+
test('should be able to pass optional context', 2, function () {
|
18
|
+
ok(Q('.a').length === 3, 'no context found 3 elements (.a)');
|
19
|
+
ok(Q('.a', Q('#boosh')).length === 2, 'context found 2 elements (#boosh .a)');
|
20
|
+
});
|
21
|
+
|
22
|
+
test('should be able to pass string as context', 5, function() {
|
23
|
+
ok(Q('.a', '#boosh').length == 2, 'context found 2 elements(.a, #boosh)');
|
24
|
+
ok(Q('.a', '.a').length == 0, 'context found 0 elements(.a, .a)');
|
25
|
+
ok(Q('.a', '.b').length == 1, 'context found 1 elements(.a, .b)');
|
26
|
+
ok(Q('.a', '#boosh .b').length == 1, 'context found 1 elements(.a, #boosh .b)');
|
27
|
+
ok(Q('.b', '#boosh .b').length == 0, 'context found 0 elements(.b, #boosh .b)');
|
28
|
+
});
|
29
|
+
|
30
|
+
test('should be able to pass qwery result as context', 5, function() {
|
31
|
+
ok(Q('.a', Q('#boosh')).length == 2, 'context found 2 elements(.a, #boosh)');
|
32
|
+
ok(Q('.a', Q('.a')).length == 0, 'context found 0 elements(.a, .a)');
|
33
|
+
ok(Q('.a', Q('.b')).length == 1, 'context found 1 elements(.a, .b)');
|
34
|
+
ok(Q('.a', Q('#boosh .b')).length == 1, 'context found 1 elements(.a, #boosh .b)');
|
35
|
+
ok(Q('.b', Q('#boosh .b')).length == 0, 'context found 0 elements(.b, #boosh .b)');
|
36
|
+
});
|
37
|
+
|
38
|
+
test('should not return duplicates from combinators', 2, function () {
|
39
|
+
ok(Q('#boosh,#boosh').length == 1, 'two booshes dont make a thing go right');
|
40
|
+
ok(Q('#boosh,.apples,#boosh').length == 1, 'two booshes and an apple dont make a thing go right');
|
41
|
+
});
|
42
|
+
|
43
|
+
test('byId sub-queries within context', 6, function() {
|
44
|
+
ok(Q('#booshTest', Q('#boosh')).length == 1, 'found "#id #id"')
|
45
|
+
ok(Q('.a.b #booshTest', Q('#boosh')).length == 1, 'found ".class.class #id"')
|
46
|
+
ok(Q('.a>#booshTest', Q('#boosh')).length == 1, 'found ".class>#id"')
|
47
|
+
ok(Q('>.a>#booshTest', Q('#boosh')).length == 1, 'found ">.class>#id"')
|
48
|
+
ok(!Q('#boosh', Q('#booshTest')).length, 'shouldn\'t find #boosh (ancestor) within #booshTest (descendent)')
|
49
|
+
ok(!Q('#boosh', Q('#lonelyBoosh')).length, 'shouldn\'t find #boosh within #lonelyBoosh (unrelated)')
|
50
|
+
})
|
51
|
+
})
|
52
|
+
|
53
|
+
sinkSuite('CSS 1', function (test, ok) {
|
54
|
+
test('get element by id', 2, function () {
|
55
|
+
var result = Q('#boosh');
|
56
|
+
ok(!!result[0], 'found element with id=boosh');
|
57
|
+
ok(!!Q('h1')[0], 'found 1 h1');
|
58
|
+
});
|
59
|
+
|
60
|
+
test('byId sub-queries', 4, function() {
|
61
|
+
ok(Q('#boosh #booshTest').length == 1, 'found "#id #id"')
|
62
|
+
ok(Q('.a.b #booshTest').length == 1, 'found ".class.class #id"')
|
63
|
+
ok(Q('#boosh>.a>#booshTest').length == 1, 'found "#id>.class>#id"')
|
64
|
+
ok(Q('.a>#booshTest').length == 1, 'found ".class>#id"')
|
65
|
+
})
|
66
|
+
|
67
|
+
test('get elements by class', 6, function () {
|
68
|
+
ok(Q('#boosh .a').length == 2, 'found two elements');
|
69
|
+
ok(!!Q('#boosh div.a')[0], 'found one element');
|
70
|
+
ok(Q('#boosh div').length == 2, 'found two {div} elements');
|
71
|
+
ok(!!Q('#boosh span')[0], 'found one {span} element');
|
72
|
+
ok(!!Q('#boosh div div')[0], 'found a single div');
|
73
|
+
ok(Q('a.odd').length == 1, 'found single a');
|
74
|
+
});
|
75
|
+
|
76
|
+
test('combos', 1, function () {
|
77
|
+
ok(Q('#boosh div,#boosh span').length == 3, 'found 2 divs and 1 span');
|
78
|
+
});
|
79
|
+
|
80
|
+
test('class with dashes', 1, function() {
|
81
|
+
ok(Q('.class-with-dashes').length == 1, 'found something');
|
82
|
+
});
|
83
|
+
|
84
|
+
test('should ignore comment nodes', 1, function() {
|
85
|
+
ok(Q('#boosh *').length === 4, 'found only 4 elements under #boosh')
|
86
|
+
});
|
87
|
+
|
88
|
+
test('deep messy relationships', 6, function() {
|
89
|
+
// these are mostly characterised by a combination of tight relationships and loose relationships
|
90
|
+
// on the right side of the query it's easy to find matches but they tighten up quickly as you
|
91
|
+
// go to the left
|
92
|
+
// they are useful for making sure the dom crawler doesn't stop short or over-extend as it works
|
93
|
+
// up the tree the crawl needs to be comprehensive
|
94
|
+
ok(Q('div#fixtures > div a').length == 5, 'found four results for "div#fixtures > div a"')
|
95
|
+
ok(Q('.direct-descend > .direct-descend .lvl2').length == 1, 'found one result for ".direct-descend > .direct-descend .lvl2"')
|
96
|
+
ok(Q('.direct-descend > .direct-descend div').length == 1, 'found one result for ".direct-descend > .direct-descend div"')
|
97
|
+
ok(Q('.direct-descend > .direct-descend div').length == 1, 'found one result for ".direct-descend > .direct-descend div"')
|
98
|
+
ok(Q('div#fixtures div ~ a div').length == 0, 'found no results for odd query')
|
99
|
+
ok(Q('.direct-descend > .direct-descend > .direct-descend ~ .lvl2').length == 0, 'found no results for another odd query')
|
100
|
+
});
|
101
|
+
});
|
102
|
+
|
103
|
+
sinkSuite('CSS 2', function (test, ok) {
|
104
|
+
|
105
|
+
test('get elements by attribute', 4, function () {
|
106
|
+
var wanted = Q('#boosh div[test]')[0];
|
107
|
+
var expected = document.getElementById('booshTest');
|
108
|
+
ok(wanted == expected, 'found attribute');
|
109
|
+
ok(Q('#boosh div[test=fg]')[0] == expected, 'found attribute with value');
|
110
|
+
ok(Q('em[rel~="copyright"]').length == 1, 'found em[rel~="copyright"]');
|
111
|
+
ok(Q('em[nopass~="copyright"]').length == 0, 'found em[nopass~="copyright"]');
|
112
|
+
});
|
113
|
+
|
114
|
+
test('should not throw error by attribute selector', 1, function () {
|
115
|
+
ok(Q('[foo^="bar"]').length === 1, 'found 1 element');
|
116
|
+
});
|
117
|
+
|
118
|
+
test('crazy town', 1, function () {
|
119
|
+
var el = document.getElementById('attr-test3');
|
120
|
+
ok(Q('div#attr-test3.found.you[title="whatup duders"]')[0] == el, 'found the right element');
|
121
|
+
});
|
122
|
+
|
123
|
+
});
|
124
|
+
|
125
|
+
sinkSuite('attribute selectors', function (test, ok, b, a, assert) {
|
126
|
+
|
127
|
+
/* CSS 2 SPEC */
|
128
|
+
|
129
|
+
test('[attr]', 1, function () {
|
130
|
+
var expected = document.getElementById('attr-test-1');
|
131
|
+
ok(Q('#attributes div[unique-test]')[0] == expected, 'found attribute with [attr]');
|
132
|
+
});
|
133
|
+
|
134
|
+
test('[attr=val]', 3, function () {
|
135
|
+
var expected = document.getElementById('attr-test-2');
|
136
|
+
ok(Q('#attributes div[test="two-foo"]')[0] == expected, 'found attribute with =');
|
137
|
+
ok(Q("#attributes div[test='two-foo']")[0] == expected, 'found attribute with =');
|
138
|
+
ok(Q('#attributes div[test=two-foo]')[0] == expected, 'found attribute with =');
|
139
|
+
});
|
140
|
+
|
141
|
+
test('[attr~=val]', 1, function () {
|
142
|
+
var expected = document.getElementById('attr-test-3');
|
143
|
+
ok(Q('#attributes div[test~=three]')[0] == expected, 'found attribute with ~=');
|
144
|
+
});
|
145
|
+
|
146
|
+
test('[attr|=val]', 2, function () {
|
147
|
+
var expected = document.getElementById('attr-test-2');
|
148
|
+
ok(Q('#attributes div[test|="two-foo"]')[0] == expected, 'found attribute with |=');
|
149
|
+
ok(Q('#attributes div[test|=two]')[0] == expected, 'found attribute with |=');
|
150
|
+
});
|
151
|
+
|
152
|
+
test('[href=#x] special case', 1, function () {
|
153
|
+
var expected = document.getElementById('attr-test-4');
|
154
|
+
ok(Q('#attributes a[href="#aname"]')[0] == expected, 'found attribute with href=#x');
|
155
|
+
});
|
156
|
+
|
157
|
+
/* CSS 3 SPEC */
|
158
|
+
|
159
|
+
test('[attr^=val]', 1, function () {
|
160
|
+
var expected = document.getElementById('attr-test-2');
|
161
|
+
ok(Q('#attributes div[test^=two]')[0] == expected, 'found attribute with ^=');
|
162
|
+
});
|
163
|
+
|
164
|
+
test('[attr$=val]', 1, function () {
|
165
|
+
var expected = document.getElementById('attr-test-2');
|
166
|
+
ok(Q('#attributes div[test$=foo]')[0] == expected, 'found attribute with $=');
|
167
|
+
});
|
168
|
+
|
169
|
+
test('[attr*=val]', 1, function () {
|
170
|
+
var expected = document.getElementById('attr-test-3');
|
171
|
+
ok(Q('#attributes div[test*=hree]')[0] == expected, 'found attribute with *=');
|
172
|
+
});
|
173
|
+
|
174
|
+
test('direct descendants', 2, function () {
|
175
|
+
ok(Q('#direct-descend > .direct-descend').length == 2, 'found two direct descendents');
|
176
|
+
ok(Q('#direct-descend > .direct-descend > .lvl2').length == 3, 'found three second-level direct descendents');
|
177
|
+
});
|
178
|
+
|
179
|
+
test('sibling elements', 17, function () {
|
180
|
+
assert(Q('#sibling-selector ~ .sibling-selector').length, 2, 'found two siblings')
|
181
|
+
assert(Q('#sibling-selector ~ div.sibling-selector').length, 2, 'found two siblings')
|
182
|
+
assert(Q('#sibling-selector + div.sibling-selector').length, 1, 'found one sibling')
|
183
|
+
assert(Q('#sibling-selector + .sibling-selector').length, 1, 'found one sibling')
|
184
|
+
|
185
|
+
assert(Q('.parent .oldest ~ .sibling').length, 4, 'found four younger siblings')
|
186
|
+
assert(Q('.parent .middle ~ .sibling').length, 2, 'found two younger siblings')
|
187
|
+
assert(Q('.parent .middle ~ h4').length, 1, 'found next sibling by tag')
|
188
|
+
assert(Q('.parent .middle ~ h4.younger').length, 1, 'found next sibling by tag and class')
|
189
|
+
assert(Q('.parent .middle ~ h3').length, 0, 'an element can\'t be its own sibling')
|
190
|
+
assert(Q('.parent .middle ~ h2').length, 0, 'didn\'t find an older sibling')
|
191
|
+
assert(Q('.parent .youngest ~ .sibling').length, 0, 'found no younger siblings')
|
192
|
+
|
193
|
+
assert(Q('.parent .oldest + .sibling').length, 1, 'found next sibling')
|
194
|
+
assert(Q('.parent .middle + .sibling').length, 1, 'found next sibling')
|
195
|
+
assert(Q('.parent .middle + h4').length, 1, 'found next sibling by tag')
|
196
|
+
assert(Q('.parent .middle + h3').length, 0, 'an element can\'t be its own sibling')
|
197
|
+
assert(Q('.parent .middle + h2').length, 0, 'didn\'t find an older sibling')
|
198
|
+
assert(Q('.parent .youngest + .sibling').length, 0, 'found no younger siblings')
|
199
|
+
});
|
200
|
+
|
201
|
+
});
|
202
|
+
|
203
|
+
sinkSuite('Uniq', function (test, ok) {
|
204
|
+
test('duplicates arent found in arrays', 2, function () {
|
205
|
+
ok(Q.uniq(['a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e']).length == 5, 'result should be a, b, c, d, e')
|
206
|
+
ok(Q.uniq(['a', 'b', 'c', 'c', 'c']).length == 3, 'result should be a, b, c')
|
207
|
+
})
|
208
|
+
})
|
209
|
+
|
210
|
+
|
211
|
+
sinkSuite('element-context queries', function(test, ok) {
|
212
|
+
test('relationship-first queries', 5, function() {
|
213
|
+
var pass = false
|
214
|
+
try { pass = Q('> .direct-descend', Q('#direct-descend')).length == 2 } catch (e) { }
|
215
|
+
ok(pass, 'found two direct descendents using > first');
|
216
|
+
|
217
|
+
pass = false
|
218
|
+
try { pass = Q('~ .sibling-selector', Q('#sibling-selector')).length == 2 } catch (e) { }
|
219
|
+
ok(pass, 'found two siblings with ~ first')
|
220
|
+
|
221
|
+
pass = false
|
222
|
+
try { pass = Q('+ .sibling-selector', Q('#sibling-selector')).length == 1 } catch (e) { }
|
223
|
+
ok(pass, 'found one sibling with + first')
|
224
|
+
|
225
|
+
pass = false
|
226
|
+
var ctx = Q('.idless')[0]
|
227
|
+
try { pass = Q('> .tokens a', ctx).length == 1 } catch (e) { }
|
228
|
+
ok(pass, 'found one sibling from a root with no id')
|
229
|
+
ok(!ctx.getAttribute('id'), 'root element used for selection still has no id')
|
230
|
+
})
|
231
|
+
|
232
|
+
// should be able to query on an element that hasn't been inserted into the dom
|
233
|
+
var frag = document.createElement('div')
|
234
|
+
frag.innerHTML = '<div class="d i v"><p id="oooo"><em></em><em id="emem"></em></p></div><p id="sep"><div class="a"><span></span></div></p>'
|
235
|
+
|
236
|
+
test('detached fragments', 2, function() {
|
237
|
+
ok(Q('.a span', frag).length == 1, 'should find child elements of fragment')
|
238
|
+
ok(Q('> div p em', frag).length == 2, 'should find child elements of fragment, relationship first')
|
239
|
+
})
|
240
|
+
|
241
|
+
test('byId sub-queries within detached fragment', 6, function () {
|
242
|
+
ok(Q('#emem', frag).length == 1, 'found "#id" in fragment')
|
243
|
+
ok(Q('.d.i #emem', frag).length == 1, 'found ".class.class #id" in fragment')
|
244
|
+
ok(Q('.d #oooo #emem', frag).length == 1, 'found ".class #id #id" in fragment')
|
245
|
+
ok(Q('> div #oooo', frag).length == 1, 'found "> .class #id" in fragment')
|
246
|
+
ok(!Q('#oooo', Q('#emem', frag)).length, 'shouldn\'t find #oooo (ancestor) within #emem (descendent)')
|
247
|
+
ok(!Q('#sep', Q('#emem', frag)).length, 'shouldn\'t find #sep within #emem (unrelated)')
|
248
|
+
})
|
249
|
+
|
250
|
+
test('exclude self in match', 1, function() {
|
251
|
+
ok(Q('.order-matters', Q('#order-matters')).length == 4, 'should not include self in element-context queries')
|
252
|
+
});
|
253
|
+
|
254
|
+
// because form's have .length
|
255
|
+
test('forms can be used as contexts', 1, function() {
|
256
|
+
ok(Q('*', Q('form')[0]).length === 3, 'found 3 elements under <form>')
|
257
|
+
})
|
258
|
+
})
|
259
|
+
|
260
|
+
sinkSuite('tokenizer', function (test, ok) {
|
261
|
+
|
262
|
+
test('should not get weird tokens', 5, function () {
|
263
|
+
ok(Q('div .tokens[title="one"]')[0] == document.getElementById('token-one'), 'found div .tokens[title="one"]');
|
264
|
+
ok(Q('div .tokens[title="one two"]')[0] == document.getElementById('token-two'), 'found div .tokens[title="one two"]');
|
265
|
+
ok(Q('div .tokens[title="one two three #%"]')[0] == document.getElementById('token-three'), 'found div .tokens[title="one two three #%"]');
|
266
|
+
ok(Q("div .tokens[title='one two three #%'] a")[0] == document.getElementById('token-four'), 'found div .tokens[title=\'one two three #%\'] a');
|
267
|
+
ok(Q('div .tokens[title="one two three #%"] a[href$=foo] div')[0] == document.getElementById('token-five'), 'found div .tokens[title="one two three #%"] a[href=foo] div');
|
268
|
+
});
|
269
|
+
|
270
|
+
});
|
271
|
+
|
272
|
+
sinkSuite('interesting syntaxes', function (test, ok) {
|
273
|
+
test('should parse bad selectors', 1, function () {
|
274
|
+
ok(Q('#spaced-tokens p em a').length, 'found element with funny tokens')
|
275
|
+
});
|
276
|
+
});
|
277
|
+
|
278
|
+
sinkSuite('order matters', function (test, ok) {
|
279
|
+
|
280
|
+
function tag(el) {
|
281
|
+
return el.tagName.toLowerCase();
|
282
|
+
}
|
283
|
+
|
284
|
+
// <div id="order-matters">
|
285
|
+
// <p class="order-matters"></p>
|
286
|
+
// <a class="order-matters">
|
287
|
+
// <em class="order-matters"></em><b class="order-matters"></b>
|
288
|
+
// </a>
|
289
|
+
// </div>
|
290
|
+
|
291
|
+
test('the order of elements return matters', 4, function () {
|
292
|
+
var els = Q('#order-matters .order-matters');
|
293
|
+
ok(tag(els[0]) == 'p', 'first element matched is a {p} tag');
|
294
|
+
ok(tag(els[1]) == 'a', 'first element matched is a {a} tag');
|
295
|
+
ok(tag(els[2]) == 'em', 'first element matched is a {em} tag');
|
296
|
+
ok(tag(els[3]) == 'b', 'first element matched is a {b} tag');
|
297
|
+
});
|
298
|
+
|
299
|
+
});
|
300
|
+
|
301
|
+
sinkSuite('pseudo-selectors', function (test, ok) {
|
302
|
+
test(':contains', 4, function() {
|
303
|
+
ok(Q('li:contains(humans)').length == 1, 'found by "element:contains(text)"')
|
304
|
+
ok(Q(':contains(humans)').length == 5, 'found by ":contains(text)", including all ancestors')
|
305
|
+
// * is an important case, can cause weird errors
|
306
|
+
ok(Q('*:contains(humans)').length == 5, 'found by "*:contains(text)", including all ancestors')
|
307
|
+
ok(Q('ol:contains(humans)').length == 1, 'found by "ancestor:contains(text)"')
|
308
|
+
})
|
309
|
+
|
310
|
+
test(':not', 1, function() {
|
311
|
+
ok(Q('.odd:not(div)').length == 1, 'found one .odd :not an <a>')
|
312
|
+
})
|
313
|
+
|
314
|
+
test(':first-child', 2, function () {
|
315
|
+
ok(Q('#pseudos div:first-child')[0] == document.getElementById('pseudos').getElementsByTagName('*')[0], 'found first child')
|
316
|
+
ok(Q('#pseudos div:first-child').length == 1, 'found only 1')
|
317
|
+
});
|
318
|
+
|
319
|
+
test(':last-child', 2, function () {
|
320
|
+
var all = document.getElementById('pseudos').getElementsByTagName('div');
|
321
|
+
ok(Q('#pseudos div:last-child')[0] == all[all.length - 1], 'found last child')
|
322
|
+
ok(Q('#pseudos div:last-child').length == 1, 'found only 1')
|
323
|
+
});
|
324
|
+
|
325
|
+
test('ol > li[attr="boosh"]:last-child', 2, function () {
|
326
|
+
var expected = document.getElementById('attr-child-boosh');
|
327
|
+
ok(Q('ol > li[attr="boosh"]:last-child').length == 1, 'only 1 element found');
|
328
|
+
ok(Q('ol > li[attr="boosh"]:last-child')[0] == expected, 'found correct element');
|
329
|
+
});
|
330
|
+
|
331
|
+
test(':nth-child(odd|even|x)', 4, function () {
|
332
|
+
var second = document.getElementById('pseudos').getElementsByTagName('div')[1];
|
333
|
+
ok(Q('#pseudos :nth-child(odd)').length == 4, 'found 4 odd elements');
|
334
|
+
ok(Q('#pseudos div:nth-child(odd)').length == 3, 'found 3 odd elements with div tag');
|
335
|
+
ok(Q('#pseudos div:nth-child(even)').length == 3, 'found 3 even elements with div tag');
|
336
|
+
ok(Q('#pseudos div:nth-child(2)')[0] == second, 'found 2nd nth-child of pseudos');
|
337
|
+
});
|
338
|
+
|
339
|
+
test(':nth-child(expr)', 6, function () {
|
340
|
+
var fifth = document.getElementById('pseudos').getElementsByTagName('a')[0];
|
341
|
+
var sixth = document.getElementById('pseudos').getElementsByTagName('div')[4];
|
342
|
+
|
343
|
+
ok(Q('#pseudos :nth-child(3n+1)').length == 3, 'found 3 elements');
|
344
|
+
ok(Q('#pseudos :nth-child(3n-2)').length == 3, 'found 3 elements'); // was +3n-2 but older safari no likey +
|
345
|
+
ok(Q('#pseudos :nth-child(-n+6)').length == 6, 'found 6 elements');
|
346
|
+
ok(Q('#pseudos :nth-child(-n+5)').length == 5, 'found 5 elements');
|
347
|
+
ok(Q('#pseudos :nth-child(3n+2)')[1] == fifth, 'second :nth-child(3n+2) is the fifth child');
|
348
|
+
ok(Q('#pseudos :nth-child(3n)')[1] == sixth, 'second :nth-child(3n) is the sixth child');
|
349
|
+
});
|
350
|
+
|
351
|
+
test(':nth-last-child(odd|even|x)', 4, function () {
|
352
|
+
var second = document.getElementById('pseudos').getElementsByTagName('div')[1];
|
353
|
+
ok(Q('#pseudos :nth-last-child(odd)').length == 4, 'found 4 odd elements');
|
354
|
+
ok(Q('#pseudos div:nth-last-child(odd)').length == 3, 'found 3 odd elements with div tag');
|
355
|
+
ok(Q('#pseudos div:nth-last-child(even)').length == 3, 'found 3 even elements with div tag');
|
356
|
+
ok(Q('#pseudos div:nth-last-child(6)')[0] == second, '6th nth-last-child should be 2nd of 7 elements');
|
357
|
+
});
|
358
|
+
|
359
|
+
test(':nth-last-child(expr)', 5, function () {
|
360
|
+
var third = document.getElementById('pseudos').getElementsByTagName('div')[2];
|
361
|
+
|
362
|
+
ok(Q('#pseudos :nth-last-child(3n+1)').length == 3, 'found 3 elements');
|
363
|
+
ok(Q('#pseudos :nth-last-child(3n-2)').length == 3, 'found 3 elements');
|
364
|
+
ok(Q('#pseudos :nth-last-child(-n+6)').length == 6, 'found 6 elements');
|
365
|
+
ok(Q('#pseudos :nth-last-child(-n+5)').length == 5, 'found 5 elements');
|
366
|
+
ok(Q('#pseudos :nth-last-child(3n+2)')[0] == third, 'first :nth-last-child(3n+2) is the third child');
|
367
|
+
});
|
368
|
+
|
369
|
+
test(':nth-of-type(expr)', 6, function () {
|
370
|
+
var a = document.getElementById('pseudos').getElementsByTagName('a')[0];
|
371
|
+
|
372
|
+
ok(Q('#pseudos div:nth-of-type(3n+1)').length == 2, 'found 2 div elements');
|
373
|
+
ok(Q('#pseudos a:nth-of-type(3n+1)').length == 1, 'found 1 a element');
|
374
|
+
ok(Q('#pseudos a:nth-of-type(3n+1)')[0] == a, 'found the right a element');
|
375
|
+
ok(Q('#pseudos a:nth-of-type(3n)').length == 0, 'no matches for every third a');
|
376
|
+
ok(Q('#pseudos a:nth-of-type(odd)').length == 1, 'found the odd a');
|
377
|
+
ok(Q('#pseudos a:nth-of-type(1)').length == 1, 'found the first a');
|
378
|
+
});
|
379
|
+
|
380
|
+
test(':nth-last-of-type(expr)', 3, function () {
|
381
|
+
var second = document.getElementById('pseudos').getElementsByTagName('div')[1];
|
382
|
+
|
383
|
+
ok(Q('#pseudos div:nth-last-of-type(3n+1)').length == 2, 'found 2 div elements');
|
384
|
+
ok(Q('#pseudos a:nth-last-of-type(3n+1)').length == 1, 'found 1 a element');
|
385
|
+
ok(Q('#pseudos div:nth-last-of-type(5)')[0] == second, '5th nth-last-of-type should be 2nd of 7 elements');
|
386
|
+
});
|
387
|
+
|
388
|
+
test(':first-of-type', 2, function () {
|
389
|
+
ok(Q('#pseudos a:first-of-type')[0] == document.getElementById('pseudos').getElementsByTagName('a')[0], 'found first a element')
|
390
|
+
ok(Q('#pseudos a:first-of-type').length == 1, 'found only 1')
|
391
|
+
});
|
392
|
+
|
393
|
+
test(':last-of-type', 2, function () {
|
394
|
+
var all = document.getElementById('pseudos').getElementsByTagName('div');
|
395
|
+
ok(Q('#pseudos div:last-of-type')[0] == all[all.length - 1], 'found last div element')
|
396
|
+
ok(Q('#pseudos div:last-of-type').length == 1, 'found only 1')
|
397
|
+
});
|
398
|
+
|
399
|
+
test(':only-of-type', 2, function () {
|
400
|
+
ok(Q('#pseudos a:only-of-type')[0] == document.getElementById('pseudos').getElementsByTagName('a')[0], 'found the only a element')
|
401
|
+
ok(Q('#pseudos a:first-of-type').length == 1, 'found only 1')
|
402
|
+
});
|
403
|
+
|
404
|
+
test(':target', 2, function () {
|
405
|
+
location.hash = '';
|
406
|
+
ok(Q('#pseudos:target').length == 0, '#pseudos is not the target');
|
407
|
+
location.hash = '#pseudos';
|
408
|
+
ok(Q('#pseudos:target').length == 1, 'now #pseudos is the target');
|
409
|
+
location.hash = '';
|
410
|
+
});
|
411
|
+
|
412
|
+
test('custom pseudos', 1, function() {
|
413
|
+
// :humanoid implemented just for testing purposes
|
414
|
+
ok(Q(':humanoid').length == 2, 'selected using custom pseudo')
|
415
|
+
});
|
416
|
+
|
417
|
+
});
|
418
|
+
|
419
|
+
sinkSuite('argument types', function (test, ok) {
|
420
|
+
|
421
|
+
test('should be able to pass in nodes as arguments', 5, function () {
|
422
|
+
var el = document.getElementById('boosh');
|
423
|
+
ok(Q(el)[0] == el, 'Q(el)[0] == el');
|
424
|
+
ok(Q(el, 'body')[0] == el, "Q(el, 'body')[0] == el");
|
425
|
+
ok(Q(el, document)[0] == el, "Q(el, document)[0] == el");
|
426
|
+
ok(Q(window)[0] == window, 'Q(window)[0] == window');
|
427
|
+
ok(Q(document)[0] == document, 'Q(document)[0] == document');
|
428
|
+
});
|
429
|
+
|
430
|
+
test('should be able to pass in an array of results as arguments', 5, function () {
|
431
|
+
var el = document.getElementById('boosh');
|
432
|
+
var result = Q([Q('#boosh'), Q(document), Q(window)]);
|
433
|
+
ok(result.length == 3, '3 elements in the combined set');
|
434
|
+
ok(result[0] == el, "result[0] == el");
|
435
|
+
ok(result[1] == document, "result[0] == document");
|
436
|
+
ok(result[2] == window, 'result[0] == window');
|
437
|
+
ok(Q([Q('#pseudos div.odd'), Q('#pseudos div.even')]).length == 6, 'found all the odd and even divs');
|
438
|
+
});
|
439
|
+
|
440
|
+
});
|
441
|
+
|
442
|
+
sinkSuite('is()', function (test, ok) {
|
443
|
+
var el = document.getElementById('attr-child-boosh');
|
444
|
+
test('simple selectors', 9, function () {
|
445
|
+
ok(Q.is(el, 'li'), 'tag');
|
446
|
+
ok(Q.is(el, '*'), 'wildcard');
|
447
|
+
ok(Q.is(el, '#attr-child-boosh'), '#id');
|
448
|
+
ok(Q.is(el, '[attr]'), '[attr]');
|
449
|
+
ok(Q.is(el, '[attr=boosh]'), '[attr=val]');
|
450
|
+
ok(!Q.is(el, 'div'), 'wrong tag');
|
451
|
+
ok(!Q.is(el, '#foo'), 'wrong #id');
|
452
|
+
ok(!Q.is(el, '[foo]'), 'wrong [attr]');
|
453
|
+
ok(!Q.is(el, '[attr=foo]'), 'wrong [attr=val]');
|
454
|
+
});
|
455
|
+
test('selector sequences', 2, function () {
|
456
|
+
ok(Q.is(el, 'li#attr-child-boosh[attr=boosh]'), 'tag#id[attr=val]');
|
457
|
+
ok(!Q.is(el, 'div#attr-child-boosh[attr=boosh]'), 'wrong tag#id[attr=val]');
|
458
|
+
});
|
459
|
+
test('selector sequences combinators', 7, function () {
|
460
|
+
ok(Q.is(el, 'ol li'), 'tag tag');
|
461
|
+
ok(Q.is(el, 'ol>li'), 'tag>tag');
|
462
|
+
ok(Q.is(el, 'ol>li+li'), 'tab>tag+tag');
|
463
|
+
ok(Q.is(el, 'ol#list li#attr-child-boosh[attr=boosh]'), 'tag#id tag#id[attr=val]');
|
464
|
+
ok(!Q.is(el, 'ol#list>li#attr-child-boosh[attr=boosh]'), 'wrong tag#id>tag#id[attr=val]');
|
465
|
+
ok(Q.is(el, 'ol ol li#attr-child-boosh[attr=boosh]'), 'tag tag tag#id[attr=val]');
|
466
|
+
ok(Q.is(Q('#token-four')[0], 'div#fixtures>div a'), 'tag#id>tag tag where ambiguous middle tag requires backtracking');
|
467
|
+
});
|
468
|
+
test('pseudos', 4, function() {
|
469
|
+
//TODO: more tests!
|
470
|
+
ok(Q.is(el, 'li:contains(hello)'), 'matching :contains(text)')
|
471
|
+
ok(!Q.is(el, 'li:contains(human)'), 'non-matching :contains(text)')
|
472
|
+
ok(Q.is(Q('#list>li')[2], ':humanoid'), 'matching custom pseudo')
|
473
|
+
ok(!Q.is(Q('#list>li')[1], ':humanoid'), 'non-matching custom pseudo')
|
474
|
+
})
|
475
|
+
test('context', 2, function () {
|
476
|
+
ok(Q.is(el, 'li#attr-child-boosh[attr=boosh]', Q('#list')[0]), 'context');
|
477
|
+
ok(!Q.is(el, 'ol#list li#attr-child-boosh[attr=boosh]', Q('#boosh')[0]), 'wrong context');
|
478
|
+
});
|
479
|
+
});
|
480
|
+
|
481
|
+
sinkSuite('selecting elements in other documents', function (test, ok) {
|
482
|
+
var doc = document.getElementById('frame').contentWindow.document
|
483
|
+
doc.body.innerHTML =
|
484
|
+
'<div id="hsoob">' +
|
485
|
+
'<div class="a b">' +
|
486
|
+
'<div class="d e sib" test="fg" id="booshTest"><p><span id="spanny"></span></p></div>' +
|
487
|
+
'<em nopass="copyrighters" rel="copyright booshrs" test="f g" class="sib"></em>' +
|
488
|
+
'<span class="h i a sib"></span>' +
|
489
|
+
'</div>' +
|
490
|
+
'<p class="odd"></p>' +
|
491
|
+
'</div>' +
|
492
|
+
'<div id="lonelyHsoob"></div>'
|
493
|
+
|
494
|
+
test('get element by id', 1, function () {
|
495
|
+
var result = Q('#hsoob', doc);
|
496
|
+
ok(!!result[0], 'found element with id=hsoob');
|
497
|
+
});
|
498
|
+
|
499
|
+
test('get elements by class', 6, function () {
|
500
|
+
ok(Q('#hsoob .a', doc).length == 2, 'found two elements');
|
501
|
+
ok(!!Q('#hsoob div.a', doc)[0], 'found one element');
|
502
|
+
ok(Q('#hsoob div', doc).length == 2, 'found two {div} elements');
|
503
|
+
ok(!!Q('#hsoob span', doc)[0], 'found one {span} element');
|
504
|
+
ok(!!Q('#hsoob div div', doc)[0], 'found a single div');
|
505
|
+
ok(Q('p.odd', doc).length == 1, 'found single br');
|
506
|
+
});
|
507
|
+
|
508
|
+
test('complex selectors', 4, function () {
|
509
|
+
ok(Q('.d ~ .sib', doc).length === 2, 'found one ~ sibling')
|
510
|
+
ok(Q('.a .d + .sib', doc).length === 1, 'found 2 + siblings')
|
511
|
+
ok(Q('#hsoob > div > .h', doc).length === 1, 'found span using child selectors')
|
512
|
+
ok(Q('.a .d ~ .sib[test="f g"]', doc).length === 1, 'found 1 ~ sibling with test attribute')
|
513
|
+
});
|
514
|
+
|
515
|
+
test('byId sub-queries', 3, function () {
|
516
|
+
ok(Q('#hsoob #spanny', doc).length == 1, 'found "#id #id" in frame')
|
517
|
+
ok(Q('.a #spanny', doc).length == 1, 'found ".class #id" in frame')
|
518
|
+
ok(Q('.a #booshTest #spanny', doc).length == 1, 'found ".class #id #id" in frame')
|
519
|
+
//ok(Q('> #hsoob', doc).length == 1, 'found "> #id" in frame') --> would be good to support this, needs some tweaking though
|
520
|
+
})
|
521
|
+
|
522
|
+
test('byId sub-queries within sub-context', 6, function () {
|
523
|
+
ok(Q('#spanny', Q('#hsoob', doc)).length == 1, 'found "#id -> #id" in frame')
|
524
|
+
ok(Q('.a #spanny', Q('#hsoob', doc)).length == 1, 'found ".class #id" in frame')
|
525
|
+
ok(Q('.a #booshTest #spanny', Q('#hsoob', doc)).length == 1, 'found ".class #id #id" in frame')
|
526
|
+
ok(Q('.a > #booshTest', Q('#hsoob', doc)).length == 1, 'found "> .class #id" in frame')
|
527
|
+
ok(!Q('#booshTest', Q('#spanny', doc)).length, 'shouldn\'t find #booshTest (ancestor) within #spanny (descendent)')
|
528
|
+
ok(!Q('#booshTest', Q('#lonelyHsoob', doc)).length, 'shouldn\'t find #booshTest within #lonelyHsoob (unrelated)')
|
529
|
+
})
|
530
|
+
|
531
|
+
});
|
532
|
+
|
533
|
+
start();
|