jquery-tablesorter 1.23.15 → 1.24.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0174cfbb069870781ff7190466a647e1c2adef6d
4
- data.tar.gz: 1c3148a7b59d0668953057219e279d5b4c2613b1
3
+ metadata.gz: fd2f6d679b0523149759cc69b1b95cb25ca39e65
4
+ data.tar.gz: 86b19e6a3167c07baf0d90e3ab2d8993da19c625
5
5
  SHA512:
6
- metadata.gz: 81c10902e944af29caa6b34b187a889212fabe87eb89147562cb8c2ac9472129474acd8d614e8f71eddeac3527d4d3cf73ee062dd4a3c914d621e2f1981660f4
7
- data.tar.gz: ca0b113781b19faf0bab7b4b49a67cd93a76f1bfe89edceebe79ee28c66988009b65e3f169c7a44e947c211022a63811cb8210895803627fc42fabd023194451
6
+ metadata.gz: f26ac12515b165ac9e47c2cefac141a377a48f1d00be50f71bf62afc75a767d0b6ff795e3564f70465de4129119c9d3b81c2136d984edaced5fd2b9695bb6c55
7
+ data.tar.gz: bb9343e62a716614e84c5ba8f450d25af4d1c6e965e02fecc2a35b7ace98654f1e7ab5025a7f9f87421c3ff075d46caa0b630ae8ccf593076394338809bd423a
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Simple integration of jQuery tablesorter ([Mottie's fork]) into the asset pipeline.
6
6
 
7
- Current tablesorter version: 2.28.15 (7/4/2017) [documentation]
7
+ Current tablesorter version: 2.29.0 (9/27/2017) [documentation]
8
8
 
9
9
  Any issue associated with the js/css files, please report to [Mottie's fork].
10
10
 
@@ -1,7 +1,7 @@
1
1
  module JqueryTablesorter
2
2
  MAJOR = 1
3
- MINOR = 23
4
- TINY = 15
3
+ MINOR = 24
4
+ TINY = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].compact.join('.')
7
7
  end
@@ -4,7 +4,7 @@
4
4
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀██
5
5
  █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
6
6
  */
7
- /*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
7
+ /*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
8
8
  /* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
9
9
  (function(factory) {
10
10
  if (typeof define === 'function' && define.amd) {
@@ -16,7 +16,7 @@
16
16
  }
17
17
  }(function(jQuery) {
18
18
 
19
- /*! TableSorter (FORK) v2.28.15 *//*
19
+ /*! TableSorter (FORK) v2.29.0 *//*
20
20
  * Client-side table sorting with ease!
21
21
  * @requires jQuery v1.2.6+
22
22
  *
@@ -40,7 +40,7 @@
40
40
  'use strict';
41
41
  var ts = $.tablesorter = {
42
42
 
43
- version : '2.28.15',
43
+ version : '2.29.0',
44
44
 
45
45
  parsers : [],
46
46
  widgets : [],
@@ -439,10 +439,10 @@
439
439
  e.stopPropagation();
440
440
  ts.applyWidgetId( this, id );
441
441
  })
442
- .bind( 'applyWidgets' + namespace, function( e, init ) {
442
+ .bind( 'applyWidgets' + namespace, function( e, callback ) {
443
443
  e.stopPropagation();
444
- // apply widgets
445
- ts.applyWidget( this, init );
444
+ // apply widgets (false = not initializing)
445
+ ts.applyWidget( this, false, callback );
446
446
  })
447
447
  .bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
448
448
  e.stopPropagation();
@@ -479,9 +479,9 @@
479
479
  downTarget = null;
480
480
  if ( core !== true ) {
481
481
  $headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
482
- tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
483
- if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
484
- $( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
482
+ tmp = ts.getClosest( $headers, 'table' );
483
+ if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
484
+ $( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
485
485
  }
486
486
  }
487
487
  tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@@ -533,8 +533,7 @@
533
533
  ts.buildCache( c );
534
534
  }
535
535
  // jQuery v1.2.6 doesn't have closest()
536
- $cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
537
- /TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
536
+ $cell = ts.getHeaderCell( $( this ) );
538
537
  // reference original table headers and find the same cell
539
538
  // don't use $headers or IE8 throws an error - see #987
540
539
  temp = $headers.index( $cell );
@@ -574,7 +573,7 @@
574
573
  '';
575
574
  // redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
576
575
  c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
577
- var configHeaders, header, column, template, tmp,
576
+ var configHeaders, header, column, template, tmp, $th,
578
577
  $elem = $( elem );
579
578
  // ignore cell (don't add it to c.$headers) if row has ignoreRow class
580
579
  if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@@ -600,7 +599,9 @@
600
599
  if ( c.onRenderHeader ) {
601
600
  c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
602
601
  }
603
- column = parseInt( $elem.attr( 'data-column' ), 10 );
602
+ // data-column stored on th or td only
603
+ $th = ts.getHeaderCell( $elem );
604
+ column = parseInt( $th.attr( 'data-column' ), 10 );
604
605
  elem.column = column;
605
606
  tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
606
607
  // this may get updated numerous times if there are multiple rows
@@ -618,10 +619,9 @@
618
619
  }
619
620
  // add cell to headerList
620
621
  c.headerList[ index ] = elem;
622
+ $elem.addClass( ts.css.header + ' ' + c.cssHeader );
621
623
  // add to parent in case there are multiple rows
622
- $elem
623
- .addClass( ts.css.header + ' ' + c.cssHeader )
624
- .parent()
624
+ ts.getClosest( $elem, 'tr' )
625
625
  .addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
626
626
  .attr( 'role', 'row' );
627
627
  // allow keyboard cursor to focus on element
@@ -1179,10 +1179,29 @@
1179
1179
  }
1180
1180
  },
1181
1181
 
1182
+ // This function does NOT return closest if the $el matches the selector
1183
+ getClosest : function( $el, selector ) {
1184
+ return $.fn.closest ?
1185
+ $el.closest( selector ) :
1186
+ $el.parents( selector ).filter( ':first' );
1187
+ },
1188
+
1189
+ getHeaderCell : function( $el ) {
1190
+ // jQuery v1.2.6 doesn't have closest()
1191
+ if ( $.fn.closest ) {
1192
+ return $el.closest( 'th, td' );
1193
+ }
1194
+ return /TH|TD/.test( $el[0].nodeName ) ?
1195
+ $el :
1196
+ $el.parents( 'th, td' ).filter( ':first' );
1197
+ },
1198
+
1182
1199
  // nextSort (optional), lets you disable next sort text
1183
1200
  setColumnAriaLabel : function( c, $header, nextSort ) {
1184
1201
  if ( $header.length ) {
1185
- var column = parseInt( $header.attr( 'data-column' ), 10 ),
1202
+ var $th = ts.getHeaderCell( $header ),
1203
+ // data-column always stored on the th/td
1204
+ column = parseInt( $th.attr( 'data-column' ), 10 ),
1186
1205
  vars = c.sortVars[ column ],
1187
1206
  tmp = $header.hasClass( ts.css.sortAsc ) ?
1188
1207
  'sortAsc' :
@@ -1340,10 +1359,9 @@
1340
1359
  $cell = $( cell ),
1341
1360
  // update cache - format: function( s, table, cell, cellIndex )
1342
1361
  // no closest in jQuery v1.2.6
1343
- tbodyIndex = $tbodies
1344
- .index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
1362
+ tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
1345
1363
  tbcache = c.cache[ tbodyIndex ],
1346
- $row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
1364
+ $row = ts.getClosest( $cell, 'tr' );
1347
1365
  cell = $cell[ 0 ]; // in case cell is a jQuery object
1348
1366
  // tbody may not exist if update is initialized while tbody is removed for processing
1349
1367
  if ( $tbodies.length && tbodyIndex >= 0 ) {
@@ -1398,11 +1416,13 @@
1398
1416
  if ( valid ) {
1399
1417
  $row = $( $row );
1400
1418
  c.$tbodies.append( $row );
1401
- } else if ( !$row ||
1419
+ } else if (
1420
+ !$row ||
1402
1421
  // row is a jQuery object?
1403
1422
  !( $row instanceof jQuery ) ||
1404
1423
  // row contained in the table?
1405
- ( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
1424
+ ( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
1425
+ ) {
1406
1426
  if ( c.debug ) {
1407
1427
  console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
1408
1428
  'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@@ -1549,10 +1569,10 @@
1549
1569
  notMultiSort = !event[ c.sortMultiSortKey ],
1550
1570
  table = c.table,
1551
1571
  len = c.$headers.length,
1552
- // get current column index
1553
- col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
1572
+ // get current column index; *always* stored on th/td
1573
+ $th = ts.getHeaderCell( $( cell ) ),
1574
+ col = parseInt( $th.attr( 'data-column' ), 10 ),
1554
1575
  order = c.sortVars[ col ].order;
1555
-
1556
1576
  // Only call sortStart if sorting is enabled
1557
1577
  c.$table.triggerHandler( 'sortStart', table );
1558
1578
  // get current column sort order
@@ -2076,7 +2096,7 @@
2076
2096
  if ( !widget.priority ) { widget.priority = 10; }
2077
2097
  widgets[ indx ] = widget;
2078
2098
  } else if ( c.debug ) {
2079
- console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
2099
+ console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
2080
2100
  }
2081
2101
  }
2082
2102
  // sort widgets by priority
@@ -2148,6 +2168,7 @@
2148
2168
  c.widgetInit[ name[ index ] ] = false;
2149
2169
  }
2150
2170
  }
2171
+ c.$table.triggerHandler( 'widgetRemoveEnd', table );
2151
2172
  },
2152
2173
 
2153
2174
  refreshWidgets : function( table, doAll, dontapply ) {
@@ -2999,7 +3020,7 @@
2999
3020
 
3000
3021
  })(jQuery, window, document);
3001
3022
 
3002
- /*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
3023
+ /*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
3003
3024
  ;(function ($) {
3004
3025
  'use strict';
3005
3026
  var ts = $.tablesorter || {};
@@ -3016,10 +3037,10 @@
3016
3037
  active : '', // applied when column is sorted
3017
3038
  hover : '', // custom css required - a defined bootstrap style may not override other classes
3018
3039
  // icon class names
3019
- icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
3040
+ icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
3020
3041
  iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
3021
- iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
3022
- iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
3042
+ iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
3043
+ iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
3023
3044
  filterRow : '', // filter row class
3024
3045
  footerRow : '',
3025
3046
  footerCells : '',
@@ -5202,7 +5223,7 @@
5202
5223
 
5203
5224
  })( jQuery );
5204
5225
 
5205
- /*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
5226
+ /*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
5206
5227
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
5207
5228
  * by Rob Garrison
5208
5229
  */
@@ -5354,10 +5375,14 @@
5354
5375
  });
