Merge "Don't check namespace in SpecialWantedtemplates"
[lhc/web/wiklou.git] / tests / qunit / suites / resources / jquery / jquery.makeCollapsible.test.js
1 ( function ( mw, $ ) {
2 var loremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';
3
4 QUnit.module( 'jquery.makeCollapsible', QUnit.newMwEnvironment( {
5 setup: function () {
6 this.clock = this.sandbox.useFakeTimers();
7 }
8 } ) );
9
10 function prepareCollapsible( html, options ) {
11 return $( $.parseHTML( html ) )
12 .appendTo( '#qunit-fixture' )
13 // options might be undefined here - this is okay
14 .makeCollapsible( options );
15 }
16
17 // This test is first because if it fails, then almost all of the latter tests are meaningless.
18 QUnit.test( 'testing hooks/triggers', 4, function ( assert ) {
19 var test = this,
20 $collapsible = prepareCollapsible(
21 '<div class="mw-collapsible">' + loremIpsum + '</div>'
22 ),
23 $content = $collapsible.find( '.mw-collapsible-content' ),
24 $toggle = $collapsible.find( '.mw-collapsible-toggle' );
25
26 // In one full collapse-expand cycle, each event will be fired once
27
28 // On collapse...
29 $collapsible.on( 'beforeCollapse.mw-collapsible', function () {
30 assert.assertTrue( $content.is( ':visible' ), 'first beforeCollapseExpand: content is visible' );
31 } );
32 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
33 assert.assertTrue( $content.is( ':hidden' ), 'first afterCollapseExpand: content is hidden' );
34
35 // On expand...
36 $collapsible.on( 'beforeExpand.mw-collapsible', function () {
37 assert.assertTrue( $content.is( ':hidden' ), 'second beforeCollapseExpand: content is hidden' );
38 } );
39 $collapsible.on( 'afterExpand.mw-collapsible', function () {
40 assert.assertTrue( $content.is( ':visible' ), 'second afterCollapseExpand: content is visible' );
41 } );
42
43 // ...expanding happens here
44 $toggle.trigger( 'click' );
45 test.clock.tick( 500 );
46 } );
47
48 // ...collapsing happens here
49 $toggle.trigger( 'click' );
50 test.clock.tick( 500 );
51 } );
52
53 QUnit.test( 'basic operation (<div>)', 5, function ( assert ) {
54 var test = this,
55 $collapsible = prepareCollapsible(
56 '<div class="mw-collapsible">' + loremIpsum + '</div>'
57 ),
58 $content = $collapsible.find( '.mw-collapsible-content' ),
59 $toggle = $collapsible.find( '.mw-collapsible-toggle' );
60
61 assert.equal( $content.length, 1, 'content is present' );
62 assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' );
63
64 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
65
66 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
67 assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
68
69 $collapsible.on( 'afterExpand.mw-collapsible', function () {
70 assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
71 } );
72
73 $toggle.trigger( 'click' );
74 test.clock.tick( 500 );
75 } );
76
77 $toggle.trigger( 'click' );
78 test.clock.tick( 500 );
79 } );
80
81 QUnit.test( 'basic operation (<table>)', 7, function ( assert ) {
82 var test = this,
83 $collapsible = prepareCollapsible(
84 '<table class="mw-collapsible">' +
85 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
86 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
87 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
88 '</table>'
89 ),
90 $headerRow = $collapsible.find( 'tr:first' ),
91 $contentRow = $collapsible.find( 'tr:last' ),
92 $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' );
93
94 assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' );
95
96 assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
97 assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' );
98
99 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
100 assert.assertTrue( $headerRow.is( ':visible' ), 'after collapsing: headerRow is still visible' );
101 assert.assertTrue( $contentRow.is( ':hidden' ), 'after collapsing: contentRow is hidden' );
102
103 $collapsible.on( 'afterExpand.mw-collapsible', function () {
104 assert.assertTrue( $headerRow.is( ':visible' ), 'after expanding: headerRow is still visible' );
105 assert.assertTrue( $contentRow.is( ':visible' ), 'after expanding: contentRow is visible' );
106 } );
107
108 $toggle.trigger( 'click' );
109 test.clock.tick( 500 );
110 } );
111
112 $toggle.trigger( 'click' );
113 test.clock.tick( 500 );
114 } );
115
116 function tableWithCaptionTest( $collapsible, test, assert ) {
117 var $caption = $collapsible.find( 'caption' ),
118 $headerRow = $collapsible.find( 'tr:first' ),
119 $contentRow = $collapsible.find( 'tr:last' ),
120 $toggle = $caption.find( '.mw-collapsible-toggle' );
121
122 assert.equal( $toggle.length, 1, 'toggle is added to the end of the caption' );
123
124 assert.assertTrue( $caption.is( ':visible' ), 'caption is visible' );
125 assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
126 assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' );
127
128 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
129 assert.assertTrue( $caption.is( ':visible' ), 'after collapsing: caption is still visible' );
130 assert.assertTrue( $headerRow.is( ':hidden' ), 'after collapsing: headerRow is hidden' );
131 assert.assertTrue( $contentRow.is( ':hidden' ), 'after collapsing: contentRow is hidden' );
132
133 $collapsible.on( 'afterExpand.mw-collapsible', function () {
134 assert.assertTrue( $caption.is( ':visible' ), 'after expanding: caption is still visible' );
135 assert.assertTrue( $headerRow.is( ':visible' ), 'after expanding: headerRow is visible' );
136 assert.assertTrue( $contentRow.is( ':visible' ), 'after expanding: contentRow is visible' );
137 } );
138
139 $toggle.trigger( 'click' );
140 test.clock.tick( 500 );
141 } );
142
143 $toggle.trigger( 'click' );
144 test.clock.tick( 500 );
145 }
146
147 QUnit.test( 'basic operation (<table> with caption)', 10, function ( assert ) {
148 tableWithCaptionTest( prepareCollapsible(
149 '<table class="mw-collapsible">' +
150 '<caption>' + loremIpsum + '</caption>' +
151 '<tr><th>' + loremIpsum + '</th><th>' + loremIpsum + '</th></tr>' +
152 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
153 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
154 '</table>'
155 ), this, assert );
156 } );
157
158 QUnit.test( 'basic operation (<table> with caption and <thead>)', 10, function ( assert ) {
159 tableWithCaptionTest( prepareCollapsible(
160 '<table class="mw-collapsible">' +
161 '<caption>' + loremIpsum + '</caption>' +
162 '<thead><tr><th>' + loremIpsum + '</th><th>' + loremIpsum + '</th></tr></thead>' +
163 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
164 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
165 '</table>'
166 ), this, assert );
167 } );
168
169 function listTest( listType, test, assert ) {
170 var $collapsible = prepareCollapsible(
171 '<' + listType + ' class="mw-collapsible">' +
172 '<li>' + loremIpsum + '</li>' +
173 '<li>' + loremIpsum + '</li>' +
174 '</' + listType + '>'
175 ),
176 $toggleItem = $collapsible.find( 'li.mw-collapsible-toggle-li:first-child' ),
177 $contentItem = $collapsible.find( 'li:last' ),
178 $toggle = $toggleItem.find( '.mw-collapsible-toggle' );
179
180 assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' );
181
182 assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' );
183 assert.assertTrue( $contentItem.is( ':visible' ), 'contentItem is visible' );
184
185 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
186 assert.assertTrue( $toggleItem.is( ':visible' ), 'after collapsing: toggleItem is still visible' );
187 assert.assertTrue( $contentItem.is( ':hidden' ), 'after collapsing: contentItem is hidden' );
188
189 $collapsible.on( 'afterExpand.mw-collapsible', function () {
190 assert.assertTrue( $toggleItem.is( ':visible' ), 'after expanding: toggleItem is still visible' );
191 assert.assertTrue( $contentItem.is( ':visible' ), 'after expanding: contentItem is visible' );
192 } );
193
194 $toggle.trigger( 'click' );
195 test.clock.tick( 500 );
196 } );
197
198 $toggle.trigger( 'click' );
199 test.clock.tick( 500 );
200 }
201
202 QUnit.test( 'basic operation (<ul>)', 7, function ( assert ) {
203 listTest( 'ul', this, assert );
204 } );
205
206 QUnit.test( 'basic operation (<ol>)', 7, function ( assert ) {
207 listTest( 'ol', this, assert );
208 } );
209
210 QUnit.test( 'basic operation when synchronous (options.instantHide)', 2, function ( assert ) {
211 var $collapsible = prepareCollapsible(
212 '<div class="mw-collapsible">' + loremIpsum + '</div>',
213 { instantHide: true }
214 ),
215 $content = $collapsible.find( '.mw-collapsible-content' );
216
217 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
218
219 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
220
221 assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
222 } );
223
224 QUnit.test( 'mw-made-collapsible data added', 1, function ( assert ) {
225 var $collapsible = prepareCollapsible(
226 '<div>' + loremIpsum + '</div>'
227 );
228
229 assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' );
230 } );
231
232 QUnit.test( 'mw-collapsible added when missing', 1, function ( assert ) {
233 var $collapsible = prepareCollapsible(
234 '<div>' + loremIpsum + '</div>'
235 );
236
237 assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' );
238 } );
239
240 QUnit.test( 'mw-collapsed added when missing', 1, function ( assert ) {
241 var $collapsible = prepareCollapsible(
242 '<div>' + loremIpsum + '</div>',
243 { collapsed: true }
244 );
245
246 assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' );
247 } );
248
249 QUnit.test( 'initial collapse (mw-collapsed class)', 2, function ( assert ) {
250 var $collapsible = prepareCollapsible(
251 '<div class="mw-collapsible mw-collapsed">' + loremIpsum + '</div>'
252 ),
253 $content = $collapsible.find( '.mw-collapsible-content' );
254
255 // Synchronous - mw-collapsed should cause instantHide: true to be used on initial collapsing
256 assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
257
258 $collapsible.on( 'afterExpand.mw-collapsible', function () {
259 assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
260 } );
261
262 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
263 this.clock.tick( 500 );
264 } );
265
266 QUnit.test( 'initial collapse (options.collapsed)', 2, function ( assert ) {
267 var $collapsible = prepareCollapsible(
268 '<div class="mw-collapsible">' + loremIpsum + '</div>',
269 { collapsed: true }
270 ),
271 $content = $collapsible.find( '.mw-collapsible-content' );
272
273 // Synchronous - collapsed: true should cause instantHide: true to be used on initial collapsing
274 assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
275
276 $collapsible.on( 'afterExpand.mw-collapsible', function () {
277 assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
278 } );
279
280 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
281 this.clock.tick( 500 );
282 } );
283
284 QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)', 2, function ( assert ) {
285 var $collapsible = prepareCollapsible(
286 '<div class="mw-collapsible">' +
287 '<div class="mw-collapsible-toggle">' +
288 'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' +
289 '</div>' +
290 '<div class="mw-collapsible-content">' + loremIpsum + '</div>' +
291 '</div>',
292 // Can't do asynchronous because we're testing that the event *doesn't* happen
293 { instantHide: true }
294 ),
295 $content = $collapsible.find( '.mw-collapsible-content' );
296
297 $collapsible.find( '.mw-collapsible-toggle a' ).trigger( 'click' );
298 assert.assertTrue( $content.is( ':visible' ), 'click event on link inside toggle passes through (content not toggled)' );
299
300 $collapsible.find( '.mw-collapsible-toggle b' ).trigger( 'click' );
301 assert.assertTrue( $content.is( ':hidden' ), 'click event on non-link inside toggle toggles content' );
302 } );
303
304 QUnit.test( 'collapse/expand text (data-collapsetext, data-expandtext)', 2, function ( assert ) {
305 var $collapsible = prepareCollapsible(
306 '<div class="mw-collapsible" data-collapsetext="Collapse me!" data-expandtext="Expand me!">' +
307 loremIpsum +
308 '</div>'
309 ),
310 $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
311
312 assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' );
313
314 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
315 assert.equal( $toggleLink.text(), 'Expand me!', 'data-expandtext is respected' );
316 } );
317
318 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
319 this.clock.tick( 500 );
320 } );
321
322 QUnit.test( 'collapse/expand text (options.collapseText, options.expandText)', 2, function ( assert ) {
323 var $collapsible = prepareCollapsible(
324 '<div class="mw-collapsible">' + loremIpsum + '</div>',
325 { collapseText: 'Collapse me!', expandText: 'Expand me!' }
326 ),
327 $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
328
329 assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' );
330
331 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
332 assert.equal( $toggleLink.text(), 'Expand me!', 'options.expandText is respected' );
333 } );
334
335 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
336 this.clock.tick( 500 );
337 } );
338
339 QUnit.test( 'cloned collapsibles can be made collapsible again', 2, function ( assert ) {
340 var test = this,
341 $collapsible = prepareCollapsible(
342 '<div class="mw-collapsible">' + loremIpsum + '</div>'
343 ),
344 $clone = $collapsible.clone() // clone without data and events
345 .appendTo( '#qunit-fixture' ).makeCollapsible(),
346 $content = $clone.find( '.mw-collapsible-content' );
347
348 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
349
350 $clone.on( 'afterCollapse.mw-collapsible', function () {
351 assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
352 } );
353
354 $clone.find( '.mw-collapsible-toggle a' ).trigger( 'click' );
355 test.clock.tick( 500 );
356 } );
357 }( mediaWiki, jQuery ) );