Merge "Define 'MW_UPDATER' when running update.php"
[mediawiki.git] / tests / qunit / suites / resources / jquery / jquery.makeCollapsible.test.js
blob3c508d421c9efc3889d9bbabbaf6fa8638c6ef59
1 ( function ( mw, $ ) {
2         var loremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';
4         QUnit.module( 'jquery.makeCollapsible', QUnit.newMwEnvironment() );
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         }
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' );
22                 // In one full collapse-expand cycle, each event will be fired once
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' );
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' );
38                                 QUnit.start();
39                         } );
41                         // ...expanding happens here
42                         $toggle.trigger( 'click' );
43                 } );
45                 // ...collapsing happens here
46                 $toggle.trigger( 'click' );
47         } );
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' );
57                 assert.equal( $content.length, 1, 'content is present' );
58                 assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' );
60                 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
62                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
63                         assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
65                         $collapsible.on( 'afterExpand.mw-collapsible', function () {
66                                 assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
67                                 QUnit.start();
68                         } );
70                         $toggle.trigger( 'click' );
71                 } );
73                 $toggle.trigger( 'click' );
74         } );
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' );
88                 $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' );
89                 assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' );
91                 assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
92                 assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' );
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' );
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                         } );
104                         $toggle.trigger( 'click' );
105                 } );
107                 $toggle.trigger( 'click' );
108         } );
110         function tableWithCaptionTest( $collapsible, assert ) {
111                 var $caption, $headerRow, $contentRow, $toggle;
113                 $caption = $collapsible.find( 'caption' );
114                 $headerRow = $collapsible.find( 'tr:first' );
115                 $contentRow = $collapsible.find( 'tr:last' );
117                 $toggle = $caption.find( '.mw-collapsible-toggle' );
118                 assert.equal( $toggle.length, 1, 'toggle is added to the end of the caption' );
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' );
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' );
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                         } );
136                         $toggle.trigger( 'click' );
137                 } );
139                 $toggle.trigger( 'click' );
140         }
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         } );
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         } );
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' );
175                 $toggle = $toggleItem.find( '.mw-collapsible-toggle' );
176                 assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' );
178                 assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' );
179                 assert.assertTrue( $contentItem.is( ':visible' ), 'contentItem is visible' );
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' );
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                         } );
191                         $toggle.trigger( 'click' );
192                 } );
194                 $toggle.trigger( 'click' );
195         }
197         QUnit.asyncTest( 'basic operation (<ul>)', 7, function ( assert ) {
198                 listTest( 'ul', assert );
199         } );
201         QUnit.asyncTest( 'basic operation (<ol>)', 7, function ( assert ) {
202                 listTest( 'ol', assert );
203         } );
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' );
213                 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
215                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
217                 assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
218         } );
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         } );
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         } );
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         } );
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' );
252                 // Synchronous - mw-collapsed should cause instantHide: true to be used on initial collapsing
253                 assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
255                 $collapsible.on( 'afterExpand.mw-collapsible', function () {
256                         assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
257                         QUnit.start();
258                 } );
260                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
261         } );
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' );
271                 // Synchronous - collapsed: true should cause instantHide: true to be used on initial collapsing
272                 assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
274                 $collapsible.on( 'afterExpand.mw-collapsible', function () {
275                         assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
276                         QUnit.start();
277                 } );
279                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
280         } );
282         QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)' , 2, function ( assert ) {
283                 var $collapsible, $content;
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' );
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)' );
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         } );
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' );
313                 assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' );
315                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
316                         assert.equal( $toggleLink.text(), 'Expand me!', 'data-expandtext is respected' );
317                         QUnit.start();
318                 } );
320                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
321         } );
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' );
331                 assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' );
333                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
334                         assert.equal( $toggleLink.text(), 'Expand me!', 'options.expandText is respected' );
335                         QUnit.start();
336                 } );
338                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
339         } );
341 }( mediaWiki, jQuery ) );