5355
5376
  }
5356
5377
  },
5378
+ getLeftPosition = function() {
5379
+ return $attach.length ?
5380
+ parseInt($attach.css('padding-left'), 10) || 0 :
5381
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
5382
+ },
5357
5383
  resizeHeader = function() {
5358
5384
  $stickyWrap.css({
5359
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
5360
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
5385
+ left : getLeftPosition(),
5361
5386
  width: $table.outerWidth()
5362
5387
  });
5363
5388
  setWidth( $table, $stickyTable );
@@ -5367,10 +5392,10 @@
5367
5392
  if (!$table.is(':visible')) { return; } // fixes #278
5368
5393
  // Detect nested tables - fixes #724
5369
5394
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
5370
- var offset = $table.offset(),
5395
+ var tmp,
5396
+ offset = $table.offset(),
5371
5397
  stickyOffset = getStickyOffset(c, wo),
5372
5398
  yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
5373
- xWindow = $.isWindow( $xScroll[0] ),
5374
5399
  attachTop = $attach.length ?
5375
5400
  ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
5376
5401
  $yScroll.scrollTop(),
@@ -5378,19 +5403,27 @@
5378
5403
  scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
5379
5404
  tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
5380
5405
  isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
5406
+ state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
5407
+ needsUpdating = !$stickyWrap.hasClass( state ),
5381
5408
  cssSettings = { visibility : isVisible };
5382
5409
  if ($attach.length) {
5410
+ // attached sticky headers always need updating
5411
+ needsUpdating = true;
5383
5412
  cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
5384
5413
  }
5385
- if (xWindow) {
5386
- // adjust when scrolling horizontally - fixes issue #143
5387
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
5414
+ // adjust when scrolling horizontally - fixes issue #143
5415
+ tmp = getLeftPosition();
5416
+ if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
5417
+ needsUpdating = true;
5418
+ cssSettings.left = tmp;
5388
5419
  }
5389
5420
  cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
5390
- $stickyWrap
5391
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
5392
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
5393
- .css(cssSettings);
5421
+ if (needsUpdating) {
5422
+ $stickyWrap
5423
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
5424
+ .addClass( state )
5425
+ .css(cssSettings);
5426
+ }
5394
5427
  if (isVisible !== laststate || resizing) {
5395
5428
  // make sure the column widths match
5396
5429
  resizeHeader();
@@ -5509,7 +5542,7 @@
5509
5542
 
5510
5543
  })(jQuery, window);
