jquery-tablesorter 1.19.4 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +2 -2
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +10 -10
  5. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +210 -108
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +151 -74
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +59 -34
  8. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +62 -32
  9. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +1 -1
  10. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +1 -1
  11. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +2 -2
  12. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +15 -12
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +6 -5
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +53 -28
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +1 -1
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +154 -76
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +9 -9
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +2 -2
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +3 -3
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +1 -1
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +2 -2
  22. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +1 -1
  23. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +2 -2
  24. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-view.js +2 -2
  25. metadata +2 -2
@@ -1,4 +1,4 @@
1
- /*! TableSorter (FORK) v2.24.6 *//*
1
+ /*! TableSorter (FORK) v2.25.0 *//*
2
2
  * Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
@@ -21,7 +21,7 @@
21
21
  'use strict';
22
22
  var ts = $.tablesorter = {
23
23
 
24
- version : '2.24.6',
24
+ version : '2.25.0',
25
25
 
26
26
  parsers : [],
27
27
  widgets : [],
@@ -62,6 +62,7 @@
62
62
 
63
63
  emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero, emptyMax, emptyMin
64
64
  stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero
65
+ duplicateSpan : true, // colspan cells in the tbody will have duplicated content in the cache for each spanned column
65
66
  textExtraction : 'basic', // text extraction method/function - function( node, table, cellIndex ){}
66
67
  textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in default textExtraction function)
67
68
  textSorter : null, // choose overall or specific column sorter function( a, b, direction, table, columnIndex ) [alt: ts.sortText]
@@ -209,7 +210,7 @@
209
210
  if ( table.hasInitialized ) {
210
211
  console.warn( 'Stopping initialization. Tablesorter has already been initialized' );
211
212
  } else {
212
- console.error( 'Stopping initialization! No table, thead or tbody' );
213
+ console.error( 'Stopping initialization! No table, thead or tbody', table );
213
214
  }
214
215
  }
215
216
  return;
@@ -332,7 +333,7 @@
332
333
  console.log( 'Overall initialization time: ' + ts.benchmark( $.data( table, 'startoveralltimer' ) ) );
333
334
  if ( c.debug && console.groupEnd ) { console.groupEnd(); }
334
335
  }
335
- $table.trigger( 'tablesorter-initialized', table );
336
+ $table.triggerHandler( 'tablesorter-initialized', table );
336
337
  if ( typeof c.initialized === 'function' ) {
337
338
  c.initialized( table );
338
339
  }
@@ -394,7 +395,7 @@
394
395
  })
395
396
  .bind( 'applyWidgetId' + namespace, function( e, id ) {
396
397
  e.stopPropagation();
397
- ts.getWidgetById( id ).format( this, this.config, this.config.widgetOptions );
398
+ ts.applyWidgetId( this, id );
398
399
  })
399
400
  .bind( 'applyWidgets' + namespace, function( e, init ) {
400
401
  e.stopPropagation();
@@ -405,6 +406,10 @@
405
406
  e.stopPropagation();
406
407
  ts.refreshWidgets( this, all, dontapply );
407
408
  })
409
+ .bind( 'removeWidget' + namespace, function( e, name, refreshing ) {
410
+ e.stopPropagation();
411
+ ts.removeWidget( this, name, refreshing );
412
+ })
408
413
  .bind( 'destroy' + namespace, function( e, removeClasses, callback ) {
409
414
  e.stopPropagation();
410
415
  ts.destroy( this, removeClasses, callback );
@@ -517,6 +522,7 @@
517
522
  timer = new Date();
518
523
  }
519
524
  // children tr in tfoot - see issue #196 & #547
525
+ // don't pass table.config to computeColumnIndex here - widgets (math) pass it to "quickly" index tbody cells
520
526
  c.columns = ts.computeColumnIndex( c.$table.children( 'thead, tfoot' ).children( 'tr' ) );
521
527
  // add icon if cssIcon option exists
522
528
  icon = c.cssIcon ?
@@ -556,7 +562,7 @@
556
562
  // this may get updated numerous times if there are multiple rows
557
563
  c.sortVars[ column ] = {
558
564
  count : -1, // set to -1 because clicking on the header automatically adds one
559
- order: ts.formatSortingOrder( tmp ) ?
565
+ order: ts.getOrder( tmp ) ?
560
566
  [ 1, 0, 2 ] : // desc, asc, unsorted
561
567
  [ 0, 1, 2 ], // asc, desc, unsorted
562
568
  lockedOrder : false
@@ -564,7 +570,7 @@
564
570
  tmp = ts.getData( $elem, configHeaders, 'lockedOrder' ) || false;
565
571
  if ( typeof tmp !== 'undefined' && tmp !== false ) {
566
572
  c.sortVars[ column ].lockedOrder = true;
567
- c.sortVars[ column ].order = ts.formatSortingOrder( tmp ) ? [ 1, 1, 1 ] : [ 0, 0, 0 ];
573
+ c.sortVars[ column ].order = ts.getOrder( tmp ) ? [ 1, 1, 1 ] : [ 0, 0, 0 ];
568
574
  }
569
575
  // add cell to headerList
570
576
  c.headerList[ index ] = elem;
@@ -687,6 +693,12 @@
687
693
  if ( span > 0 ) {
688
694
  colIndex += span;
689
695
  max += span;
696
+ while ( span + 1 > 0 ) {
697
+ // set colspan columns to use the same parsers & extractors
698
+ list.parsers[ colIndex - span ] = parser;
699
+ list.extractors[ colIndex - span ] = extractor;
700
+ span--;
701
+ }
690
702
  }
691
703
  }
692
704
  colIndex++;
@@ -829,7 +841,7 @@
829
841
  buildCache : function( c, callback, $tbodies ) {
830
842
  var cache, val, txt, rowIndex, colIndex, tbodyIndex, $tbody, $row,
831
843
  cols, $cells, cell, cacheTime, totalRows, rowData, prevRowData,
832
- colMax, span, cacheIndex, max, len,
844
+ colMax, span, cacheIndex, hasParser, max, len, index,
833
845
  table = c.table,
834
846
  parsers = c.parsers;
835
847
  // update tbody variable
@@ -904,22 +916,31 @@
904
916
  max = c.columns;
905
917
  for ( colIndex = 0; colIndex < max; ++colIndex ) {
906
918
  cell = $row[ 0 ].cells[ colIndex ];
907
- if ( typeof parsers[ cacheIndex ] === 'undefined' ) {
908
- if ( c.debug ) {
909
- console.warn( 'No parser found for column ' + colIndex + '; cell:', cell, 'does it have a header?' );
919
+ if ( cell && cacheIndex < c.columns ) {
920
+ hasParser = typeof parsers[ cacheIndex ] !== 'undefined';
921
+ if ( !hasParser && c.debug ) {
922
+ console.warn( 'No parser found for row: ' + rowIndex + ', column: ' + colIndex +
923
+ '; cell containing: "' + $(cell).text() + '"; does it have a header?' );
910
924
  }
911
- } else if ( cell ) {
912
925
  val = ts.getElementText( c, cell, cacheIndex );
913
926
  rowData.raw[ cacheIndex ] = val; // save original row text
927
+ // save raw column text even if there is no parser set
914
928
  txt = ts.getParsedText( c, cell, cacheIndex, val );
915
929
  cols[ cacheIndex ] = txt;
916
- if ( ( parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) {
930
+ if ( hasParser && ( parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) {
917
931
  // determine column max value (ignore sign)
918
932
  colMax[ cacheIndex ] = Math.max( Math.abs( txt ) || 0, colMax[ cacheIndex ] || 0 );
919
933
  }
920
934
  // allow colSpan in tbody
921
935
  span = cell.colSpan - 1;
922
936
  if ( span > 0 ) {
937
+ index = 0;
938
+ while ( index <= span ) {
939
+ // duplicate text (or not) to spanned columns
940
+ rowData.raw[ cacheIndex + index ] = c.duplicateSpan || index === 0 ? val : '';
941
+ cols[ cacheIndex + index ] = c.duplicateSpan || index === 0 ? val : '';
942
+ index++;
943
+ }
923
944
  cacheIndex += span;
924
945
  max += span;
925
946
  }
@@ -939,7 +960,21 @@
939
960
  ts.isProcessing( table ); // remove processing icon
940
961
  }
941
962
  if ( c.debug ) {
942
- console.log( 'Building cache for ' + totalRows + ' rows' + ts.benchmark( cacheTime ) );
963
+ len = Math.min( 5, c.cache[ 0 ].normalized.length );
964
+ console[ console.group ? 'group' : 'log' ]( 'Building cache for ' + c.totalRows +
965
+ ' rows (showing ' + len + ' rows in log)' + ts.benchmark( cacheTime ) );
966
+ val = {};
967
+ for ( colIndex = 0; colIndex < c.columns; colIndex++ ) {
968
+ for ( cacheIndex = 0; cacheIndex < len; cacheIndex++ ) {
969
+ if ( !val[ 'row: ' + cacheIndex ] ) {
970
+ val[ 'row: ' + cacheIndex ] = {};
971
+ }
972
+ val[ 'row: ' + cacheIndex ][ c.$headerIndexed[ colIndex ].text() ] =
973
+ c.cache[ 0 ].normalized[ cacheIndex ][ colIndex ];
974
+ }
975
+ }
976
+ console[ console.table ? 'table' : 'log' ]( val );
977
+ if ( console.groupEnd ) { console.groupEnd(); }
943
978
  }
944
979
  if ( $.isFunction( callback ) ) {
945
980
  callback( table );
@@ -1035,7 +1070,7 @@
1035
1070
  col = parseInt( $el.attr( 'data-column' ), 10 ),
1036
1071
  end = col + c.$headers[ i ].colSpan;
1037
1072
  for ( ; col < end; col++ ) {
1038
- include = include ? ts.isValueInArray( col, c.sortList ) > -1 : false;
1073
+ include = include ? include || ts.isValueInArray( col, c.sortList ) > -1 : false;
1039
1074
  }
1040
1075
  return include;
1041
1076
  });
@@ -1140,6 +1175,14 @@
1140
1175
  col = parseInt( val[ 0 ], 10 );
1141
1176
  // prevents error if sorton array is wrong
1142
1177
  if ( col < c.columns ) {
1178
+
1179
+ // set order if not already defined - due to colspan header without associated header cell
1180
+ // adding this check prevents a javascript error
1181
+ if ( !c.sortVars[ col ].order ) {
1182
+ order = c.sortVars[ col ].order = ts.getOrder( c.sortInitialOrder ) ? [ 1, 0, 2 ] : [ 0, 1, 2 ];
1183
+ c.sortVars[ col ].count = 0;
1184
+ }
1185
+
1143
1186
  order = c.sortVars[ col ].order;
1144
1187
  dir = ( '' + val[ 1 ] ).match( /^(1|d|s|o|n)/ );
1145
1188
  dir = dir ? dir[ 0 ] : '';
@@ -1200,6 +1243,12 @@
1200
1243
  },
1201
1244
 
1202
1245
  updateCell : function( c, cell, resort, callback ) {
1246
+ if ( ts.isEmptyObject( c.cache ) ) {
1247
+ // empty table, do an update instead - fixes #1099
1248
+ ts.updateHeader( c );
1249
+ ts.commonUpdate( c, resort, callback );
1250
+ return;
1251
+ }
1203
1252
  c.table.isUpdating = true;
1204
1253
  c.$table.find( c.selectorRemove ).remove();
1205
1254
  // get position from the dom
@@ -1250,6 +1299,11 @@
1250
1299
  // problems with element focus
1251
1300
  ts.resortComplete( c, callback );
1252
1301
  }
1302
+ } else {
1303
+ if ( c.debug ) {
1304
+ console.error( 'updateCell aborted, tbody missing or not within the indicated table' );
1305
+ }
1306
+ c.table.isUpdating = false;
1253
1307
  }
1254
1308
  },
1255
1309
 
@@ -1346,7 +1400,7 @@
1346
1400
  if ( ts.isEmptyObject( cache ) ) {
1347
1401
  // run pager appender in case the table was just emptied
1348
1402
  return c.appender ? c.appender( table, rows ) :
1349
- table.isUpdating ? c.$table.trigger( 'updateComplete', table ) : ''; // Fixes #532
1403
+ table.isUpdating ? c.$table.triggerHandler( 'updateComplete', table ) : ''; // Fixes #532
1350
1404
  }
1351
1405
  if ( c.debug ) {
1352
1406
  appendTime = new Date();
@@ -1380,7 +1434,7 @@
1380
1434
  ts.applyWidget( table );
1381
1435
  }
1382
1436
  if ( table.isUpdating ) {
1383
- c.$table.trigger( 'updateComplete', table );
1437
+ c.$table.triggerHandler( 'updateComplete', table );
1384
1438
  }
1385
1439
  },
1386
1440
 
@@ -1407,6 +1461,7 @@
1407
1461
  ts.initSort( c, cell, event );
1408
1462
  }, 50 );
1409
1463
  }
1464
+
1410
1465
  var arry, indx, headerIndx, dir, temp, tmp, $header,
1411
1466
  notMultiSort = !event[ c.sortMultiSortKey ],
1412
1467
  table = c.table,
@@ -1416,7 +1471,7 @@
1416
1471
  order = c.sortVars[ col ].order;
1417
1472
 
1418
1473
  // Only call sortStart if sorting is enabled
1419
- c.$table.trigger( 'sortStart', table );
1474
+ c.$table.triggerHandler( 'sortStart', table );
1420
1475
  // get current column sort order
1421
1476
  c.sortVars[ col ].count =
1422
1477
  event[ c.sortResetKey ] ? 2 : ( c.sortVars[ col ].count + 1 ) % ( c.sortReset ? 3 : 2 );
@@ -1527,14 +1582,15 @@
1527
1582
  }
1528
1583
  }
1529
1584
  // sortBegin event triggered immediately before the sort
1530
- c.$table.trigger( 'sortBegin', table );
1585
+ c.$table.triggerHandler( 'sortBegin', table );
1531
1586
  // setTimeout needed so the processing icon shows up
1532
1587
  setTimeout( function() {
1533
1588
  // set css for headers
1534
1589
  ts.setHeadersCss( c );
1535
1590
  ts.multisort( c );
1536
1591
  ts.appendCache( c );
1537
- c.$table.trigger( 'sortEnd', table );
1592
+ c.$table.triggerHandler( 'sortBeforeEnd', table );
1593
+ c.$table.triggerHandler( 'sortEnd', table );
1538
1594
  }, 1 );
1539
1595
  },
1540
1596
 
@@ -1610,7 +1666,7 @@
1610
1666
 
1611
1667
  resortComplete : function( c, callback ) {
1612
1668
  if ( c.table.isUpdating ) {
1613
- c.$table.trigger( 'updateComplete', c.table );
1669
+ c.$table.triggerHandler( 'updateComplete', c.table );
1614
1670
  }
1615
1671
  if ( $.isFunction( callback ) ) {
1616
1672
  callback( c.table );
@@ -1642,7 +1698,7 @@
1642
1698
 
1643
1699
  sortOn : function( c, list, callback, init ) {
1644
1700
  var table = c.table;
1645
- c.$table.trigger( 'sortStart', table );
1701
+ c.$table.triggerHandler( 'sortStart', table );
1646
1702
  // update header count index
1647
1703
  ts.updateHeaderSortCount( c, list );
1648
1704
  // set css for headers
@@ -1651,11 +1707,12 @@
1651
1707
  if ( c.delayInit && ts.isEmptyObject( c.cache ) ) {
1652
1708
  ts.buildCache( c );
1653
1709
  }
1654
- c.$table.trigger( 'sortBegin', table );
1710
+ c.$table.triggerHandler( 'sortBegin', table );
1655
1711
  // sort the table and append it to the dom
1656
1712
  ts.multisort( c );
1657
1713
  ts.appendCache( c, init );
1658
- c.$table.trigger( 'sortEnd', table );
1714
+ c.$table.triggerHandler( 'sortBeforeEnd', table );
1715
+ c.$table.triggerHandler( 'sortEnd', table );
1659
1716
  ts.applyWidget( table );
1660
1717
  if ( $.isFunction( callback ) ) {
1661
1718
  callback( table );
@@ -1676,7 +1733,7 @@
1676
1733
  return ( parsers && parsers[ column ] ) ? parsers[ column ].type || '' : '';
1677
1734
  },
1678
1735
 
1679
- formatSortingOrder : function( val ) {
1736
+ getOrder : function( val ) {
1680
1737
  // look for 'd' in 'desc' order; return true
1681
1738
  return ( /^d/i.test( val ) || val === 1 );
1682
1739
  },
@@ -1836,9 +1893,54 @@
1836
1893
  }
1837
1894
  },
1838
1895
 
1896
+ applyWidgetId : function( table, id, init ) {
1897
+ var applied, time, name,
1898
+ c = table.config,
1899
+ wo = c.widgetOptions,
1900
+ widget = ts.getWidgetById( id );
1901
+ if ( widget ) {
1902
+ name = widget.id;
1903
+ applied = false;
1904
+ // add widget name to option list so it gets reapplied after sorting, filtering, etc
1905
+ if ( $.inArray( name, c.widgets ) < 0 ) {
1906
+ c.widgets.push( name );
1907
+ }
1908
+ if ( c.debug ) { time = new Date(); }
1909
+
1910
+ if ( init || !( c.widgetInit[ name ] ) ) {
1911
+ // set init flag first to prevent calling init more than once (e.g. pager)
1912
+ c.widgetInit[ name ] = true;
1913
+ if ( table.hasInitialized ) {
1914
+ // don't reapply widget options on tablesorter init
1915
+ ts.applyWidgetOptions( table );
1916
+ }
1917
+ if ( typeof widget.init === 'function' ) {
1918
+ applied = true;
1919
+ if ( c.debug ) {
1920
+ console[ console.group ? 'group' : 'log' ]( 'Initializing ' + name + ' widget' );
1921
+ }
1922
+ widget.init( table, widget, c, wo );
1923
+ }
1924
+ }
1925
+ if ( !init && typeof widget.format === 'function' ) {
1926
+ applied = true;
1927
+ if ( c.debug ) {
1928
+ console[ console.group ? 'group' : 'log' ]( 'Updating ' + name + ' widget' );
1929
+ }
1930
+ widget.format( table, c, wo, false );
1931
+ }
1932
+ if ( c.debug ) {
1933
+ if ( applied ) {
1934
+ console.log( 'Completed ' + ( init ? 'initializing ' : 'applying ' ) + name + ' widget' + ts.benchmark( time ) );
1935
+ if ( console.groupEnd ) { console.groupEnd(); }
1936
+ }
1937
+ }
1938
+ }
1939
+ },
1940
+
1839
1941
  applyWidget : function( table, init, callback ) {
1840
1942
  table = $( table )[ 0 ]; // in case this is called externally
1841
- var indx, len, names, widget, name, applied, time, time2,
1943
+ var indx, len, names, widget, time,
1842
1944
  c = table.config,
1843
1945
  widgets = [];
1844
1946
  // prevent numerous consecutive widget applications
@@ -1877,39 +1979,8 @@
1877
1979
  }
1878
1980
  for ( indx = 0; indx < len; indx++ ) {
1879
1981
  widget = widgets[ indx ];
1880
- if ( widget ) {
1881
- name = widget.id;
1882
- applied = false;
1883
- if ( c.debug ) { time2 = new Date(); }
1884
-
1885
- if ( init || !( c.widgetInit[ name ] ) ) {
1886
- // set init flag first to prevent calling init more than once (e.g. pager)
1887
- c.widgetInit[ name ] = true;
1888
- if ( table.hasInitialized ) {
1889
- // don't reapply widget options on tablesorter init
1890
- ts.applyWidgetOptions( table );
1891
- }
1892
- if ( typeof widget.init === 'function' ) {
1893
- applied = true;
1894
- if ( c.debug ) {
1895
- console[ console.group ? 'group' : 'log' ]( 'Initializing ' + name + ' widget' );
1896
- }
1897
- widget.init( table, widget, table.config, table.config.widgetOptions );
1898
- }
1899
- }
1900
- if ( !init && typeof widget.format === 'function' ) {
1901
- applied = true;
1902
- if ( c.debug ) {
1903
- console[ console.group ? 'group' : 'log' ]( 'Updating ' + name + ' widget' );
1904
- }
1905
- widget.format( table, table.config, table.config.widgetOptions, false );
1906
- }
1907
- if ( c.debug ) {
1908
- if ( applied ) {
1909
- console.log( 'Completed ' + ( init ? 'initializing ' : 'applying ' ) + name + ' widget' + ts.benchmark( time2 ) );
1910
- if ( console.groupEnd ) { console.groupEnd(); }
1911
- }
1912
- }
1982
+ if ( widget && widget.id ) {
1983
+ ts.applyWidgetId( table, widget.id, init );
1913
1984
  }
1914
1985
  }
1915
1986
  if ( c.debug && console.groupEnd ) { console.groupEnd(); }
@@ -1921,7 +1992,7 @@
1921
1992
  c.timerReady = setTimeout( function() {
1922
1993
  table.isApplyingWidgets = false;
1923
1994
  $.data( table, 'lastWidgetApplication', new Date() );
1924
- c.$table.trigger( 'tablesorter-ready' );
1995
+ c.$table.triggerHandler( 'tablesorter-ready' );
1925
1996
  }, 10 );
1926
1997
  if ( c.debug ) {
1927
1998
  widget = c.widgets.length;
@@ -1977,7 +2048,7 @@
1977
2048
  len = widgets.length,
1978
2049
  list = [],
1979
2050
  callback = function( table ) {
1980
- $( table ).trigger( 'refreshComplete' );
2051
+ $( table ).triggerHandler( 'refreshComplete' );
1981
2052
  };
1982
2053
  // remove widgets not defined in config.widgets, unless doAll is true
1983
2054
  for ( indx = 0; indx < len; indx++ ) {
@@ -2066,17 +2137,17 @@
2066
2137
  // computeTableHeaderCellIndexes from:
2067
2138
  // http://www.javascripttoolbox.com/lib/table/examples.php
2068
2139
  // http://www.javascripttoolbox.com/temp/table_cellindex.html
2069
- computeColumnIndex : function( $rows ) {
2070
- var i, j, k, l, $cell, cell, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol,
2140
+ computeColumnIndex : function( $rows, c ) {
2141
+ var i, j, k, l, cell, cells, rowIndex, rowSpan, colSpan, firstAvailCol,
2142
+ // total columns has been calculated, use it to set the matrixrow
2143
+ columns = c && c.columns || 0,
2071
2144
  matrix = [],
2072
- matrixrow = [];
2145
+ matrixrow = new Array( columns );
2073
2146
  for ( i = 0; i < $rows.length; i++ ) {
2074
2147
  cells = $rows[ i ].cells;
2075
2148
  for ( j = 0; j < cells.length; j++ ) {
2076
2149
  cell = cells[ j ];
2077
- $cell = $( cell );
2078
2150
  rowIndex = cell.parentNode.rowIndex;
2079
- cellId = rowIndex + '-' + $cell.index();
2080
2151
  rowSpan = cell.rowSpan || 1;
2081
2152
  colSpan = cell.colSpan || 1;
2082
2153
  if ( typeof matrix[ rowIndex ] === 'undefined' ) {
@@ -2089,11 +2160,16 @@
2089
2160
  break;
2090
2161
  }
2091
2162
  }
2092
- // add data-column (setAttribute = IE8+)
2093
- if ( cell.setAttribute ) {
2163
+ // jscs:disable disallowEmptyBlocks
2164
+ if ( columns && cell.cellIndex === firstAvailCol ) {
2165
+ // don't to anything
2166
+ } else if ( cell.setAttribute ) {
2167
+ // jscs:enable disallowEmptyBlocks
2168
+ // add data-column (setAttribute = IE8+)
2094
2169
  cell.setAttribute( 'data-column', firstAvailCol );
2095
2170
  } else {
2096
- $cell.attr( 'data-column', firstAvailCol );
2171
+ // remove once we drop support for IE7 - 1/12/2016
2172
+ $( cell ).attr( 'data-column', firstAvailCol );
2097
2173
  }
2098
2174
  for ( k = rowIndex; k < rowIndex + rowSpan; k++ ) {
2099
2175
  if ( typeof matrix[ k ] === 'undefined' ) {
@@ -2302,15 +2378,16 @@
2302
2378
  $f = $t.find( 'tfoot:first > tr' ).children( 'th, td' );
2303
2379
  if ( removeClasses === false && $.inArray( 'uitheme', c.widgets ) >= 0 ) {
2304
2380
  // reapply uitheme classes, in case we want to maintain appearance
2305
- $t.trigger( 'applyWidgetId', [ 'uitheme' ] );
2306
- $t.trigger( 'applyWidgetId', [ 'zebra' ] );
2381
+ $t.triggerHandler( 'applyWidgetId', [ 'uitheme' ] );
2382
+ $t.triggerHandler( 'applyWidgetId', [ 'zebra' ] );
2307
2383
  }
2308
2384
  // remove widget added rows, just in case
2309
2385
  $h.find( 'tr' ).not( $r ).remove();
2310
- // disable tablesorter
2386
+ // disable tablesorter - not using .unbind( namespace ) because namespacing was
2387
+ // added in jQuery v1.4.3 - see http://api.jquery.com/event.namespace/
2311
2388
  events = 'sortReset update updateRows updateAll updateHeaders updateCell addRows updateComplete sorton ' +
2312
- 'appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress ' +
2313
- 'sortBegin sortEnd resetToLoadState '.split( ' ' )
2389
+ 'appendCache updateCache applyWidgetId applyWidgets refreshWidgets removeWidget destroy mouseup mouseleave ' +
2390
+ 'keypress sortBegin sortEnd resetToLoadState '.split( ' ' )
2314
2391
  .join( c.namespace + ' ' );
2315
2392
  $t
2316
2393
  .removeData( 'tablesorter' )