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