5511
5544
 
5512
- /*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
5545
+ /*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
5513
5546
  /*jshint browser:true, jquery:true, unused:false */
5514
5547
  ;(function ($, window) {
5515
5548
  'use strict';
@@ -5836,6 +5869,7 @@
5836
5869
  vars.$target = vars.$next = null;
5837
5870
  // will update stickyHeaders, just in case, see #912
5838
5871
  c.$table.triggerHandler('stickyHeadersUpdate');
5872
+ c.$table.triggerHandler('resizableComplete');
5839
5873
  }
5840
5874
  };
5841
5875
 
@@ -1,4 +1,4 @@
1
- /*! TableSorter (FORK) v2.28.15 *//*
1
+ /*! TableSorter (FORK) v2.29.0 *//*
2
2
  * Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
@@ -22,7 +22,7 @@
22
22
  'use strict';
23
23
  var ts = $.tablesorter = {
24
24
 
25
- version : '2.28.15',
25
+ version : '2.29.0',
26
26
 
27
27
  parsers : [],
28
28
  widgets : [],
@@ -421,10 +421,10 @@
421
421
  e.stopPropagation();
422
422
  ts.applyWidgetId( this, id );
423
423
  })
424
- .bind( 'applyWidgets' + namespace, function( e, init ) {
424
+ .bind( 'applyWidgets' + namespace, function( e, callback ) {
425
425
  e.stopPropagation();
426
- // apply widgets
427
- ts.applyWidget( this, init );
426
+ // apply widgets (false = not initializing)
427
+ ts.applyWidget( this, false, callback );
428
428
  })
429
429
  .bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
430
430
  e.stopPropagation();
@@ -461,9 +461,9 @@
461
461
  downTarget = null;
462
462
  if ( core !== true ) {
463
463
  $headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
464
- tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
465
- if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
466
- $( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
464
+ tmp = ts.getClosest( $headers, 'table' );
465
+ if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
466
+ $( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
467
467
  }
468
468
  }
469
469
  tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@@ -515,8 +515,7 @@
515
515
  ts.buildCache( c );
516
516
  }
517
517
  // jQuery v1.2.6 doesn't have closest()
518
- $cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
519
- /TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
518
+ $cell = ts.getHeaderCell( $( this ) );
520
519
  // reference original table headers and find the same cell
521
520
  // don't use $headers or IE8 throws an error - see #987
522
521
  temp = $headers.index( $cell );
@@ -556,7 +555,7 @@
556
555
  '';
557
556
  // redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
558
557
  c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
559
- var configHeaders, header, column, template, tmp,
558
+ var configHeaders, header, column, template, tmp, $th,
560
559
  $elem = $( elem );
561
560
  // ignore cell (don't add it to c.$headers) if row has ignoreRow class
562
561
  if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@@ -582,7 +581,9 @@
582
581
  if ( c.onRenderHeader ) {
583
582
  c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
584
583
  }
585
- column = parseInt( $elem.attr( 'data-column' ), 10 );
584
+ // data-column stored on th or td only
585
+ $th = ts.getHeaderCell( $elem );
586
+ column = parseInt( $th.attr( 'data-column' ), 10 );
586
587
  elem.column = column;
587
588
  tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
588
589
  // this may get updated numerous times if there are multiple rows
@@ -600,10 +601,9 @@
600
601
  }
601
602
  // add cell to headerList
602
603
  c.headerList[ index ] = elem;
604
+ $elem.addClass( ts.css.header + ' ' + c.cssHeader );
603
605
  // add to parent in case there are multiple rows
604
- $elem
605
- .addClass( ts.css.header + ' ' + c.cssHeader )
606
- .parent()
606
+ ts.getClosest( $elem, 'tr' )
607
607
  .addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
608
608
  .attr( 'role', 'row' );
609
609
  // allow keyboard cursor to focus on element
@@ -1161,10 +1161,29 @@
1161
1161
  }
1162
1162
  },
1163
1163
 
1164
+ // This function does NOT return closest if the $el matches the selector
1165
+ getClosest : function( $el, selector ) {
1166
+ return $.fn.closest ?
1167
+ $el.closest( selector ) :
1168
+ $el.parents( selector ).filter( ':first' );
1169
+ },
1170
+
1171
+ getHeaderCell : function( $el ) {
1172
+ // jQuery v1.2.6 doesn't have closest()
1173
+ if ( $.fn.closest ) {
1174
+ return $el.closest( 'th, td' );
1175
+ }
1176
+ return /TH|TD/.test( $el[0].nodeName ) ?
1177
+ $el :
1178
+ $el.parents( 'th, td' ).filter( ':first' );
1179
+ },
1180
+
1164
1181
  // nextSort (optional), lets you disable next sort text
1165
1182
  setColumnAriaLabel : function( c, $header, nextSort ) {
1166
1183
  if ( $header.length ) {
1167
- var column = parseInt( $header.attr( 'data-column' ), 10 ),
1184
+ var $th = ts.getHeaderCell( $header ),
1185
+ // data-column always stored on the th/td
1186
+ column = parseInt( $th.attr( 'data-column' ), 10 ),
1168
1187
  vars = c.sortVars[ column ],
1169
1188
  tmp = $header.hasClass( ts.css.sortAsc ) ?
1170
1189
  'sortAsc' :
@@ -1322,10 +1341,9 @@
1322
1341
  $cell = $( cell ),
1323
1342
  // update cache - format: function( s, table, cell, cellIndex )
1324
1343
  // no closest in jQuery v1.2.6
1325
- tbodyIndex = $tbodies
1326
- .index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
1344
+ tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
1327
1345
  tbcache = c.cache[ tbodyIndex ],
1328
- $row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
1346
+ $row = ts.getClosest( $cell, 'tr' );
1329
1347
  cell = $cell[ 0 ]; // in case cell is a jQuery object
1330
1348
  // tbody may not exist if update is initialized while tbody is removed for processing
1331
1349
  if ( $tbodies.length && tbodyIndex >= 0 ) {
@@ -1380,11 +1398,13 @@
1380
1398
  if ( valid ) {
1381
1399
  $row = $( $row );
1382
1400
  c.$tbodies.append( $row );
1383
- } else if ( !$row ||
1401
+ } else if (
1402
+ !$row ||
1384
1403
  // row is a jQuery object?
1385
1404
  !( $row instanceof jQuery ) ||
1386
1405
  // row contained in the table?
1387
- ( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
1406
+ ( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
1407
+ ) {
1388
1408
  if ( c.debug ) {
1389
1409
  console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
1390
1410
  'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@@ -1531,10 +1551,10 @@
1531
1551
  notMultiSort = !event[ c.sortMultiSortKey ],
1532
1552
  table = c.table,
1533
1553
  len = c.$headers.length,
1534
- // get current column index
1535
- col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
1554
+ // get current column index; *always* stored on th/td
1555
+ $th = ts.getHeaderCell( $( cell ) ),
1556
+ col = parseInt( $th.attr( 'data-column' ), 10 ),
1536
1557
  order = c.sortVars[ col ].order;
1537
-
1538
1558
  // Only call sortStart if sorting is enabled
1539
1559
  c.$table.triggerHandler( 'sortStart', table );
1540
1560
  // get current column sort order
@@ -2058,7 +2078,7 @@
2058
2078
  if ( !widget.priority ) { widget.priority = 10; }
2059
2079
  widgets[ indx ] = widget;
2060
2080
  } else if ( c.debug ) {
2061
- console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
2081
+ console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
2062
2082
  }
2063
2083
  }
2064
2084
  // sort widgets by priority
@@ -2130,6 +2150,7 @@
2130
2150
  c.widgetInit[ name[ index ] ] = false;
2131
2151
  }
2132
2152
  }
2153
+ c.$table.triggerHandler( 'widgetRemoveEnd', table );
2133
2154
  },
2134
2155
 
2135
2156
  refreshWidgets : function( table, doAll, dontapply ) {
@@ -4,7 +4,7 @@
4
4
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀██
5
5
  █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
6
6
  */
