jquery-tablesorter 1.16.2 → 1.16.3

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +1 -1
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +8 -6
  5. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +30 -20
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +343 -193
  7. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +4 -4
  8. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +3 -2
  9. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-select2.js +2 -2
  10. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +26 -23
  11. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +2 -3
  12. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +11 -5
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +277 -139
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +543 -220
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +3 -10
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +28 -15
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +7 -4
  18. data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +5 -4
  19. data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +8 -5
  20. data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +5 -4
  21. data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +6 -5
  22. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +6 -5
  23. data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +6 -5
  24. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +5 -5
  25. data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +13 -8
  26. data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +8 -5
  27. data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +16 -9
  28. data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +4 -3
  29. data/vendor/assets/stylesheets/jquery-tablesorter/theme.metro-dark.css +5 -4
  30. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ccbde787981d827d7b3dbc159fe3da131a047d40
4
- data.tar.gz: efc7453655e3b187b2c188993c64f540ed38dd2d
3
+ metadata.gz: 2f5f02392625ac72228f63113d0c2eff960685aa
4
+ data.tar.gz: c7faf012f91b35ffb12e8095f40f9984d4b189ca
5
5
  SHA512:
6
- metadata.gz: 281fb01a0cd7b6605bf22f5d026c7523fe1f89a9fad5aad4d3b700b5a6d439beeed1e8d333b1d7dbcc93465736cc04826e3d9453b04d9630a25e81fb4e308fbf
7
- data.tar.gz: af6d1fc76d055a5f4005adb808cfc408ad81f77322370b4d040ccb885f7bc468d511069849619cbe2c204130f85a9de786c64e2a4ae3829ea70cfa8f79107552
6
+ metadata.gz: 5c900f0806e4eab93cc8fd22edc85f7e9042c3a26d1bd6f308b5c89d8b3d86c492bf41be4cbd50d90481c06fd73b53c62773ee546ddb023d433a8825d9f5c802
7
+ data.tar.gz: ff378b3abff6e7571761a7866fd7ee8422500f41ec46c7e65d6dd0baff6f59180ab4376bd6b5e9d5cf5b74258aa43ba3d3ae41577668bd48a9a104d4b67404b3
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Simple integration of jquery-tablesorter into the asset pipeline.
6
6
 
7
- Current tablesorter version: 2.21.2 (3/13/2015), [documentation]
7
+ Current tablesorter version: 2.21.3 (3/26/2015), [documentation]
8
8
 
