2 /*jshint onevar: false */
5 wgMonthNames
: ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
6 wgMonthNamesShort
: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
7 wgDefaultDateFormat
: 'dmy',
8 wgSeparatorTransformTable
: ['', ''],
9 wgDigitTransformTable
: ['', ''],
10 wgContentLanguage
: 'en'
13 QUnit
.module( 'jquery.tablesorter', QUnit
.newMwEnvironment( { config
: config
} ) );
16 * Create an HTML table from an array of row arrays containing text strings.
17 * First row will be header row. No fancy rowspan/colspan stuff.
19 * @param {String[]} header
20 * @param {String[][]} data
23 function tableCreate( header
, data
) {
25 $table
= $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
26 $thead
= $table
.find( 'thead' ),
27 $tbody
= $table
.find( 'tbody' ),
30 $.each( header
, function ( i
, str
) {
31 var $th
= $( '<th>' );
32 $th
.text( str
).appendTo( $tr
);
34 $tr
.appendTo( $thead
);
36 for ( i
= 0; i
< data
.length
; i
++ ) {
37 /*jshint loopfunc: true */
39 $.each( data
[i
], function ( j
, str
) {
40 var $td
= $( '<td>' );
41 $td
.text( str
).appendTo( $tr
);
43 $tr
.appendTo( $tbody
);
49 * Extract text from table.
51 * @param {jQuery} $table
54 function tableExtract( $table
) {
57 $table
.find( 'tbody' ).find( 'tr' ).each( function ( i
, tr
) {
59 $( tr
).find( 'td,th' ).each( function ( i
, td
) {
60 row
.push( $( td
).text() );
68 * Run a table test by building a table with the given data,
69 * running some callback on it, then checking the results.
71 * @param {String} msg text to pass on to qunit for the comparison
72 * @param {String[]} header cols to make the table
73 * @param {String[][]} data rows/cols to make the table
74 * @param {String[][]} expected rows/cols to compare against at end
75 * @param {function($table)} callback something to do with the table before we compare
77 function tableTest( msg
, header
, data
, expected
, callback
) {
78 QUnit
.test( msg
, 1, function ( assert
) {
79 var $table
= tableCreate( header
, data
);
81 // Give caller a chance to set up sorting and manipulate the table.
84 // Table sorting is done synchronously; if it ever needs to change back
85 // to asynchronous, we'll need a timeout or a callback here.
86 var extracted
= tableExtract( $table
);
87 assert
.deepEqual( extracted
, expected
, msg
);
92 * Run a table test by building a table with the given HTML,
93 * running some callback on it, then checking the results.
95 * @param {String} msg text to pass on to qunit for the comparison
96 * @param {String} HTML to make the table
97 * @param {String[][]} expected rows/cols to compare against at end
98 * @param {function($table)} callback something to do with the table before we compare
100 function tableTestHTML( msg
, html
, expected
, callback
) {
101 QUnit
.test( msg
, 1, function ( assert
) {
102 var $table
= $( html
);
104 // Give caller a chance to set up sorting and manipulate the table.
108 $table
.tablesorter();
109 $table
.find( '#sortme' ).click();
112 // Table sorting is done synchronously; if it ever needs to change back
113 // to asynchronous, we'll need a timeout or a callback here.
114 var extracted
= tableExtract( $table
);
115 assert
.deepEqual( extracted
, expected
, msg
);
119 function reversed( arr
) {
121 var arr2
= arr
.slice( 0 );
128 // Sample data set using planets named and their radius
129 var header
= [ 'Planet' , 'Radius (km)'],
130 mercury
= [ 'Mercury', '2439.7' ],
131 venus
= [ 'Venus' , '6051.8' ],
132 earth
= [ 'Earth' , '6371.0' ],
133 mars
= [ 'Mars' , '3390.0' ],
134 jupiter
= [ 'Jupiter', '69911' ],
135 saturn
= [ 'Saturn' , '58232' ];
138 var planets
= [mercury
, venus
, earth
, mars
, jupiter
, saturn
];
139 var ascendingName
= [earth
, jupiter
, mars
, mercury
, saturn
, venus
];
140 var ascendingRadius
= [mercury
, mars
, venus
, earth
, saturn
, jupiter
];
143 'Basic planet table: sorting initially - ascending by name',
147 function ( $table
) {
148 $table
.tablesorter( { sortList
: [
154 'Basic planet table: sorting initially - descending by radius',
157 reversed( ascendingRadius
),
158 function ( $table
) {
159 $table
.tablesorter( { sortList
: [
165 'Basic planet table: ascending by name',
169 function ( $table
) {
170 $table
.tablesorter();
171 $table
.find( '.headerSort:eq(0)' ).click();
175 'Basic planet table: ascending by name a second time',
179 function ( $table
) {
180 $table
.tablesorter();
181 $table
.find( '.headerSort:eq(0)' ).click();
185 'Basic planet table: descending by name',
188 reversed( ascendingName
),
189 function ( $table
) {
190 $table
.tablesorter();
191 $table
.find( '.headerSort:eq(0)' ).click().click();
195 'Basic planet table: ascending radius',
199 function ( $table
) {
200 $table
.tablesorter();
201 $table
.find( '.headerSort:eq(1)' ).click();
205 'Basic planet table: descending radius',
208 reversed( ascendingRadius
),
209 function ( $table
) {
210 $table
.tablesorter();
211 $table
.find( '.headerSort:eq(1)' ).click().click();
215 // Sample data set to test multiple column sorting
216 header
= [ 'column1' , 'column2'];
224 var initial
= [a2
, b3
, a1
, a3
, b2
, b1
];
225 var asc
= [a1
, a2
, a3
, b1
, b2
, b3
];
226 var descasc
= [b1
, b2
, b3
, a1
, a2
, a3
];
229 'Sorting multiple columns by passing sort list',
233 function ( $table
) {
243 'Sorting multiple columns by programmatically triggering sort()',
247 function ( $table
) {
248 $table
.tablesorter();
249 $table
.data( 'tablesorter' ).sort(
258 'Reset to initial sorting by triggering sort() without any parameters',
262 function ( $table
) {
269 $table
.data( 'tablesorter' ).sort(
275 $table
.data( 'tablesorter' ).sort();
278 QUnit
.test( 'Reset sorting making table appear unsorted', 3, function ( assert
) {
279 var $table
= tableCreate( header
, initial
);
286 $table
.data( 'tablesorter' ).sort( [] );
289 $table
.find( 'th.headerSortUp' ).length
+ $table
.find( 'th.headerSortDown' ).length
,
291 'No sort specific sort classes addign to header cells'
295 $table
.find( 'th' ).first().attr( 'title' ),
296 mw
.msg( 'sort-ascending' ),
297 'First header cell has default title'
301 $table
.find( 'th' ).first().attr( 'title' ),
302 $table
.find( 'th' ).last().attr( 'title' ),
303 'Both header cells\' titles match'
307 // Sorting with colspans
308 header
= [ 'column1a' , 'column1b', 'column1c', 'column2' ];
310 aaa1
= [ 'A', 'A', 'A', '1' ],
311 aab5
= [ 'A', 'A', 'B', '5' ],
312 abc3
= [ 'A', 'B', 'C', '3' ],
313 bbc2
= [ 'B', 'B', 'C', '2' ],
314 caa4
= [ 'C', 'A', 'A', '4' ];
315 // initial is already declared above
316 initial
= [ aab5
, aaa1
, abc3
, bbc2
, caa4
];
317 tableTest( 'Sorting with colspanned headers: spanned column',
320 [ aaa1
, aab5
, abc3
, bbc2
, caa4
],
321 function ( $table
) {
322 // Make colspanned header for test
323 $table
.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove();
324 $table
.find( 'tr:eq(0) th:eq(0)' ).prop( 'colspan', '3' );
326 $table
.tablesorter();
327 $table
.find( '.headerSort:eq(0)' ).click();
330 tableTest( 'Sorting with colspanned headers: subsequent column',
333 [ aaa1
, bbc2
, abc3
, caa4
, aab5
],
334 function ( $table
) {
335 // Make colspanned header for test
336 $table
.find( 'tr:eq(0) th:eq(1), tr:eq(0) th:eq(2)' ).remove();
337 $table
.find( 'tr:eq(0) th:eq(0)' ).prop( 'colspan', '3' );
339 $table
.tablesorter();
340 $table
.find( '.headerSort:eq(1)' ).click();
346 'Bug 28775: German-style (dmy) short numeric dates',
349 // German-style dates are day-month-year
357 // Sorted by ascending date
364 function ( $table
) {
365 mw
.config
.set( 'wgDefaultDateFormat', 'dmy' );
366 mw
.config
.set( 'wgContentLanguage', 'de' );
368 $table
.tablesorter();
369 $table
.find( '.headerSort:eq(0)' ).click();
374 'Bug 28775: American-style (mdy) short numeric dates',
377 // American-style dates are month-day-year
385 // Sorted by ascending date
392 function ( $table
) {
393 mw
.config
.set( 'wgDefaultDateFormat', 'mdy' );
395 $table
.tablesorter();
396 $table
.find( '.headerSort:eq(0)' ).click();
401 // Some randomly generated fake IPs
412 // Sort order should go octet by octet
424 'Bug 17141: IPv4 address sorting',
428 function ( $table
) {
429 $table
.tablesorter();
430 $table
.find( '.headerSort:eq(0)' ).click();
434 'Bug 17141: IPv4 address sorting (reverse)',
437 reversed( ipv4Sorted
),
438 function ( $table
) {
439 $table
.tablesorter();
440 $table
.find( '.headerSort:eq(0)' ).click().click();
445 // Some words with Umlauts
456 var umlautWordsSorted
= [
457 // Some words with Umlauts
469 'Accented Characters with custom collation',
473 function ( $table
) {
474 mw
.config
.set( 'tableSorterCollation', {
481 $table
.tablesorter();
482 $table
.find( '.headerSort:eq(0)' ).click();
486 QUnit
.test( 'Rowspan not exploded on init', 1, function ( assert
) {
487 var $table
= tableCreate( header
, planets
);
489 // Modify the table to have a multiple-row-spanning cell:
490 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
491 $table
.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
492 // - Set rowspan for 2nd cell of 3rd row to 3.
493 // This covers the removed cell in the 4th and 5th row.
494 $table
.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
496 $table
.tablesorter();
499 $table
.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan' ),
501 'Rowspan not exploded'
505 var planetsRowspan
= [
506 [ 'Earth', '6051.8' ],
508 [ 'Mars', '6051.8' ],
513 var planetsRowspanII
= [ jupiter
, mercury
, saturn
, venus
, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
516 'Basic planet table: same value for multiple rows via rowspan',
520 function ( $table
) {
521 // Modify the table to have a multiple-row-spanning cell:
522 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
523 $table
.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
524 // - Set rowspan for 2nd cell of 3rd row to 3.
525 // This covers the removed cell in the 4th and 5th row.
526 $table
.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
528 $table
.tablesorter();
529 $table
.find( '.headerSort:eq(0)' ).click();
533 'Basic planet table: same value for multiple rows via rowspan (sorting initially)',
537 function ( $table
) {
538 // Modify the table to have a multiple-row-spanning cell:
539 // - Remove 2nd cell of 4th row, and, 2nd cell or 5th row.
540 $table
.find( 'tr:eq(3) td:eq(1), tr:eq(4) td:eq(1)' ).remove();
541 // - Set rowspan for 2nd cell of 3rd row to 3.
542 // This covers the removed cell in the 4th and 5th row.
543 $table
.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
545 $table
.tablesorter( { sortList
: [
551 'Basic planet table: Same value for multiple rows via rowspan II',
555 function ( $table
) {
556 // Modify the table to have a multiple-row-spanning cell:
557 // - Remove 1st cell of 4th row, and, 1st cell or 5th row.
558 $table
.find( 'tr:eq(3) td:eq(0), tr:eq(4) td:eq(0)' ).remove();
559 // - Set rowspan for 1st cell of 3rd row to 3.
560 // This covers the removed cell in the 4th and 5th row.
561 $table
.find( 'tr:eq(2) td:eq(0)' ).prop( 'rowspan', '3' );
563 $table
.tablesorter();
564 $table
.find( '.headerSort:eq(0)' ).click();
568 var complexMDYDates
= [
569 // Some words with Umlauts
570 ['January, 19 2010'],
577 var complexMDYSorted
= [
581 ['January, 19 2010'],
586 'Complex date parsing I',
590 function ( $table
) {
591 mw
.config
.set( 'wgDefaultDateFormat', 'mdy' );
593 $table
.tablesorter();
594 $table
.find( '.headerSort:eq(0)' ).click();
598 var currencyUnsorted
= [
608 var currencySorted
= [
615 // Comma's sort after dots
616 // Not intentional but test to detect changes
621 'Currency parsing I',
625 function ( $table
) {
626 $table
.tablesorter();
627 $table
.find( '.headerSort:eq(0)' ).click();
631 var ascendingNameLegacy
= ascendingName
.slice( 0 );
632 ascendingNameLegacy
[4] = ascendingNameLegacy
[5];
633 ascendingNameLegacy
.pop();
636 'Legacy compat with .sortbottom',
640 function ( $table
) {
641 $table
.find( 'tr:last' ).addClass( 'sortbottom' );
642 $table
.tablesorter();
643 $table
.find( '.headerSort:eq(0)' ).click();
647 QUnit
.test( 'Test detection routine', 1, function ( assert
) {
650 '<table class="sortable">' +
651 '<caption>CAPTION</caption>' +
652 '<tr><th>THEAD</th></tr>' +
653 '<tr><td>1</td></tr>' +
654 '<tr class="sortbottom"><td>text</td></tr>' +
657 $table
.tablesorter();
658 $table
.find( '.headerSort:eq(0)' ).click();
661 $table
.data( 'tablesorter' ).config
.parsers
[0].id
,
663 'Correctly detected column content skipping sortbottom'
667 /** FIXME: the diff output is not very readeable. */
668 QUnit
.test( 'bug 32047 - caption must be before thead', 1, function ( assert
) {
671 '<table class="sortable">' +
672 '<caption>CAPTION</caption>' +
673 '<tr><th>THEAD</th></tr>' +
674 '<tr><td>A</td></tr>' +
675 '<tr><td>B</td></tr>' +
676 '<tr class="sortbottom"><td>TFOOT</td></tr>' +
679 $table
.tablesorter();
682 $table
.children().get( 0 ).nodeName
,
684 'First element after <thead> must be <caption> (bug 32047)'
688 QUnit
.test( 'data-sort-value attribute, when available, should override sorting position', 3, function ( assert
) {
691 // Example 1: All cells except one cell without data-sort-value,
692 // which should be sorted at it's text content value.
694 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
696 '<tr><td>Cheetah</td></tr>' +
697 '<tr><td data-sort-value="Apple">Bird</td></tr>' +
698 '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
699 '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
700 '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
703 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
706 $table
.find( 'tbody > tr' ).each( function ( i
, tr
) {
707 $( tr
).find( 'td' ).each( function ( i
, td
) {
709 data
: $( td
).data( 'sortValue' ),
715 assert
.deepEqual( data
, [
736 ], 'Order matches expected order (based on data-sort-value attribute values)' );
740 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
742 '<tr><td>D</td></tr>' +
743 '<tr><td data-sort-value="E">A</td></tr>' +
744 '<tr><td>B</td></tr>' +
745 '<tr><td>G</td></tr>' +
746 '<tr><td data-sort-value="F">C</td></tr>' +
749 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
752 $table
.find( 'tbody > tr' ).each( function ( i
, tr
) {
753 $( tr
).find( 'td' ).each( function ( i
, td
) {
755 data
: $( td
).data( 'sortValue' ),
761 assert
.deepEqual( data
, [
782 ], 'Order matches expected order (based on data-sort-value attribute values)' );
784 // Example 3: Test that live changes are used from data-sort-value,
785 // even if they change after the tablesorter is constructed (bug 38152).
787 '<table class="sortable"><thead><tr><th>Data</th></tr></thead>' +
789 '<tr><td>D</td></tr>' +
790 '<tr><td data-sort-value="1">A</td></tr>' +
791 '<tr><td>B</td></tr>' +
792 '<tr><td data-sort-value="2">G</td></tr>' +
793 '<tr><td>C</td></tr>' +
796 // initialize table sorter and sort once
799 .find( '.headerSort:eq(0)' ).click();
801 // Change the sortValue data properties (bug 38152)
803 $table
.find( 'td:contains(A)' ).data( 'sortValue', 3 );
805 $table
.find( 'td:contains(B)' ).data( 'sortValue', 1 );
806 // - remove data, bring back attribute: 2
807 $table
.find( 'td:contains(G)' ).removeData( 'sortValue' );
809 // Now sort again (twice, so it is back at Ascending)
810 $table
.find( '.headerSort:eq(0)' ).click();
811 $table
.find( '.headerSort:eq(0)' ).click();
814 $table
.find( 'tbody > tr' ).each( function ( i
, tr
) {
815 $( tr
).find( 'td' ).each( function ( i
, td
) {
817 data
: $( td
).data( 'sortValue' ),
823 assert
.deepEqual( data
, [
844 ], 'Order matches expected order, using the current sortValue in $.data()' );
865 tableTest( 'bug 8115: sort numbers with commas (ascending)',
866 ['Numbers'], numbers
, numbersAsc
,
867 function ( $table
) {
868 $table
.tablesorter();
869 $table
.find( '.headerSort:eq(0)' ).click();
873 tableTest( 'bug 8115: sort numbers with commas (descending)',
874 ['Numbers'], numbers
, reversed( numbersAsc
),
875 function ( $table
) {
876 $table
.tablesorter();
877 $table
.find( '.headerSort:eq(0)' ).click().click();
880 // TODO add numbers sorting tests for bug 8115 with a different language
882 QUnit
.test( 'bug 32888 - Tables inside a tableheader cell', 2, function ( assert
) {
885 '<table class="sortable" id="mw-bug-32888">' +
886 '<tr><th>header<table id="mw-bug-32888-2">' +
887 '<tr><th>1</th><th>2</th></tr>' +
888 '</table></th></tr>' +
889 '<tr><td>A</td></tr>' +
890 '<tr><td>B</td></tr>' +
893 $table
.tablesorter();
896 $table
.find( '> thead:eq(0) > tr > th.headerSort' ).length
,
898 'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
901 $( '#mw-bug-32888-2' ).find( 'th.headerSort' ).length
,
903 'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'
908 var correctDateSorting1
= [
910 ['05 February 2010'],
914 var correctDateSortingSorted1
= [
921 'Correct date sorting I',
924 correctDateSortingSorted1
,
925 function ( $table
) {
926 mw
.config
.set( 'wgDefaultDateFormat', 'mdy' );
928 $table
.tablesorter();
929 $table
.find( '.headerSort:eq(0)' ).click();
933 var correctDateSorting2
= [
935 ['February 05 2010'],
939 var correctDateSortingSorted2
= [
946 'Correct date sorting II',
949 correctDateSortingSorted2
,
950 function ( $table
) {
951 mw
.config
.set( 'wgDefaultDateFormat', 'dmy' );
953 $table
.tablesorter();
954 $table
.find( '.headerSort:eq(0)' ).click();
958 QUnit
.test( 'Sorting images using alt text', 1, function ( assert
) {
960 '<table class="sortable">' +
961 '<tr><th>THEAD</th></tr>' +
962 '<tr><td><img alt="2"/></td></tr>' +
963 '<tr><td>1</td></tr>' +
966 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
969 $table
.find( 'td' ).first().text(),
971 'Applied correct sorting order'
975 QUnit
.test( 'Sorting images using alt text (complex)', 1, function ( assert
) {
977 '<table class="sortable">' +
978 '<tr><th>THEAD</th></tr>' +
979 '<tr><td><img alt="D" />A</td></tr>' +
980 '<tr><td>CC</td></tr>' +
981 '<tr><td><a><img alt="A" /></a>F</tr>' +
982 '<tr><td><img alt="A" /><strong>E</strong></tr>' +
983 '<tr><td><strong><img alt="A" />D</strong></tr>' +
984 '<tr><td><img alt="A" />C</tr>' +
987 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
990 $table
.find( 'td' ).text(),
992 'Applied correct sorting order'
996 QUnit
.test( 'Sorting images using alt text (with format autodetection)', 1, function ( assert
) {
998 '<table class="sortable">' +
999 '<tr><th>THEAD</th></tr>' +
1000 '<tr><td><img alt="1" />7</td></tr>' +
1001 '<tr><td>1<img alt="6" /></td></tr>' +
1002 '<tr><td>5</td></tr>' +
1003 '<tr><td>4</td></tr>' +
1006 $table
.tablesorter().find( '.headerSort:eq(0)' ).click();
1009 $table
.find( 'td' ).text(),
1011 'Applied correct sorting order'
1015 // bug 41889 - exploding rowspans in more complex cases
1017 'Rowspan exploding with row headers',
1018 '<table class="sortable">' +
1019 '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th></tr></thead>' +
1021 '<tr><td>1</td><th rowspan="2">foo</th><td rowspan="2">bar</td><td>baz</td></tr>' +
1022 '<tr><td>2</td><td>baz</td></tr>' +
1025 [ '1', 'foo', 'bar', 'baz' ],
1026 [ '2', 'foo', 'bar', 'baz' ]
1031 'Rowspan exploding with colspanned cells',
1032 '<table class="sortable">' +
1033 '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th></tr></thead>' +
1035 '<tr><td>1</td><td>foo</td><td>bar</td><td rowspan="2">baz</td></tr>' +
1036 '<tr><td>2</td><td colspan="2">foobar</td></tr>' +
1039 [ '1', 'foo', 'bar', 'baz' ],
1040 [ '2', 'foobar', 'baz' ]
1045 'Rowspan exploding with colspanned cells (2)',
1046 '<table class="sortable">' +
1047 '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th><th>quux</th></tr></thead>' +
1049 '<tr><td>1</td><td>foo</td><td>bar</td><td rowspan="2">baz</td><td>quux</td></tr>' +
1050 '<tr><td>2</td><td colspan="2">foobar</td><td>quux</td></tr>' +
1053 [ '1', 'foo', 'bar', 'baz', 'quux' ],
1054 [ '2', 'foobar', 'baz', 'quux' ]
1059 'Rowspan exploding with rightmost rows spanning most',
1060 '<table class="sortable">' +
1061 '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th></tr></thead>' +
1063 '<tr><td>1</td><td rowspan="2">foo</td><td rowspan="4">bar</td></tr>' +
1064 '<tr><td>2</td></tr>' +
1065 '<tr><td>3</td><td rowspan="2">foo</td></tr>' +
1066 '<tr><td>4</td></tr>' +
1069 [ '1', 'foo', 'bar' ],
1070 [ '2', 'foo', 'bar' ],
1071 [ '3', 'foo', 'bar' ],
1072 [ '4', 'foo', 'bar' ]
1077 'Rowspan exploding with rightmost rows spanning most (2)',
1078 '<table class="sortable">' +
1079 '<thead><tr><th id="sortme">n</th><th>foo</th><th>bar</th><th>baz</th></tr></thead>' +
1081 '<tr><td>1</td><td rowspan="2">foo</td><td rowspan="4">bar</td><td>baz</td></tr>' +
1082 '<tr><td>2</td><td>baz</td></tr>' +
1083 '<tr><td>3</td><td rowspan="2">foo</td><td>baz</td></tr>' +
1084 '<tr><td>4</td><td>baz</td></tr>' +
1087 [ '1', 'foo', 'bar', 'baz' ],
1088 [ '2', 'foo', 'bar', 'baz' ],
1089 [ '3', 'foo', 'bar', 'baz' ],
1090 [ '4', 'foo', 'bar', 'baz' ]
1095 'Rowspan exploding with row-and-colspanned cells',
1096 '<table class="sortable">' +
1097 '<thead><tr><th id="sortme">n</th><th>foo1</th><th>foo2</th><th>bar</th><th>baz</th></tr></thead>' +
1099 '<tr><td>1</td><td rowspan="2">foo1</td><td rowspan="2">foo2</td><td rowspan="4">bar</td><td>baz</td></tr>' +
1100 '<tr><td>2</td><td>baz</td></tr>' +
1101 '<tr><td>3</td><td colspan="2" rowspan="2">foo</td><td>baz</td></tr>' +
1102 '<tr><td>4</td><td>baz</td></tr>' +
1105 [ '1', 'foo1', 'foo2', 'bar', 'baz' ],
1106 [ '2', 'foo1', 'foo2', 'bar', 'baz' ],
1107 [ '3', 'foo', 'bar', 'baz' ],
1108 [ '4', 'foo', 'bar', 'baz' ]
1113 'Rowspan exploding with uneven rowspan layout',
1114 '<table class="sortable">' +
1115 '<thead><tr><th id="sortme">n</th><th>foo1</th><th>foo2</th><th>foo3</th><th>bar</th><th>baz</th></tr></thead>' +
1117 '<tr><td>1</td><td rowspan="2">foo1</td><td rowspan="2">foo2</td><td rowspan="2">foo3</td><td>bar</td><td>baz</td></tr>' +
1118 '<tr><td>2</td><td rowspan="3">bar</td><td>baz</td></tr>' +
1119 '<tr><td>3</td><td rowspan="2">foo1</td><td rowspan="2">foo2</td><td rowspan="2">foo3</td><td>baz</td></tr>' +
1120 '<tr><td>4</td><td>baz</td></tr>' +
1123 [ '1', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ],
1124 [ '2', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ],
1125 [ '3', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ],
1126 [ '4', 'foo1', 'foo2', 'foo3', 'bar', 'baz' ]
1130 }( jQuery
, mediaWiki
) );