7
- /*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
7
+ /*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
8
8
  /* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
9
9
  (function(factory) {
10
10
  if (typeof define === 'function' && define.amd) {
@@ -133,7 +133,7 @@
133
133
 
134
134
  })(jQuery, window, document);
135
135
 
136
- /*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
136
+ /*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
137
137
  ;(function ($) {
138
138
  'use strict';
139
139
  var ts = $.tablesorter || {};
@@ -150,10 +150,10 @@
150
150
  active : '', // applied when column is sorted
151
151
  hover : '', // custom css required - a defined bootstrap style may not override other classes
152
152
  // icon class names
153
- icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
153
+ icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
154
154
  iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
155
- iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
156
- iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
155
+ iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
156
+ iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
157
157
  filterRow : '', // filter row class
158
158
  footerRow : '',
159
159
  footerCells : '',
@@ -2336,7 +2336,7 @@
2336
2336
 
2337
2337
  })( jQuery );
2338
2338
 
2339
- /*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
2339
+ /*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
2340
2340
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
2341
2341
  * by Rob Garrison
2342
2342
  */
@@ -2488,10 +2488,14 @@
2488
2488
  });
2489
2489
  }
2490
2490
  },
2491
+ getLeftPosition = function() {
2492
+ return $attach.length ?
2493
+ parseInt($attach.css('padding-left'), 10) || 0 :
2494
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
2495
+ },
2491
2496
  resizeHeader = function() {
2492
2497
  $stickyWrap.css({
2493
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
2494
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
2498
+ left : getLeftPosition(),
2495
2499
  width: $table.outerWidth()
2496
2500
  });
2497
2501
  setWidth( $table, $stickyTable );
@@ -2501,10 +2505,10 @@
2501
2505
  if (!$table.is(':visible')) { return; } // fixes #278
2502
2506
  // Detect nested tables - fixes #724
2503
2507
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
2504
- var offset = $table.offset(),
2508
+ var tmp,
2509
+ offset = $table.offset(),
2505
2510
  stickyOffset = getStickyOffset(c, wo),
2506
2511
  yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
2507
- xWindow = $.isWindow( $xScroll[0] ),
2508
2512
  attachTop = $attach.length ?
2509
2513
  ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
2510
2514
  $yScroll.scrollTop(),
@@ -2512,19 +2516,27 @@
2512
2516
  scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
2513
2517
  tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
2514
2518
  isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
2519
+ state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
2520
+ needsUpdating = !$stickyWrap.hasClass( state ),
2515
2521
  cssSettings = { visibility : isVisible };
2516
2522
  if ($attach.length) {
2523
+ // attached sticky headers always need updating
2524
+ needsUpdating = true;
2517
2525
  cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
2518
2526
  }
2519
- if (xWindow) {
2520
- // adjust when scrolling horizontally - fixes issue #143
2521
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
2527
+ // adjust when scrolling horizontally - fixes issue #143
2528
+ tmp = getLeftPosition();
2529
+ if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
2530
+ needsUpdating = true;
2531
+ cssSettings.left = tmp;
2522
2532
  }
2523
2533
  cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
2524
- $stickyWrap
2525
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
2526
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
2527
- .css(cssSettings);
2534
+ if (needsUpdating) {
2535
+ $stickyWrap
2536
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
2537
+ .addClass( state )
2538
+ .css(cssSettings);
2539
+ }
2528
2540
  if (isVisible !== laststate || resizing) {
2529
2541
  // make sure the column widths match
2530
2542
  resizeHeader();
@@ -2643,7 +2655,7 @@
2643
2655
 
2644
2656
  })(jQuery, window);