9
9
  Any issue associated with the js/css files, please report to [Mottie's fork].
10
10
 
@@ -1,3 +1,3 @@
1
1
  module JqueryTablesorter
2
- VERSION = '1.16.2'
2
+ VERSION = '1.16.3'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * tablesorter (FORK) pager plugin
3
- * updated 3/5/2015 (v2.21.0)
3
+ * updated 3/26/2015 (v2.21.3)
4
4
  */
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  ;(function($) {
@@ -115,7 +115,7 @@
115
115
  };
116
116
 
117
117
  var pagerEvents = 'filterInit filterStart filterEnd sortEnd disable enable destroy updateComplete ' +
118
- 'pageSize pageSet pageAndSize pagerUpdate ',
118
+ 'pageSize pageSet pageAndSize pagerUpdate refreshComplete ',
119
119
 
120
120
  $this = this,
121
121
 
@@ -204,7 +204,7 @@
204
204
  p.$goto.html(t).val( p.page + 1 );
205
205
  }
206
206
  if ($out.length) {
207
- $out[ ($out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
207
+ $out[ ($out[0].nodeName === 'INPUT') ? 'val' : 'html' ](s);
208
208
  // rebind startRow/page inputs
209
209
  $out.find('.ts-startRow, .ts-page').unbind('change.pager').bind('change.pager', function(){
210
210
  var v = $(this).val(),
@@ -934,9 +934,12 @@
934
934
  })
935
935
  .bind('pageSet.pager pagerUpdate.pager', function(e,v){
936
936
  e.stopPropagation();
937
- p.page = (parseInt(v, 10) || 1) - 1;
938
937
  // force pager refresh
939
- if (e.type === 'pagerUpdate') { p.last.page = true; }
938
+ if (e.type === 'pagerUpdate') {
939
+ v = typeof v === 'undefined' ? p.page + 1 : v;
940
+ p.last.page = true;
941
+ }
942
+ p.page = (parseInt(v, 10) || 1) - 1;
940
943
  moveToPage(table, p, true);
941
944
  updatePageDisplay(table, p, false);
942
945
  })
@@ -984,7 +987,6 @@
984
987
  } else if (c.debug) {
985
988
  ts.log('Pager: >> Goto selector not found');
986
989
  }
987
-
988
990
  // page size selector
989
991
  p.$size = pager.find(p.cssPageSize);
990
992
  if ( p.$size.length ) {
@@ -1,4 +1,4 @@
1
- /*! TableSorter (FORK) v2.21.2 *//*
1
+ /*! TableSorter (FORK) v2.21.3 *//*
2
2
  * Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
@@ -34,7 +34,7 @@
34
34
 
35
35
  var ts = this;
36
36
 
37
- ts.version = '2.21.2';
37
+ ts.version = '2.21.3';
38
38
 
39
39
  ts.parsers = [];
40
40
  ts.widgets = [];
@@ -559,7 +559,9 @@
559
559
  cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ],
560
560
  aria = ['ascending', 'descending'],
561
561
  // find the footer
562
- $t = $(table).find('tfoot tr').children().add(c.$extraHeaders).removeClass(css.join(' '));
562
+ $t = $(table).find('tfoot tr').children()
563
+ .add( $( c.namespace + '_extra_headers' ) )
564
+ .removeClass( css.join( ' ' ) );
563
565
  // remove all header information
564
566
  c.$headers
565
567
  .removeClass(css.join(' '))
@@ -579,7 +581,7 @@
579
581
  .removeClass(none)
580
582
  .addClass(css[list[i][1]])
581
583
  .attr('aria-sort', aria[list[i][1]])
582
- .find('.' + c.cssIcon)
584
+ .find('.' + ts.css.icon)
583
585
  .removeClass(cssIcon[2])
584
586
  .addClass(cssIcon[list[i][1]]);
585
587
  }
@@ -1067,7 +1069,7 @@
1067
1069
  // save initial settings
1068
1070
  c.originalSettings = settings;
1069
1071
  // create a table from data (build table widget)
1070
- if (!table.hasInitialized && ts.buildTable && this.tagName !== 'TABLE') {
1072
+ if (!table.hasInitialized && ts.buildTable && this.nodeName !== 'TABLE') {
1071
1073
  // return the table (in case the original target is the table's container)
1072
1074
  ts.buildTable(table, c);
1073
1075
  } else {
@@ -1334,34 +1336,42 @@
1334
1336
 
1335
1337
  ts.bindEvents = function(table, $headers, core){
1336
1338
  table = $(table)[0];
1337
- var downTime,
1339
+ var t, downTarget = null,
1338
1340
  c = table.config;
1339
1341
  if (core !== true) {
1340
- c.$extraHeaders = c.$extraHeaders ? c.$extraHeaders.add($headers) : $headers;
1342
+ $headers.addClass( c.namespace.slice(1) + '_extra_headers' );
1343
+ t = $.fn.closest ? $headers.closest('table')[0] : $headers.parents('table')[0];
1344
+ if (t && t.nodeName === 'TABLE' && t !== table) {
1345
+ $(t).addClass( c.namespace.slice(1) + '_extra_table' );
1346
+ }
1341
1347
  }
1342
1348
  // apply event handling to headers and/or additional headers (stickyheaders, scroller, etc)
1343
1349
  $headers
1344
1350
  // http://stackoverflow.com/questions/5312849/jquery-find-self;
1345
1351
  .find(c.selectorSort).add( $headers.filter(c.selectorSort) )
1346
- .unbind( ('mousedown mouseup sort keyup '.split(' ').join(c.namespace + ' ')).replace(/\s+/g, ' ') )
1347
- .bind( 'mousedown mouseup sort keyup '.split(' ').join(c.namespace + ' '), function(e, external) {
1352
+ .unbind( ('mousedown mouseup click sort keyup '.split(' ').join(c.namespace + ' ')).replace(/\s+/g, ' ') )
1353
+ .bind( 'mousedown mouseup click sort keyup '.split(' ').join(c.namespace + ' '), function(e, external) {
1348
1354
  var cell,
1349
1355
  $target = $(e.target),
1350
1356
  type = e.type;
1351
- // only recognize left clicks or enter
1352
- if ( ((e.which || e.button) !== 1 && !/sort|keyup/.test(type)) || (type === 'keyup' && e.which !== 13) ) {
1357
+ // only recognize left clicks
1358
+ if ( ( ( e.which || e.button ) !== 1 && !/sort|keyup|click/.test(type) ) ||
1359
+ // allow pressing enter
1360
+ ( type === 'keyup' && e.which !== 13 ) ||
1361
+ // allow triggering a click event (e.which is undefined) & ignore physical clicks
1362
+ ( type === 'click' && typeof e.which !== 'undefined' ) ) {
1353
1363
  return;
1354
1364
  }
1355
- // ignore long clicks (prevents resizable widget from initializing a sort)
1356
- if (type === 'mouseup' && external !== true && (new Date().getTime() - downTime > 250)) { return; }
1365
+ // ignore mouseup if mousedown wasn't on the same target
1366
+ if ( type === 'mouseup' && downTarget !== e.target && external !== true ) { return; }
1357
1367
  // set timer on mousedown
1358
- if (type === 'mousedown') {
1359
- downTime = new Date().getTime();
1368
+ if ( type === 'mousedown' ) {
1369
+ downTarget = e.target;
1360
1370
  return;
1361
1371
  }
1362
- cell = $.fn.closest ? $target.closest('td,th') : $target.parents('td,th').filter(':first');
1372
+ downTarget = null;
1363
1373
  // prevent sort being triggered on form elements
1364
- if ( /(input|select|button|textarea)/i.test(e.target.tagName) ||
1374
+ if ( /(input|select|button|textarea)/i.test(e.target.nodeName) ||
1365
1375
  // nosort class name, or elements within a nosort container
1366
1376
  $target.hasClass(c.cssNoSort) || $target.parents('.' + c.cssNoSort).length > 0 ||
1367
1377
  // elements within a button
@@ -1370,7 +1380,7 @@
1370
1380
  }
1371
1381
  if (c.delayInit && isEmptyObject(c.cache)) { buildCache(table); }
1372
1382
  // jQuery v1.2.6 doesn't have closest()
1373
- cell = $.fn.closest ? $(this).closest('th, td')[0] : /TH|TD/.test(this.tagName) ? this : $(this).parents('th, td')[0];
1383
+ cell = $.fn.closest ? $(this).closest('th, td')[0] : /TH|TD/.test(this.nodeName) ? this : $(this).parents('th, td')[0];
1374
1384
  // reference original table headers and find the same cell
1375
1385
  cell = c.$headers[ $headers.index( cell ) ];
1376
1386
  if (!cell.sortDisabled) {
@@ -2048,8 +2058,8 @@
2048
2058
  priority: 90,
2049
2059
  format: function(table, c, wo) {
2050
2060
  var $tb, $tv, $tr, row, even, time, k,
2051
- child = new RegExp(c.cssChildRow, 'i'),
2052
- b = c.$tbodies;
2061
+ child = new RegExp(c.cssChildRow, 'i'),
2062
+ b = c.$tbodies.add( $( c.namespace + '_extra_table' ).children( 'tbody' ) );
2053
2063
  if (c.debug) {
2054
2064
  time = new Date();
2055
2065
  }
@@ -4,7 +4,7 @@
4
4
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀▀██
5
5
  █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
6
6
  */
7
- /*! tablesorter (FORK) widgets - updated 03-13-2015 (v2.21.2)*/
7
+ /*! tablesorter (FORK) widgets - updated 03-26-2015 (v2.21.3)*/
8
8
  /* Includes: 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($) {
18
18
 
19
- /*! Widget: storage */
19
+ /*! Widget: storage - updated 3/26/2015 (v2.21.3) */
20
20
  ;(function ($, window, document) {
21
21
  'use strict';
22
22
 
@@ -43,26 +43,39 @@ var ts = $.tablesorter = $.tablesorter || {};
43
43
  ts.storage = function(table, key, value, options) {
44
44
  table = $(table)[0];
45
45
  var cookieIndex, cookies, date,
46
- hasLocalStorage = false,
46
+ hasStorage = false,
47
47
  values = {},
48
48
  c = table.config,
49
+ wo = c && c.widgetOptions,
50
+ storageType = ( options && options.useSessionStorage ) || ( wo && wo.storage_useSessionStorage ) ?
51
+ 'sessionStorage' : 'localStorage',
49
52
  $table = $(table),
50
- id = options && options.id || $table.attr(options && options.group ||
51
- 'data-table-group') || table.id || $('.tablesorter').index( $table ),
52
- url = options && options.url || $table.attr(options && options.page ||
53
- 'data-table-page') || c && c.fixedUrl || window.location.pathname;
53
+ // id from (1) options ID, (2) table "data-table-group" attribute, (3) widgetOptions.storage_tableId,
54
+ // (4) table ID, then (5) table index
55
+ id = options && options.id ||
56
+ $table.attr( options && options.group || wo && wo.storage_group || 'data-table-group') ||
57
+ wo && wo.storage_tableId || table.id || $('.tablesorter').index( $table ),
58
+ // url from (1) options url, (2) table "data-table-page" attribute, (3) widgetOptions.storage_fixedUrl,
59
+ // (4) table.config.fixedUrl (deprecated), then (5) window location path
60
+ url = options && options.url ||
61
+ $table.attr(options && options.page || wo && wo.storage_page || 'data-table-page') ||
62
+ wo && wo.storage_fixedUrl || c && c.fixedUrl || window.location.pathname;
54
63
  // https://gist.github.com/paulirish/5558557
55
- if ('localStorage' in window) {
64
+ if (storageType in window) {
56
65
  try {
57
- window.localStorage.setItem('_tmptest', 'temp');
58
- hasLocalStorage = true;
59
- window.localStorage.removeItem('_tmptest');
60
- } catch(error) {}
66
+ window[storageType].setItem('_tmptest', 'temp');
67
+ hasStorage = true;
68
+ window[storageType].removeItem('_tmptest');
69
+ } catch(error) {
70
+ if (c && c.debug) {
71
+ ts.log( storageType + ' is not supported in this browser' );
72
+ }
73
+ }
61
74
  }
62
75
  // *** get value ***
63
76
  if ($.parseJSON) {
64
- if (hasLocalStorage) {
65
- values = $.parseJSON(localStorage[key] || 'null') || {};
77
+ if (hasStorage) {
78
+ values = $.parseJSON( window[storageType][key] || 'null' ) || {};
66
79
  } else {
67
80
  // old browser, using cookies
68
81
  cookies = document.cookie.split(/[;\s|=]/);
@@ -79,8 +92,8 @@ ts.storage = function(table, key, value, options) {
79
92
  }
80
93
  values[url][id] = value;
81
94
  // *** set value ***
82
- if (hasLocalStorage) {
83
- localStorage[key] = JSON.stringify(values);
95
+ if (hasStorage) {
96
+ window[storageType][key] = JSON.stringify(values);
84
97
  } else {
85
98
  date = new Date();
86
99
  date.setTime(date.getTime() + (31536e+6)); // 365 days
@@ -93,7 +106,7 @@ ts.storage = function(table, key, value, options) {
93
106
 
94
107
  })(jQuery, window, document);
95
108
 
96
- /*! Widget: uitheme */
109
+ /*! Widget: uitheme - updated 3/26/2015 (v2.21.3) */
97
110
  ;(function ($) {
98
111
  'use strict';
99
112
  var ts = $.tablesorter = $.tablesorter || {};
@@ -153,8 +166,8 @@ ts.addWidget({
153
166
  format: function(table, c, wo) {
154
167
  var i, hdr, icon, time, $header, $icon, $tfoot, $h, oldtheme, oldremove, oldIconRmv, hasOldTheme,
155
168
  themesAll = ts.themes,
156
- $table = c.$table.add( c.$extraTables ),
157
- $headers = c.$headers.add( c.$extraHeaders ),
169
+ $table = c.$table.add( $( c.namespace + '_extra_table' ) ),
170
+ $headers = c.$headers.add( $( c.namespace + '_extra_headers' ) ),
158
171
  theme = c.theme || 'jui',
159
172
  themes = themesAll[theme] || {},
160
173
  remove = $.trim( [ themes.sortNone, themes.sortDesc, themes.sortAsc, themes.active ].join( ' ' ) ),
@@ -225,7 +238,10 @@ ts.addWidget({
225
238
  }
226
239
  }
227
240
  for (i = 0; i < c.columns; i++) {
228
- $header = c.$headers.add(c.$extraHeaders).not('.sorter-false').filter('[data-column="' + i + '"]');
241
+ $header = c.$headers
242
+ .add($(c.namespace + '_extra_headers'))
243
+ .not('.sorter-false')
244
+ .filter('[data-column="' + i + '"]');
229
245
  $icon = (ts.css.icon) ? $header.find('.' + ts.css.icon) : $();
230
246
  $h = $headers.not('.sorter-false').filter('[data-column="' + i + '"]:last');
231
247
  if ($h.length) {
@@ -355,17 +371,20 @@ ts.addWidget({
355
371
 
356
372
  })(jQuery);
357
373
 
358
- /*! Widget: filter - updated 3/5/2015 (v2.21.0) *//*
374
+ /*! Widget: filter - updated 3/26/2015 (v2.21.3) *//*
359
375
  * Requires tablesorter v2.8+ and jQuery 1.7+
360
376
  * by Rob Garrison
361
377
  */
362
378
  ;(function ($) {
363
379
  'use strict';
364
- var ts = $.tablesorter = $.tablesorter || {};
365
-
366
- $.extend(ts.css, {
367
- filterRow : 'tablesorter-filter-row',
368
- filter : 'tablesorter-filter'
380
+ var ts = $.tablesorter = $.tablesorter || {},
381
+ tscss = ts.css;
382
+
383
+ $.extend(tscss, {
384
+ filterRow : 'tablesorter-filter-row',
385
+ filter : 'tablesorter-filter',
386
+ filterDisabled : 'disabled',
387
+ filterRowHide : 'hideme'
369
388
  });
370
389
 
371
390
  ts.addWidget({
@@ -415,7 +434,7 @@ ts.addWidget({
415
434
  // add .tsfilter namespace to all BUT search
416
435
  .unbind( events.replace(/\s+/g, ' ') )
417
436
  // remove the filter row even if refreshing, because the column might have been moved
418
- .find('.' + ts.css.filterRow).remove();
437
+ .find('.' + tscss.filterRow).remove();
419
438
  if (refreshing) { return; }
420
439
  for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
421
440
  $tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
@@ -643,13 +662,13 @@ ts.filter = {
643
662
  c.$table.bind( txt, function(event, filter) {
644
663
  val = (wo.filter_hideEmpty && $.isEmptyObject(c.cache) && !(c.delayInit && event.type === 'appendCache'));
645
664
  // hide filter row using the "filtered" class name
646
- c.$table.find('.' + ts.css.filterRow).toggleClass(wo.filter_filteredRow, val ); // fixes #450
665
+ c.$table.find('.' + tscss.filterRow).toggleClass(wo.filter_filteredRow, val ); // fixes #450
647
666
  if ( !/(search|filter)/.test(event.type) ) {
648
667
  event.stopPropagation();
649
668
  ts.filter.buildDefault(table, true);
650
669
  }
651
670
  if (event.type === 'filterReset') {
652
- c.$table.find('.' + ts.css.filter).add(wo.filter_$externalFilters).val('');
671
+ c.$table.find('.' + tscss.filter).add(wo.filter_$externalFilters).val('');
653
672
  ts.filter.searching(table, []);
654
673
  } else if (event.type === 'filterEnd') {
655
674
  ts.filter.buildDefault(table, true);
@@ -712,7 +731,7 @@ ts.filter = {
712
731
  options += '<option ' + (txt === val ? '' : 'data-function-name="' + string + '" ') + 'value="' + val + '">' + txt + '</option>';
713
732
  }
714
733
  }
715
- c.$table.find('thead').find('select.' + ts.css.filter + '[data-column="' + column + '"]').append(options);
734
+ c.$table.find('thead').find('select.' + tscss.filter + '[data-column="' + column + '"]').append(options);
716
735
  }
717
736
  }
718
737
  }
@@ -721,7 +740,7 @@ ts.filter = {
721
740
  // it would append the same options twice.
722
741
  ts.filter.buildDefault(table, true);
723
742
 
724
- ts.filter.bindSearch( table, c.$table.find('.' + ts.css.filter), true );
743
+ ts.filter.bindSearch( table, c.$table.find('.' + tscss.filter), true );
725
744
  if (wo.filter_external) {
726
745
  ts.filter.bindSearch( table, wo.filter_external );
727
746
  }
@@ -736,7 +755,7 @@ ts.filter = {
736
755
  .unbind( ('filterStart filterEnd '.split(' ').join(c.namespace + 'filter ')).replace(/\s+/g, ' ') )
737
756
  .bind( 'filterStart filterEnd '.split(' ').join(c.namespace + 'filter '), function(event, columns) {
738
757
  // only add processing to certain columns to all columns
739
- $header = (columns) ? c.$table.find('.' + ts.css.header).filter('[data-column]').filter(function() {
758
+ $header = (columns) ? c.$table.find('.' + tscss.header).filter('[data-column]').filter(function() {
740
759
  return columns[$(this).data('column')] !== '';
741
760
  }) : '';
742
761
  ts.isProcessing(table, event.type === 'filterStart', columns ? $header : '');
@@ -850,7 +869,7 @@ ts.filter = {
850
869
  // c.columns defined in computeThIndexes()
851
870
  columns = c.columns,
852
871
  arry = $.isArray(wo.filter_cellFilter),
853
- buildFilter = '<tr role="row" class="' + ts.css.filterRow + '">';
872
+ buildFilter = '<tr role="row" class="' + tscss.filterRow + ' ' + c.cssIgnoreRow + '">';
854
873
  for (column = 0; column < columns; column++) {
855
874
  if (arry) {
856
875
  buildFilter += '<td' + ( wo.filter_cellFilter[column] ? ' class="' + wo.filter_cellFilter[column] + '"' : '' ) + '></td>';
@@ -899,9 +918,9 @@ ts.filter = {
899
918
  name = ( $.isArray(wo.filter_cssFilter) ?
900
919
  (typeof wo.filter_cssFilter[column] !== 'undefined' ? wo.filter_cssFilter[column] || '' : '') :
901
920
  wo.filter_cssFilter ) || '';
902
- buildFilter.addClass( ts.css.filter + ' ' + name ).attr('data-column', column);
921
+ buildFilter.addClass( tscss.filter + ' ' + name ).attr('data-column', column);
903
922
  if (disabled) {
904
- buildFilter.attr('placeholder', '').addClass('disabled')[0].disabled = true; // disabled!
923
+ buildFilter.attr('placeholder', '').addClass(tscss.filterDisabled)[0].disabled = true; // disabled!
905
924
  }
906
925
  }
907
926
  }
@@ -995,7 +1014,7 @@ ts.filter = {
995
1014
  }
996
1015
  if (wo.filter_hideFilters) {
997
1016
  // show/hide filter row as needed
998
- c.$table.find('.' + ts.css.filterRow).trigger( combinedFilters === '' ? 'mouseleave' : 'mouseenter' );
1017
+ c.$table.find('.' + tscss.filterRow).trigger( combinedFilters === '' ? 'mouseleave' : 'mouseenter' );
999
1018
  }
1000
1019
  // return if the last search is the same; but filter === false when updating the search
1001
1020
  // see example-widget-filter.html filter toggle buttons
@@ -1021,8 +1040,8 @@ ts.filter = {
1021
1040
  hideFilters: function(table, c) {
1022
1041
  var $filterRow, $filterRow2, timer;
1023
1042
  $(table)
1024
- .find('.' + ts.css.filterRow)
1025
- .addClass('hideme')
1043
+ .find('.' + tscss.filterRow)
1044
+ .addClass(tscss.filterRowHide)
1026
1045
  .bind('mouseenter mouseleave', function(e) {
1027
1046
  // save event object - http://bugs.jquery.com/ticket/12140
1028
1047
  var event = e;
@@ -1030,14 +1049,14 @@ ts.filter = {
1030
1049
  clearTimeout(timer);
1031
1050
  timer = setTimeout(function() {
1032
1051
  if ( /enter|over/.test(event.type) ) {
1033
- $filterRow.removeClass('hideme');
1052
+ $filterRow.removeClass(tscss.filterRowHide);
1034
1053
  } else {
1035
1054
  // don't hide if input has focus
1036
1055
  // $(':focus') needs jQuery 1.6+
1037
1056
  if ( $(document.activeElement).closest('tr')[0] !== $filterRow[0] ) {
1038
1057
  // don't hide row if any filter has a value
1039
1058
  if (c.lastCombinedFilter === '') {
1040
- $filterRow.addClass('hideme');
1059
+ $filterRow.addClass(tscss.filterRowHide);
1041
1060
  }
1042
1061
  }
1043
1062
  }
@@ -1050,7 +1069,7 @@ ts.filter = {
1050
1069
  timer = setTimeout(function() {
1051
1070
  // don't hide row if any filter has a value
1052
1071
  if (ts.getFilters(c.$table).join('') === '') {
1053
- $filterRow2[ event.type === 'focus' ? 'removeClass' : 'addClass']('hideme');
1072
+ $filterRow2[ event.type === 'focus' ? 'removeClass' : 'addClass'](tscss.filterRowHide);
1054
1073
  }
1055
1074
  }, 200);
1056
1075
  });
@@ -1538,7 +1557,7 @@ ts.filter = {
1538
1557
  // t.data('placeholder') won't work in jQuery older than 1.4.3
1539
1558
  options = '<option value="">' + ( node.data('placeholder') || node.attr('data-placeholder') || wo.filter_placeholder.select || '' ) + '</option>',
1540
1559
  // Get curent filter value
1541
- currentValue = c.$table.find('thead').find('select.' + ts.css.filter + '[data-column="' + column + '"]').val();
1560
+ currentValue = c.$table.find('thead').find('select.' + tscss.filter + '[data-column="' + column + '"]').val();
1542
1561
  // nothing included in arry (external source), so get the options from filter_selectSource or column data
1543
1562
  if (typeof arry === 'undefined' || arry === '') {
1544
1563
  arry = ts.filter.getOptionSource(table, column, onlyAvail);
@@ -1565,7 +1584,7 @@ ts.filter = {
1565
1584
  }
1566
1585
 
1567
1586
  // update all selects in the same column (clone thead in sticky headers & any external selects) - fixes 473
1568
- $filters = ( c.$filters ? c.$filters : c.$table.children('thead') ).find('.' + ts.css.filter);
1587
+ $filters = ( c.$filters ? c.$filters : c.$table.children('thead') ).find('.' + tscss.filter);
1569
1588
  if (wo.filter_$externalFilters) {
1570
1589
  $filters = $filters && $filters.length ? $filters.add(wo.filter_$externalFilters) : wo.filter_$externalFilters;
1571
1590
  }
@@ -1609,7 +1628,7 @@ ts.getFilters = function(table, getRaw, setFilters, skipFirst) {
1609
1628
  }
1610
1629
  if (c) {
1611
1630
  if (c.$filters) {
1612
- $filters = c.$filters.find('.' + ts.css.filter);
1631
+ $filters = c.$filters.find('.' + tscss.filter);
1613
1632
  }
1614
1633
  if (wo.filter_$externalFilters) {
1615
1634
  $filters = $filters && $filters.length ? $filters.add(wo.filter_$externalFilters) : wo.filter_$externalFilters;
@@ -1675,7 +1694,7 @@ ts.setFilters = function(table, filter, apply, skipFirst) {
1675
1694
 
1676
1695
  })(jQuery);
1677
1696
 
1678
- /*! Widget: stickyHeaders - updated 3/5/2015 (v2.21.0) *//*
1697
+ /*! Widget: stickyHeaders - updated 3/26/2015 (v2.21.3) *//*
1679
1698
  * Requires tablesorter v2.8+ and jQuery 1.4.3+
1680
1699
  * by Rob Garrison
1681
1700
  */
@@ -1772,7 +1791,7 @@ ts.addWidget({
1772
1791
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.height() : 0,
1773
1792
  // clone table, then wrap to make sticky header
1774
1793
  $stickyTable = wo.$sticky = $table.clone()
1775
- .addClass('containsStickyHeaders ' + ts.css.sticky + ' ' + wo.stickyHeaders)
1794
+ .addClass('containsStickyHeaders ' + ts.css.sticky + ' ' + wo.stickyHeaders + ' ' + c.namespace.slice(1) + '_extra_table' )
1776
1795
  .wrap('<div class="' + ts.css.stickyWrap + '">'),
1777
1796
  $stickyWrap = $stickyTable.parent()
1778
1797
  .addClass(ts.css.stickyHide)
@@ -1830,13 +1849,6 @@ ts.addWidget({
1830
1849
  if ($attach.length && !$attach.css('position')) {
1831
1850
  $attach.css('position', 'relative');
1832
1851
  }
1833
- // save stickyTable element to config
1834
- // it is also saved to wo.$sticky
1835
- if (c.$extraTables && c.$extraTables.length) {
1836
- c.$extraTables.add($stickyTable);
1837
- } else {
1838
- c.$extraTables = $stickyTable;
1839
- }
1840
1852
  // fix clone ID, if it exists - fixes #271
1841
1853
  if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
1842
1854
  // clear out cloned table, except for sticky header
@@ -1856,7 +1868,7 @@ ts.addWidget({
1856
1868
  resizeHeader();
1857
1869
  });
1858
1870
 
1859
- ts.bindEvents(table, $stickyThead.children().children('.tablesorter-header'));
1871
+ ts.bindEvents(table, $stickyThead.children().children('.' + ts.css.header));
1860
1872
 
1861
1873
  // add stickyheaders AFTER the table. If the table is selected by ID, the original one (first) will be returned.
1862
1874
  $table.after( $stickyWrap );
@@ -1954,182 +1966,320 @@ ts.addWidget({
1954
1966
 
1955
1967
  })(jQuery, window);
1956
1968
 
1957
- /*! Widget: resizable */
1969
+ /*! Widget: resizable - updated 3/26/2015 (v2.21.3) */
1958
1970
  ;(function ($, window) {
1959
1971
  'use strict';
1960
1972
  var ts = $.tablesorter = $.tablesorter || {};
1961
1973
 
1962
1974
  $.extend(ts.css, {
1963
- resizer : 'tablesorter-resizer' // resizable
1975
+ resizableContainer : 'tablesorter-resizable-container',
1976
+ resizableHandle : 'tablesorter-resizable-handle',
1977
+ resizableNoSelect : 'tablesorter-disableSelection',
1978
+ resizableStorage : 'tablesorter-resizable'
1964
1979
  });
1965
1980
 
1966
- // this widget saves the column widths if
1967
- // $.tablesorter.storage function is included
1968
- // **************************
1969
- ts.addWidget({
1970
- id: "resizable",
1971
- priority: 40,
1972
- options: {
1973
- resizable : true,
1974
- resizable_addLastColumn : false,
1975
- resizable_widths : [],
1976
- resizable_throttle : false // set to true (5ms) or any number 0-10 range
1981
+ // Add extra scroller css
1982
+ $(function(){
1983
+ var s = '<style>' +
1984
+ 'body.' + ts.css.resizableNoSelect + ' { -ms-user-select: none; -moz-user-select: -moz-none;' +
1985
+ '-khtml-user-select: none; -webkit-user-select: none; user-select: none; }' +
1986
+ '.' + ts.css.resizableContainer + ' { position: relative; height: 1px; }' +
1987
+ // make handle z-index > than stickyHeader z-index, so the handle stays above sticky header
1988
+ '.' + ts.css.resizableHandle + ' { position: absolute; display: inline-block; width: 8px; top: 1px;' +
1989
+ 'cursor: ew-resize; z-index: 3; user-select: none; -moz-user-select: none; }' +
1990
+ '</style>';
1991
+ $(s).appendTo('body');
1992
+ });
1993
+
1994
+ ts.resizable = {
1995
+ init : function( c, wo ) {
1996
+ if ( c.$table.hasClass( 'hasResizable' ) ) { return; }
1997
+ c.$table.addClass( 'hasResizable' );
1998
+ ts.resizableReset( c.table, true ); // set default widths
1999
+
2000
+ // internal variables
2001
+ wo.resizable_ = {
2002
+ $wrap : c.$table.parent(),
2003
+ mouseXPosition : 0,
2004
+ $target : null,
2005
+ $next : null,
2006
+ overflow : c.$table.parent().css('overflow') === 'auto',
2007
+ fullWidth : Math.abs(c.$table.parent().width() - c.$table.width()) < 20,
2008
+ storedSizes : []
2009
+ };
2010
+
2011
+ var noResize, $header, column, storedSizes,
2012
+ marginTop = parseInt( c.$table.css( 'margin-top' ), 10 );
2013
+
2014
+ wo.resizable_.storedSizes = storedSizes = ( ( ts.storage && wo.resizable !== false ) ?
2015
+ ts.storage( c.table, ts.css.resizableStorage ) :
2016
+ [] ) || [];
2017
+ ts.resizable.setWidths( c, wo, storedSizes );
2018
+
2019
+ wo.$resizable_container = $( '<div class="' + ts.css.resizableContainer + '">' )
2020
+ .css({ top : marginTop })
2021
+ .insertBefore( c.$table );
2022
+ // add container
2023
+ for ( column = 0; column < c.columns; column++ ) {
2024
+ $header = c.$headerIndexed[ column ];
2025
+ noResize = ts.getData( $header, ts.getColumnData( c.table, c.headers, column ), 'resizable' ) === 'false';
2026
+ if ( !noResize ) {
2027
+ $( '<div class="' + ts.css.resizableHandle + '">' )
2028
+ .appendTo( wo.$resizable_container )
2029
+ .attr({
2030
+ 'data-column' : column,
2031
+ 'unselectable' : 'on'
2032
+ })
2033
+ .data( 'header', $header )
2034
+ .bind( 'selectstart', false );
2035
+ }
2036
+ }
2037
+ c.$table.one('tablesorter-initialized', function() {
2038
+ ts.resizable.setHandlePosition( c, wo );
2039
+ ts.resizable.bindings( this.config, this.config.widgetOptions );
2040
+ });
1977
2041
  },
1978
- format: function(table, c, wo) {
1979
- if (c.$table.hasClass('hasResizable')) { return; }
1980
- c.$table.addClass('hasResizable');
1981
- ts.resizableReset(table, true); // set default widths
1982
- var $rows, $columns, $column, column, timer,
1983
- storedSizes = {},
1984
- $table = c.$table,
1985
- $wrap = $table.parent(),
1986
- overflow = $table.parent().css('overflow') === 'auto',
1987
- mouseXPosition = 0,
1988
- $target = null,
1989
- $next = null,
1990
- fullWidth = Math.abs($table.parent().width() - $table.width()) < 20,
1991
- mouseMove = function(event){
1992
- if (mouseXPosition === 0 || !$target) { return; }
1993
- // resize columns
1994
- var leftEdge = event.pageX - mouseXPosition,
1995
- targetWidth = $target.width();
1996
- $target.width( targetWidth + leftEdge );
1997
- if ($target.width() !== targetWidth && fullWidth) {
1998
- $next.width( $next.width() - leftEdge );
1999
- } else if (overflow) {
2000
- $table.width(function(i, w){
2001
- return w + leftEdge;
2002
- });
2003
- if (!$next.length) {
2004
- // if expanding right-most column, scroll the wrapper
2005
- $wrap[0].scrollLeft = $table.width();
2006
- }
2007
- }
2008
- mouseXPosition = event.pageX;
2009
- },
2010
- stopResize = function() {
2011
- if (ts.storage && $target && $next) {
2012
- storedSizes = {};
2013
- storedSizes[$target.index()] = $target.width();
2014
- storedSizes[$next.index()] = $next.width();
2015
- $target.width( storedSizes[$target.index()] );
2016
- $next.width( storedSizes[$next.index()] );
2017
- if (wo.resizable !== false) {
2018
- // save all column widths
2019
- ts.storage(table, 'tablesorter-resizable', c.$headers.map(function(){ return $(this).width(); }).get() );
2020
- }
2021
- }
2022
- mouseXPosition = 0;
2023
- $target = $next = null;
2024
- $(window).trigger('resize'); // will update stickyHeaders, just in case
2025
- };
2026
- storedSizes = (ts.storage && wo.resizable !== false) ? ts.storage(table, 'tablesorter-resizable') : {};
2042
+
2043
+ setWidth : function( $el, width ) {
2044
+ $el.css({
2045
+ 'width' : width,
2046
+ 'min-width' : '',
2047
+ 'max-width' : ''
2048
+ });
2049
+ },
2050
+
2051
+ setWidths : function( c, wo, storedSizes ) {
2052
+ var column,
2053
+ $extra = $( c.namespace + '_extra_headers' ),
2054
+ $col = c.$table.children( 'colgroup' ).children( 'col' );
2055
+ storedSizes = storedSizes || wo.resizable_.storedSizes || [];
2027
2056
  // process only if table ID or url match
2028
- if (storedSizes) {
2029
- for (column in storedSizes) {
2030
- if (!isNaN(column) && column < c.$headers.length) {
2031
- c.$headers.eq(column).width(storedSizes[column]); // set saved resizable widths
2057
+ if ( storedSizes.length ) {
2058
+ for ( column = 0; column < c.columns; column++ ) {
2059
+ // set saved resizable widths
2060
+ c.$headers.eq( column ).width( storedSizes[ column ] );
2061
+ if ( $extra.length ) {
2062
+ // stickyHeaders needs to modify min & max width as well
2063
+ ts.resizable.setWidth( $extra.eq( column ).add( $col.eq( column ) ), storedSizes[ column ] );
2032
2064
  }
2033
2065
  }
2066
+ if ( $( c.namespace + '_extra_table' ).length && !ts.hasWidget( c.table, 'scroller' ) ) {
2067
+ ts.resizable.setWidth( $( c.namespace + '_extra_table' ), c.$table.outerWidth() );
2068
+ }
2034
2069
  }
2035
- $rows = $table.children('thead:first').children('tr');
2036
- // add resizable-false class name to headers (across rows as needed)
2037
- $rows.children().each(function() {
2038
- var canResize,
2039
- $column = $(this);
2040
- column = $column.attr('data-column');
2041
- canResize = ts.getData( $column, ts.getColumnData( table, c.headers, column ), 'resizable') === "false";
2042
- $rows.children().filter('[data-column="' + column + '"]')[canResize ? 'addClass' : 'removeClass']('resizable-false');
2043
- });
2044
- // add wrapper inside each cell to allow for positioning of the resizable target block
2045
- $rows.each(function() {
2046
- $column = $(this).children().not('.resizable-false');
2047
- if (!$(this).find('.' + ts.css.wrapper).length) {
2048
- // Firefox needs this inner div to position the resizer correctly
2049
- $column.wrapInner('<div class="' + ts.css.wrapper + '" style="position:relative;height:100%;width:100%"></div>');
2070
+ },
2071
+
2072
+ setHandlePosition : function( c, wo ) {
2073
+ var tableWidth = c.$table.outerWidth(),
2074
+ hasScroller = ts.hasWidget( c.table, 'scroller' ),
2075
+ tableHeight = c.$table.height(),
2076
+ $handles = wo.$resizable_container.children(),
2077
+ handleCenter = Math.floor( $handles.width() / 2 - parseFloat( c.$headers.css( 'border-right-width' ) ) * 2 );
2078
+
2079
+ if ( hasScroller ) {
2080
+ tableHeight = 0;
2081
+ c.$table.closest( '.' + ts.css.scrollerWrap ).children().each(function(){
2082
+ var $this = $(this);
2083
+ // center table has a max-height set
2084
+ tableHeight += $this.filter('[style*="height"]').length ? $this.height() : $this.children('table').height();
2085
+ });
2086
+ }
2087
+ $handles.each( function() {
2088
+ var $this = $(this),
2089
+ column = parseInt( $this.attr( 'data-column' ), 10 ),
2090
+ columns = c.columns - 1,
2091
+ $header = $this.data( 'header' );
2092
+ if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
2093
+ $this.css({
2094
+ height : tableHeight,
2095
+ left : $header.position().left + $header.width() - handleCenter
2096
+ });
2050
2097
  }
2051
- // don't include the last column of the row
2052
- if (!wo.resizable_addLastColumn) { $column = $column.slice(0,-1); }
2053
- $columns = $columns ? $columns.add($column) : $column;
2054
2098
  });
2055
- $columns
2056
- .each(function() {
2057
- var $column = $(this),
2058
- padding = parseInt($column.css('padding-right'), 10) + 10; // 10 is 1/2 of the 20px wide resizer
2059
- $column
2060
- .find('.' + ts.css.wrapper)
2061
- .append('<div class="' + ts.css.resizer + '" style="cursor:w-resize;position:absolute;z-index:1;right:-' +
2062
- padding + 'px;top:0;height:100%;width:20px;"></div>');
2063
- })
2064
- .find('.' + ts.css.resizer)
2065
- .bind('mousedown', function(event) {
2099
+ },
2100
+
2101
+ // prevent text selection while dragging resize bar
2102
+ toggleTextSelection : function( c, toggle ) {
2103
+ var namespace = c.namespace + 'tsresize';
2104
+ c.widgetOptions.resizable_.disabled = toggle;
2105
+ $( 'body' ).toggleClass( ts.css.resizableNoSelect, toggle );
2106
+ if ( toggle ) {
2107
+ $( 'body' )
2108
+ .attr( 'unselectable', 'on' )
2109
+ .bind( 'selectstart' + namespace, false );
2110
+ } else {
2111
+ $( 'body' )
2112
+ .removeAttr( 'unselectable' )
2113
+ .unbind( 'selectstart' + namespace );
2114
+ }
2115
+ },
2116
+
2117
+ bindings : function( c, wo ) {
2118
+ var namespace = c.namespace + 'tsresize';
2119
+ wo.$resizable_container.children().bind( 'mousedown', function( event ) {
2066
2120
  // save header cell and mouse position
2067
- $target = $(event.target).closest('th');
2068
- var $header = c.$headers.filter('[data-column="' + $target.attr('data-column') + '"]');
2069
- if ($header.length > 1) { $target = $target.add($header); }
2121
+ var column,
2122
+ vars = wo.resizable_,
2123
+ $extras = $( c.namespace + '_extra_headers' ),
2124
+ $header = $( event.target ).data( 'header' );
2125
+
2126
+ column = parseInt( $header.attr( 'data-column' ), 10 );
2127
+ vars.$target = $header = $header.add( $extras.filter('[data-column="' + column + '"]') );
2128
+ vars.target = column;
2129
+
2070
2130
  // if table is not as wide as it's parent, then resize the table
2071
- $next = event.shiftKey ? $target.parent().find('th').not('.resizable-false').filter(':last') : $target.nextAll(':not(.resizable-false)').eq(0);
2072
- mouseXPosition = event.pageX;
2131
+ vars.$next = event.shiftKey || wo.resizable_targetLast ?
2132
+ $header.parent().children().not( '.resizable-false' ).filter( ':last' ) :
2133
+ $header.nextAll( ':not(.resizable-false)' ).eq( 0 );
2134
+
2135
+ column = parseInt( vars.$next.attr( 'data-column' ), 10 );
2136
+ vars.$next = vars.$next.add( $extras.filter('[data-column="' + column + '"]') );
2137
+ vars.next = column;
2138
+
2139
+ vars.mouseXPosition = event.pageX;
2140
+ vars.storedSizes = c.$headers.map(function(){ return $(this).width(); }).get();
2141
+ ts.resizable.toggleTextSelection( c, true );
2073
2142
  });
2074
- $(document)
2075
- .bind('mousemove.tsresize', function(event) {
2076
- // ignore mousemove if no mousedown
2077
- if (mouseXPosition === 0 || !$target) { return; }
2078
- if (wo.resizable_throttle) {
2079
- clearTimeout(timer);
2080
- timer = setTimeout(function(){
2081
- mouseMove(event);
2082
- }, isNaN(wo.resizable_throttle) ? 5 : wo.resizable_throttle );
2083
- } else {
2084
- mouseMove(event);
2085
- }
2086
- })
2087
- .bind('mouseup.tsresize', function() {
2088
- stopResize();
2143
+
2144
+ $( document )
2145
+ .bind( 'mousemove' + namespace, function( event ) {
2146
+ var vars = wo.resizable_;
2147
+ // ignore mousemove if no mousedown
2148
+ if ( !vars.disabled || vars.mouseXPosition === 0 || !vars.$target ) { return; }
2149
+ if ( wo.resizable_throttle ) {
2150
+ clearTimeout( vars.timer );
2151
+ vars.timer = setTimeout( function() {
2152
+ ts.resizable.mouseMove( c, wo, event );
2153
+ }, isNaN( wo.resizable_throttle ) ? 5 : wo.resizable_throttle );
2154
+ } else {
2155
+ ts.resizable.mouseMove( c, wo, event );
2156
+ }
2157
+ })
2158
+ .bind( 'mouseup' + namespace, function() {
2159
+ if (!wo.resizable_.disabled) { return; }
2160
+ ts.resizable.toggleTextSelection( c, false );
2161
+ ts.resizable.stopResize( c, wo );
2162
+ ts.resizable.setHandlePosition( c, wo );
2163
+ });
2164
+
2165
+ // resizeEnd event triggered by scroller widget
2166
+ $( window ).bind( 'resize' + namespace + ' resizeEnd' + namespace, function() {
2167
+ ts.resizable.setHandlePosition( c, wo );
2089
2168
  });
2090
2169
 
2091
2170
  // right click to reset columns to default widths
2092
- $table.find('thead:first').bind('contextmenu.tsresize', function() {
2093
- ts.resizableReset(table);
2171
+ c.$table.find( 'thead:first' ).add( $( c.namespace + '_extra_table' ).find( 'thead:first' ) )
2172
+ .bind( 'contextmenu' + namespace, function() {
2094
2173
  // $.isEmptyObject() needs jQuery 1.4+; allow right click if already reset
2095
- var allowClick = $.isEmptyObject ? $.isEmptyObject(storedSizes) : true;
2096
- storedSizes = {};
2174
+ var allowClick = wo.resizable_.storedSizes.length === 0;
2175
+ ts.resizableReset( c.table );
2176
+ ts.resizable.setHandlePosition( c, wo );
2177
+ wo.resizable_.storedSizes = [];
2097
2178
  return allowClick;
2098
2179
  });
2180
+
2099
2181
  },
2100
- remove: function(table, c) {
2101
- c.$table
2102
- .removeClass('hasResizable')
2103
- .children('thead')
2104
- .unbind('mouseup.tsresize mouseleave.tsresize contextmenu.tsresize')
2105
- .children('tr').children()
2106
- .unbind('mousemove.tsresize mouseup.tsresize')
2107
- // don't remove "tablesorter-wrapper" as uitheme uses it too
2108
- .find('.' + ts.css.resizer).remove();
2109
- ts.resizableReset(table);
2182
+
2183
+ mouseMove : function( c, wo, event ) {
2184
+ if ( wo.resizable_.mouseXPosition === 0 || !wo.resizable_.$target ) { return; }
2185
+ // resize columns
2186
+ var vars = wo.resizable_,
2187
+ $target = vars.$target,
2188
+ $next = vars.$next,
2189
+ leftEdge = event.pageX - vars.mouseXPosition,
2190
+ targetWidth = $target.width();
2191
+ if ( vars.fullWidth ) {
2192
+ vars.storedSizes[ vars.target ] += leftEdge;
2193
+ vars.storedSizes[ vars.next ] -= leftEdge;
2194
+ ts.resizable.setWidths( c, wo );
2195
+
2196
+ } else if ( vars.overflow ) {
2197
+ c.$table.add( $( c.namespace + '_extra_table' ) ).width(function(i, w){
2198
+ return w + leftEdge;
2199
+ });
2200
+ if ( !$next.length ) {
2201
+ // if expanding right-most column, scroll the wrapper
2202
+ vars.$wrap[0].scrollLeft = c.$table.width();
2203
+ }
2204
+ } else {
2205
+ vars.storedSizes[ vars.target ] += leftEdge;
2206
+ ts.resizable.setWidths( c, wo );
2207
+ }
2208
+ vars.mouseXPosition = event.pageX;
2209
+ },
2210
+
2211
+ stopResize : function( c, wo ) {
2212
+ var vars = wo.resizable_;
2213
+ vars.storedSizes = [];
2214
+ if ( ts.storage ) {
2215
+ vars.storedSizes = c.$headers.map(function(){ return $(this).width(); }).get();
2216
+ if ( wo.resizable !== false ) {
2217
+ // save all column widths
2218
+ ts.storage( c.table, ts.css.resizableStorage, vars.storedSizes );
2219
+ }
2220
+ }
2221
+ vars.mouseXPosition = 0;
2222
+ vars.$target = vars.$next = null;
2223
+ $(window).trigger('resize'); // will update stickyHeaders, just in case
2224
+ }
2225
+ };
2226
+
2227
+ // this widget saves the column widths if
2228
+ // $.tablesorter.storage function is included
2229
+ // **************************
2230
+ ts.addWidget({
2231
+ id: "resizable",
2232
+ priority: 40,
2233
+ options: {
2234
+ resizable : true,
2235
+ resizable_addLastColumn : false,
2236
+ resizable_widths : [],
2237
+ resizable_throttle : false, // set to true (5ms) or any number 0-10 range
2238
+ resizable_targetLast : false
2239
+ },
2240
+ init: function(table, thisWidget, c, wo) {
2241
+ ts.resizable.init( c, wo );
2242
+ },
2243
+ remove: function( table, c, wo ) {
2244
+ if (wo.$resizable_container) {
2245
+ var namespace = c.namespace + 'tsresize';
2246
+ c.$table.add( $( c.namespace + '_extra_table' ) )
2247
+ .removeClass('hasResizable')
2248
+ .children( 'thead' ).unbind( 'contextmenu' + namespace );
2249
+
2250
+ wo.$resizable_container.remove();
2251
+ ts.resizable.toggleTextSelection( c, false );
2252
+ ts.resizableReset( table );
2253
+ $( document ).unbind( 'mousemove' + namespace + ' mouseup' + namespace );
2254
+ }
2110
2255
  }
2111
2256
  });
2112
- ts.resizableReset = function(table, nosave) {
2113
- $(table).each(function(){
2257
+
2258
+ ts.resizableReset = function( table, nosave ) {
2259
+ $( table ).each(function(){
2114
2260
  var $t,
2115
2261
  c = this.config,
2116
2262
  wo = c && c.widgetOptions;
2117
- if (table && c) {
2118
- c.$headers.each(function(i){
2263
+ if ( table && c ) {
2264
+ c.$headers.each( function( i ) {
2119
2265
  $t = $(this);
2120
- if (wo.resizable_widths && wo.resizable_widths[i]) {
2121
- $t.css('width', wo.resizable_widths[i]);
2122
- } else if (!$t.hasClass('resizable-false')) {
2266
+ if ( wo.resizable_widths && wo.resizable_widths[ i ] ) {
2267
+ $t.css( 'width', wo.resizable_widths[ i ] );
2268
+ } else if ( !$t.hasClass( 'resizable-false' ) ) {
2123
2269
  // don't clear the width of any column that is not resizable
2124
- $t.css('width','');
2270
+ $t.css( 'width', '' );
2125
2271
  }
2126
2272
  });
2127
- if (ts.storage && !nosave) { ts.storage(this, 'tablesorter-resizable', {}); }
2273
+ // reset stickyHeader widths
2274
+ $( window ).trigger( 'resize' );
2275
+ if ( ts.storage && !nosave ) {
2276
+ ts.storage( this, ts.css.resizableStorage, {} );
2277
+ }
2128
2278
  }
2129
2279
  });
2130
2280
  };
2131
2281
 
2132
- })(jQuery, window);
2282
+ })( jQuery, window );
2133
2283
 
2134
2284
  /*! Widget: saveSort */
2135
2285
  ;(function ($) {