2645
2657
 
2646
- /*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
2658
+ /*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
2647
2659
  /*jshint browser:true, jquery:true, unused:false */
2648
2660
  ;(function ($, window) {
2649
2661
  'use strict';
@@ -2970,6 +2982,7 @@
2970
2982
  vars.$target = vars.$next = null;
2971
2983
  // will update stickyHeaders, just in case, see #912
2972
2984
  c.$table.triggerHandler('stickyHeadersUpdate');
2985
+ c.$table.triggerHandler('resizableComplete');
2973
2986
  }
2974
2987
  };
2975
2988
 
@@ -1,4 +1,4 @@
1
- /* Widget: columnSelector (responsive table widget) - updated 7/4/2017 (v2.28.15) *//*
1
+ /* Widget: columnSelector (responsive table widget) - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Justin Hallett & Rob Garrison
4
4
  */
@@ -269,16 +269,16 @@
269
269
  c.$table.triggerHandler(wo.columnSelector_updated);
270
270
  }
271
271
  },
272
- addSelectors: function( prefix, column ) {
272
+ addSelectors: function( wo, prefix, column ) {
273
273
  var array = [],
274
274
  temp = ' col:nth-child(' + column + ')';
275
275
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
276
- temp = ' tr:not(.hasSpan) th[data-column="' + ( column - 1 ) + '"]';
276
+ temp = ' tr:not(.' + wo.columnSelector_classHasSpan + ') th[data-column="' + ( column - 1 ) + '"]';
277
277
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
278
- temp = ' tr:not(.hasSpan) td:nth-child(' + column + ')';
278
+ temp = ' tr:not(.' + wo.columnSelector_classHasSpan + ') td:nth-child(' + column + ')';
279
279
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
280
280
  // for other cells in colspan columns
281
- temp = ' tr td:not(' + prefix + 'HasSpan)[data-column="' + (column - 1) + '"]';
281
+ temp = ' tr td:not(' + prefix + wo.columnSelector_classHasSpan + ')[data-column="' + (column - 1) + '"]';
282
282
  array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
283
283
  return array;
284
284
  },
@@ -301,7 +301,7 @@
301
301
  isHidden[ column + 1 ] = ts.getData( c.$headerIndexed[ column ], col, 'columnSelector' ) === 'false';
302
302
  if ( isHidden[ column + 1 ] ) {
303
303
  // hide columnSelector false column (in auto mode)
304
- mediaAll = mediaAll.concat( tsColSel.addSelectors( prefix, column + 1 ) );
304
+ mediaAll = mediaAll.concat( tsColSel.addSelectors( wo, prefix, column + 1 ) );
305
305
  }
306
306
  }
307
307
  }
@@ -313,7 +313,7 @@
313
313
  column = parseInt($(this).attr('data-column'), 10) + 1;
314
314
  // don't reveal columnSelector false columns
315
315
  if ( !isHidden[ column ] ) {
316
- breaks = breaks.concat( tsColSel.addSelectors( prefix, column ) );
316
+ breaks = breaks.concat( tsColSel.addSelectors( wo, prefix, column ) );
317
317
  }
318
318
  });
319
319
  if (breaks.length) {
@@ -343,7 +343,7 @@
343
343
  colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
344
344
  if (!this.checked) {
345
345
  column = parseInt( $(this).attr('data-column'), 10 ) + 1;
346
- styles = styles.concat( tsColSel.addSelectors( prefix, column ) );
346
+ styles = styles.concat( tsColSel.addSelectors( wo, prefix, column ) );
347
347
  }
348
348
  $(this).toggleClass( wo.columnSelector_cssChecked, this.checked );
349
349
  });
@@ -373,10 +373,10 @@
373
373
  if ( span > 1 ) {
374
374
  hasSpans = true;
375
375
  $cells.eq( index )
376
- .addClass( c.namespace.slice( 1 ) + 'columnselectorHasSpan' )
376
+ .addClass( c.namespace.slice( 1 ) + 'columnselector' + wo.columnSelector_classHasSpan )
377
377
  .attr( 'data-col-span', span );
378
378
  // add data-column values
379
- ts.computeColumnIndex( $cells.eq( index ).parent().addClass( 'hasSpan' ) );
379
+ ts.computeColumnIndex( $cells.eq( index ).parent().addClass( wo.columnSelector_classHasSpan ) );
380
380
  }
381
381
  }
382
382
  // only add resize end if using media queries
@@ -402,7 +402,9 @@
402
402
  autoModeOn = wo.columnSelector_mediaquery && colSel.auto,
403
403
  // find all header/footer cells in case a regular column follows a colspan; see #1238
404
404
  $headers = c.$table.children( 'thead, tfoot' ).children().children()
405
- .add( $(c.namespace + '_extra_table').children( 'thead, tfoot' ).children().children() ),
405
+ .add( $(c.namespace + '_extra_table').children( 'thead, tfoot' ).children().children() )
406
+ // include grouping widget headers (they have colspans!)
407
+ .add( c.$table.find( '.group-header' ).children() ),
406
408
  len = $headers.length;
407
409
  for ( index = 0; index < len; index++ ) {
408
410
  $cell = $headers.eq(index);
@@ -422,7 +424,7 @@
422
424
  $cell.addClass( filtered );
423
425
  }
424
426
  } else if ( typeof colSel.states[ col ] !== 'undefined' && colSel.states[ col ] !== null ) {
425
- $cell.toggleClass( filtered, !colSel.states[ col ] );
427
+ $cell.toggleClass( filtered, !autoModeOn && !colSel.states[ col ] );
426
428
  }
427
429
  }
428
430
  },
@@ -533,6 +535,8 @@
533
535
  // class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
534
536
  // applied icons; use this class name (input.checked) instead of input:checked
535
537
  columnSelector_cssChecked : 'checked',
538
+ // class name added to rows that have a span (e.g. grouping widget & other rows inside the tbody)
539
+ columnSelector_classHasSpan : 'hasSpan',
536
540
  // event triggered when columnSelector completes
537
541
  columnSelector_updated : 'columnUpdate'
538
542
  },
@@ -546,10 +550,10 @@
546
550
  if ( csel.$popup ) { csel.$popup.empty(); }
547
551
  csel.$style.remove();
548
552
  csel.$breakpoints.remove();
549
- $( c.namespace + 'columnselectorHasSpan' ).removeClass( wo.filter_filteredRow || 'filtered' );
553
+ $( c.namespace + 'columnselector' + wo.columnSelector_classHasSpan )
554
+ .removeClass( wo.filter_filteredRow || 'filtered' );
550
555
  c.$table.find('[data-col-span]').each(function(indx, el) {
551
556
  var $el = $(el);
552
- console.log($el, $el.attr('data-col-span'));
553
557
  $el.attr('colspan', $el.attr('data-col-span'));
554
558
  });
555
559
  c.$table.off('updateAll' + namespace + ' update' + namespace);
@@ -1,4 +1,4 @@
1
- /*! Widget: grouping - updated 11/26/2016 (v2.28.0) *//*
1
+ /*! Widget: grouping - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -172,7 +172,10 @@
172
172
 
173
173
  groupHeaderHTML : function( c, wo, data ) {
174
174
  var name = ( data.currentGroup || '' ).toString().replace(/</g, '&lt;').replace(/>/g, '&gt;');
175
- return '<tr class="group-header ' + c.selectorRemove.slice(1) +
175
+ return '<tr class="group-header ' + c.selectorRemove.slice(1) + ' ' +
176
+ // prevent grouping row from being hidden by the columnSelector;
177
+ // classHasSpan option added 2.29.0
178
+ ( wo.columnSelector_classHasSpan || 'hasSpan' ) +
176
179
  '" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
177
180
  data.groupIndex + '">' +
178
181
  '<td colspan="' + c.columns + '">' +
@@ -221,6 +224,10 @@
221
224
  }
222
225
  }
223
226
  }
227
+ if ( ts.hasWidget( c.table, 'columnSelector' ) ) {
228
+ // make sure to handle the colspan adjustments of the grouping rows
229
+ ts.columnSelector.setUpColspan( c, wo );
230
+ }
224
231
  },
225
232
  insertGroupHeader: function( c, wo, data ) {
226
233
  var $header = c.$headerIndexed[ data.column ],
@@ -1,4 +1,4 @@
1
- /*! Widget: output - updated 4/2/2017 (v2.28.6) *//*
1
+ /*! Widget: output - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * Modified from:
4
4
  * HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
@@ -131,8 +131,10 @@
131
131
  return data;
132
132
  },
133
133
 
134
- process : function(c, wo) {
135
- var mydata, $this, $rows, headers, csvData, len, rowsLen, tmp,
134
+ // optional vars $rows and dump added by TheSin to make
135
+ // process callable via callback for ajaxPager
136
+ process : function(c, wo, $rows, dump) {
137
+ var mydata, $this, headers, csvData, len, rowsLen, tmp,
136
138
  hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
137
139
  indx = 0,
138
140
  tmpData = (wo.output_separator || ',').toLowerCase(),
@@ -162,7 +164,8 @@
162
164
  headers = output.processRow(c, $this, true, outputJSON);
163
165
 
164
166
  // all tbody rows - do not include widget added rows (e.g. grouping widget headers)
165
- $rows = $el.children('tbody').children('tr').not(c.selectorRemove);
167
+ if ( !$rows )
168
+ $rows = $el.children('tbody').children('tr').not(c.selectorRemove);
166
169
 
167
170
  // check for a filter callback function first! because
168
171
  // /^f/.test(function(){ console.log('test'); }) is TRUE! (function is converted to a string)
@@ -210,10 +213,15 @@
210
213
  mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
211
214
  }
212
215
 
216
+ if (dump) {
217
+ return mydata;
218
+ }
219
+
213
220
  // callback; if true returned, continue processing
214
221
  if ($.isFunction(wo.output_callback)) {
215
222
  tmp = wo.output_callback(c, mydata, c.pager && c.pager.ajaxObject.url || null);
216
223
  if ( tmp === false ) {
224
+ output.busy = false;
217
225
  return;
218
226
  } else if ( typeof tmp === 'string' ) {
219
227
  mydata = tmp;
@@ -1,4 +1,4 @@
1
- /*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
1
+ /*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
2
2
  /*jshint browser:true, jquery:true, unused:false */
3
3
  ;(function ($, window) {
4
4
  'use strict';
@@ -325,6 +325,7 @@
325
325
  vars.$target = vars.$next = null;
326
326
  // will update stickyHeaders, just in case, see #912
327
327
  c.$table.triggerHandler('stickyHeadersUpdate');
328
+ c.$table.triggerHandler('resizableComplete');
328
329
  }
329
330
  };
330
331
 
@@ -1,4 +1,4 @@
1
- /*! Widget: scroller - updated 4/18/2017 (v2.28.8) *//*
1
+ /*! Widget: scroller - updated 9/27/2017 (v2.29.0) *//*
2
2
  Copyright (C) 2011 T. Connell & Associates, Inc.
3
3
 
4
4
  Dual-licensed under the MIT and GPL licenses
@@ -273,6 +273,9 @@
273
273
  $tableWrap
274
274
  .off( 'scroll' + namespace )
275
275
  .on( 'scroll' + namespace, function() {
276
+ // Save position
277
+ wo.scroller_saved[0] = $tableWrap.scrollLeft();
278
+ wo.scroller_saved[1] = $tableWrap.scrollTop();
276
279
  if ( wo.scroller_jumpToHeader ) {
277
280
  var pos = $win.scrollTop() - $hdr.offset().top;
278
281
  if ( $( this ).scrollTop() !== 0 && pos < tbHt && pos > 0 ) {
@@ -841,6 +844,7 @@
841
844
  // adjust caption height, see #1202
842
845
  $fixedColumn.find('caption').height( wo.scroller_$header.find( 'caption' ).height() );
843
846
 
847
+ $tableWrap.scroll();
844
848
  wo.scroller_isBusy = false;
845
849
 
846
850
  },
@@ -1,4 +1,4 @@
1
- /*! Widget: sort2Hash (BETA) - updated 7/4/2017 (v2.28.15) */
1
+ /*! Widget: sort2Hash (BETA) - updated 9/27/2017 (v2.29.0) */
2
2
  /* Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -225,8 +225,27 @@
225
225
  hash = s2h.cleanHash( c, wo, component, hash );
226
226
  str += value;
227
227
  });
228
- // add updated hash
229
- window.location.hash = ( ( window.location.hash || '' ).replace( '#', '' ).length ? hash : wo.sort2Hash_hash ) + str;
228
+
229
+ var hashChar = wo.sort2Hash_hash;
230
+ // Combine new hash with any existing hashes
231
+ var newHash = (
232
+ ( window.location.hash || '' ).replace( hashChar, '' ).length ?
233
+ hash : hashChar
234
+ ) + str;
235
+
236
+ if (wo.sort2Hash_replaceHistory) {
237
+ var baseUrl = window.location.href.split(hashChar)[0];
238
+ // Ensure that there is a leading hash character
239
+ var firstChar = newHash[0];
240
+ if (firstChar != hashChar) {
241
+ newHash = hashChar + newHash;
242
+ }
243
+ // Update URL in browser
244
+ window.location.replace(baseUrl + newHash);
245
+ } else {
246
+ // Add updated hash
247
+ window.location.hash = newHash;
248
+ }
230
249
  }
231
250
  };
232
251
 
@@ -239,6 +258,7 @@
239
258
  sort2Hash_headerTextAttr : 'data-header', // data attribute containing alternate header text
240
259
  sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
241
260
  sort2Hash_overrideSaveSort : false, // if true, override saveSort widget if saved sort available
261
+ sort2Hash_replaceHistory : false, // if true, hash changes are not saved to browser history
242
262
 
243
263
  // this option > table ID > table index on page
244
264
  sort2Hash_tableId : null,
@@ -1,4 +1,4 @@
1
- /*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
1
+ /*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
3
3
  * by Rob Garrison
4
4
  */
@@ -150,10 +150,14 @@
150
150
  });
151
151
  }
152
152
  },
153
+ getLeftPosition = function() {
154
+ return $attach.length ?
155
+ parseInt($attach.css('padding-left'), 10) || 0 :
156
+ $table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
157
+ },
153
158
  resizeHeader = function() {
154
159
  $stickyWrap.css({
155
- left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
156
- $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
160
+ left : getLeftPosition(),
157
161
  width: $table.outerWidth()
158
162
  });
159
163
  setWidth( $table, $stickyTable );
@@ -163,10 +167,10 @@
163
167
  if (!$table.is(':visible')) { return; } // fixes #278
164
168
  // Detect nested tables - fixes #724
165
169
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
166
- var offset = $table.offset(),
170
+ var tmp,
171
+ offset = $table.offset(),
167
172
  stickyOffset = getStickyOffset(c, wo),
168
173
  yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
169
- xWindow = $.isWindow( $xScroll[0] ),
170
174
  attachTop = $attach.length ?
171
175
  ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
172
176
  $yScroll.scrollTop(),
@@ -174,19 +178,27 @@
174
178
  scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
175
179
  tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
176
180
  isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
181
+ state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
182
+ needsUpdating = !$stickyWrap.hasClass( state ),
177
183
  cssSettings = { visibility : isVisible };
178
184
  if ($attach.length) {
185
+ // attached sticky headers always need updating
186
+ needsUpdating = true;
179
187
  cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
180
188
  }
181
- if (xWindow) {
182
- // adjust when scrolling horizontally - fixes issue #143
183
- cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
189
+ // adjust when scrolling horizontally - fixes issue #143
190
+ tmp = getLeftPosition();
191
+ if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
192
+ needsUpdating = true;
193
+ cssSettings.left = tmp;
184
194
  }
185
195
  cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
186
- $stickyWrap
187
- .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
188
- .addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
189
- .css(cssSettings);
196
+ if (needsUpdating) {
197
+ $stickyWrap
198
+ .removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
199
+ .addClass( state )
200
+ .css(cssSettings);
201
+ }
190
202
  if (isVisible !== laststate || resizing) {
191
203
  // make sure the column widths match
192
204
  resizeHeader();
@@ -1,4 +1,4 @@
1
- /*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
1
+ /*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
2
2
  ;(function ($) {
3
3
  'use strict';
4
4
  var ts = $.tablesorter || {};
@@ -15,10 +15,10 @@
15
15
  active : '', // applied when column is sorted
16
16
  hover : '', // custom css required - a defined bootstrap style may not override other classes
17
17
  // icon class names
18
- icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
18
+ icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
19
19
  iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
20
- iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
21
- iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
20
+ iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
21
+ iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
22
22
  filterRow : '', // filter row class
23
23
  footerRow : '',
24
24
  footerCells : '',
@@ -56,8 +56,8 @@
56
56
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
57
57
  }
58
58
 
59
- /* white unsorted icon */
60
- .tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
59
+ /* white unsorted icon; updated to use bootstrap-icon-white - see #1432 */
60
+ .tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted {
61
61
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
62
62
  }
63
63
 
@@ -53,8 +53,8 @@
53
53
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
54
54
  }
55
55
 
56
- /* white unsorted icon */
57
- .tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
56
+ /* white unsorted icon; updated to use bootstrap-icon-white - see #1432 */
57
+ .tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted {
58
58
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
59
59
  }
60
60
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jquery-tablesorter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.23.15
4
+ version: 1.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jun Lin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-07-09 00:00:00.000000000 Z
12
+ date: 2017-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
183
  version: '0'
184
184
  requirements: []
185
185
  rubyforge_project:
186
- rubygems_version: 2.6.11
186
+ rubygems_version: 2.6.13
187
187
  signing_key:
188
188
  specification_version: 4
189
189
  summary: Simple integration of jquery-tablesorter (Mottie's fork) into the Rails asset