jquery-tablesorter 1.12.8 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) 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 +115 -67
  5. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +62 -40
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +251 -118
  7. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +48 -24
  8. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-iso8601.js +5 -4
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +16 -10
  10. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-two-digit-year.js +26 -19
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +16 -10
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +7 -4
  13. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +121 -0
  14. data/vendor/assets/javascripts/jquery-tablesorter/parsers/{parser-ipv6.js → parser-network.js} +66 -17
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +10 -7
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +62 -35
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +197 -174
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +3 -6
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +145 -62
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-repeatheaders.js +1 -1
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +16 -14
  22. data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +2 -2
  23. data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +2 -2
  24. data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +2 -2
  25. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +2 -2
  26. data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +2 -2
  27. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +2 -2
  28. data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +2 -2
  29. data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +2 -2
  30. data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +2 -2
  31. data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +4 -1
  32. data/vendor/assets/stylesheets/jquery-tablesorter/theme.metro-dark.css +4 -4
  33. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f537540ad9cb3ae7519f0ede00b10a967df49b5
4
- data.tar.gz: 4e043ff89f30abfa0bb964799a352dbe63d61b81
3
+ metadata.gz: 352f918783831cc401eb8b3c9a8ed8d0b1dbf1aa
4
+ data.tar.gz: 8d49de1c504051729de9cb5a9434542c479a9f0c
5
5
  SHA512:
6
- metadata.gz: a1ee4421ddd5364f2f8471cdfa0ca6c1a9ef3794f53721092a859236b7492e756c3a925a7e9d4e6c5bc2725d2d8ba29be917ff82c9bb85972c218090ad54bf1a
7
- data.tar.gz: c71c7fd64e88115f2a3fb66a3205c050001c4da2cfed4cf0a1178a4a18932d2ede7d40cc0b43b2ae25cfa3d1ad9e21bc32880acf0ceb5f001d2887817d54a4f3
6
+ metadata.gz: 4e11a4e7722b7eb97301d93caa25eefcade3a83750f68cb0a9608947e0d728537db07e408af70ec553269994569b6b66819467fec67aa0e96da1d5ef27cb32de
7
+ data.tar.gz: 9e1d3646f6ce66a39135020b2a94359018c96f824834046fb21e302879b336d98a7b50e18252fa52f518824db5a184969cf981232a273cfc14adbf6725deb125
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.17.8 (9/15/2014), [documentation]
7
+ Current tablesorter version: 2.18.0 (10/26/2014), [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.12.8'
2
+ VERSION = '1.13.0'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * tablesorter pager plugin
3
- * updated 9/15/2014 (v2.17.8)
3
+ * updated 10/26/2014 (v2.18.0)
4
4
  */
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  ;(function($) {
@@ -131,16 +131,10 @@
131
131
  }
132
132
  },
133
133
 
134
- updatePageDisplay = function(table, p, completed) {
135
- var i, pg, s, $out, regex,
136
- c = table.config,
137
- f = c.$table.hasClass('hasFilters'),
138
- t = [],
139
- sz = p.size || 10; // don't allow dividing by zero
140
- t = [ (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered'), c.selectorRemove.replace(/^(\w+\.)/g,'') ];
141
- if (p.countChildRows) { t.push(c.cssChildRow); }
142
- regex = new RegExp( '(' + t.join('|') + ')' );
143
- if (f && !p.ajaxUrl) {
134
+ calcFilters = function(table, p) {
135
+ var c = table.config,
136
+ hasFilters = c.$table.hasClass('hasFilters');
137
+ if (hasFilters && !p.ajaxUrl) {
144
138
  if ($.isEmptyObject(c.cache)) {
145
139
  // delayInit: true so nothing is in the cache
146
140
  p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( p.countChildRows ? '' : '.' + c.cssChildRow ).length;
@@ -150,11 +144,20 @@
150
144
  p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
151
145
  });
152
146
  }
153
- } else if (!f) {
147
+ } else if (!hasFilters) {
154
148
  p.filteredRows = p.totalRows;
155
149
  }
150
+ },
151
+
152
+ updatePageDisplay = function(table, p, completed) {
153
+ if ( !p.initialized ) { return; }
154
+ var s, t, $out,
155
+ c = table.config,
156
+ sz = p.size || 10; // don't allow dividing by zero
157
+ if (p.countChildRows) { t.push(c.cssChildRow); }
156
158
  p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
157
159
  c.totalRows = p.totalRows;
160
+ calcFilters(table, p);
158
161
  c.filteredRows = p.filteredRows;
159
162
  p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
160
163
  if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
@@ -188,38 +191,11 @@
188
191
  $out[ ($out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
189
192
  if ( p.$goto.length ) {
190
193
  t = '';
191
- pg = Math.min( p.totalPages, p.filteredPages );
192
- // Filter the options page number link array if it's larger than 'maxOptionSize'
193
- // as large page set links will slow the browser on large dom inserts
194
- var skip_set_size = Math.floor(pg / p.maxOptionSize),
195
- large_collection = pg > p.maxOptionSize,
196
- current_page = p.page + 1,
197
- start_page = 1,
198
- end_page = pg,
199
- option_pages = [];
200
- //construct default options pages array
201
- var option_pages_start_page = (large_collection && current_page == 1) ? skip_set_size : 1;
202
- for (i = option_pages_start_page; i <= pg;) {
203
- option_pages.push(i);
204
- i = large_collection ? i + skip_set_size : i++;
205
- }
206
- if (large_collection) {
207
- var central_focus_size = Math.floor(p.maxOptionSize / 2) - 1,
208
- lower_focus_window = Math.abs(Math.floor(current_page - central_focus_size/2)),
209
- focus_option_pages = [];
210
- start_page = Math.min(current_page, lower_focus_window);
211
- end_page = start_page + central_focus_size;
212
- //construct an array to get a focus set around the current page
213
- for (i = start_page; i <= end_page ; i++) focus_option_pages.push(i);
214
- var insert_index = Math.floor(option_pages.length / 2) - Math.floor(focus_option_pages.length / 2);
215
- Array.prototype.splice.apply(option_pages, [ insert_index, focus_option_pages.length ].concat(focus_option_pages));
216
- option_pages.sort(function sortNumber(a,b) { return a - b; });
217
- }
218
- for ( i = 0; i < option_pages.length; i++) {
219
- t += '<option>' + option_pages[i] + '</option>';
220
- }
221
- p.$goto[0].innerHTML = t;
222
- p.$goto[0].value = current_page;
194
+ $.each(buildPageSelect(p), function(i, opt){
195
+ t += '<option value="' + opt + '">' + opt + '</option>';
196
+ });
197
+ // innerHTML doesn't work in IE9 - http://support2.microsoft.com/kb/276228
198
+ p.$goto.html(t).val( p.page + 1 );
223
199
  }
224
200
  // rebind startRow/page inputs
225
201
  $out.find('.ts-startRow, .ts-page').unbind('change').bind('change', function(){
@@ -230,6 +206,7 @@
230
206
  }
231
207
  }
232
208
  pagerArrows(p);
209
+ fixHeight(table, p);
233
210
  if (p.initialized && completed !== false) {
234
211
  c.$table.trigger('pagerComplete', p);
235
212
  // save pager info to storage
@@ -242,26 +219,92 @@
242
219
  }
243
220
  },
244
221
 
222
+ buildPageSelect = function(p) {
223
+ // Filter the options page number link array if it's larger than 'maxOptionSize'
224
+ // as large page set links will slow the browser on large dom inserts
225
+ var i, central_focus_size, focus_option_pages, insert_index, option_length, focus_length,
226
+ pg = Math.min( p.totalPages, p.filteredPages ) || 1,
227
+ // make skip set size multiples of 5
228
+ skip_set_size = Math.ceil( ( pg / p.maxOptionSize ) / 5 ) * 5,
229
+ large_collection = pg > p.maxOptionSize,
230
+ current_page = p.page + 1,
231
+ start_page = skip_set_size,
232
+ end_page = pg - skip_set_size,
233
+ option_pages = [1],
234
+ // construct default options pages array
235
+ option_pages_start_page = (large_collection) ? skip_set_size : 1;
236
+
237
+ for ( i = option_pages_start_page; i <= pg; ) {
238
+ option_pages.push(i);
239
+ i = i + ( large_collection ? skip_set_size : 1 );
240
+ }
241
+ option_pages.push(pg);
242
+ if (large_collection) {
243
+ focus_option_pages = [];
244
+ // don't allow central focus size to be > 5 on either side of current page
245
+ central_focus_size = Math.max( Math.floor( p.maxOptionSize / skip_set_size ) - 1, 5 );
246
+
247
+ start_page = current_page - central_focus_size;
248
+ if (start_page < 1) { start_page = 1; }
249
+ end_page = current_page + central_focus_size;
250
+ if (end_page > pg) { end_page = pg; }
251
+ // construct an array to get a focus set around the current page
252
+ for (i = start_page; i <= end_page ; i++) {
253
+ focus_option_pages.push(i);
254
+ }
255
+
256
+ // keep unique values
257
+ option_pages = $.grep(option_pages, function(value, indx) {
258
+ return $.inArray(value, option_pages) === indx;
259
+ });
260
+
261
+ option_length = option_pages.length;
262
+ focus_length = focus_option_pages.length;
263
+
264
+ // make sure at all option_pages aren't replaced
265
+ if (option_length - focus_length > skip_set_size / 2 && option_length + focus_length > p.maxOptionSize ) {
266
+ insert_index = Math.floor(option_length / 2) - Math.floor(focus_length / 2);
267
+ Array.prototype.splice.apply(option_pages, [ insert_index, focus_length ]);
268
+ }
269
+ option_pages = option_pages.concat(focus_option_pages);
270
+
271
+ }
272
+
273
+ // keep unique values again
274
+ option_pages = $.grep(option_pages, function(value, indx) {
275
+ return $.inArray(value, option_pages) === indx;
276
+ })
277
+ .sort(function(a,b) { return a - b; });
278
+
279
+ return option_pages;
280
+ },
281
+
245
282
  fixHeight = function(table, p) {
246
283
  var d, h,
247
284
  c = table.config,
248
285
  $b = c.$tbodies.eq(0);
249
- if (p.fixedHeight) {
250
- $b.find('tr.pagerSavedHeightSpacer').remove();
286
+ $b.find('tr.pagerSavedHeightSpacer').remove();
287
+ if (p.fixedHeight && !p.isDisabled) {
251
288
  h = $.data(table, 'pagerSavedHeight');
252
289
  if (h) {
253
290
  d = h - $b.height();
254
291
  if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
255
- $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '" style="height:' + d + 'px;"></tr>');
292
+ $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.slice(1) + '" style="height:' + d + 'px;"></tr>');
256
293
  }
257
294
  }
258
295
  }
259
296
  },
260
297
 
261
298
  changeHeight = function(table, p) {
262
- var $b = table.config.$tbodies.eq(0);
299
+ var h,
300
+ c = table.config,
301
+ $b = c.$tbodies.eq(0);
263
302
  $b.find('tr.pagerSavedHeightSpacer').remove();
264
- $.data(table, 'pagerSavedHeight', $b.height());
303
+ if (!$b.children('tr:visible').length) {
304
+ $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.slice(1) + '"><td>&nbsp</td></tr>');
305
+ }
306
+ h = $b.children('tr').eq(0).height() * p.size;
307
+ $.data(table, 'pagerSavedHeight', h);
265
308
  fixHeight(table, p);
266
309
  $.data(table, 'pagerLastSize', p.size);
267
310
  },
@@ -418,8 +461,7 @@
418
461
  p.last.totalRows = p.totalRows;
419
462
  p.last.currentFilters = p.currentFilters;
420
463
  p.last.sortList = (c.sortList || []).join(',');
421
- updatePageDisplay(table, p);
422
- fixHeight(table, p);
464
+ updatePageDisplay(table, p, true);
423
465
  $t.trigger('updateCache', [function(){
424
466
  if (p.initialized) {
425
467
  // apply widgets after table has rendered & after a delay to prevent
@@ -560,8 +602,7 @@
560
602
  }
561
603
  ts.processTbody(table, $tb, false);
562
604
  }
563
- updatePageDisplay(table, p);
564
- if ( !p.isDisabled ) { fixHeight(table, p); }
605
+ updatePageDisplay(table, p, true);
565
606
  if (table.isUpdating) {
566
607
  $t.trigger('updateComplete', [ table, true ]);
567
608
  }
@@ -612,13 +653,14 @@
612
653
 
613
654
  moveToPage = function(table, p, pageMoved) {
614
655
  if ( p.isDisabled ) { return; }
615
- var c = table.config,
656
+ var pg, c = table.config,
616
657
  $t = $(table),
617
- l = p.last,
618
- pg = Math.min( p.totalPages, p.filteredPages );
619
- if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
658
+ l = p.last;
659
+ if ( pageMoved !== false && p.initialized && $.isEmptyObject(c.cache)) {
620
660
  return updateCache(table);
621
661
  }
662
+ calcFilters(table, p);
663
+ pg = Math.min( p.totalPages, p.filteredPages );
622
664
  if ( p.page < 0 ) { p.page = 0; }
623
665
  if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
624
666
  // fixes issue where one currentFilter is [] and the other is ['','',''],
@@ -628,6 +670,10 @@
628
670
  // don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
629
671
  if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
630
672
  (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
673
+ // check for ajax url changes see #730
674
+ (l.ajaxUrl || '') === (p.ajaxObject.url || '') &&
675
+ // & ajax url option changes (dynamically add/remove/rename sort & filter parameters)
676
+ (l.optAjaxUrl || '') === (p.ajaxUrl || '') &&
631
677
  l.sortList === (c.sortList || []).join(',') ) { return; }
632
678
  if (c.debug) {
633
679
  ts.log('Pager changing to page ' + p.page);
@@ -638,7 +684,9 @@
638
684
  // fixes #408; modify sortList otherwise it auto-updates
639
685
  sortList : (c.sortList || []).join(','),
640
686
  totalRows : p.totalRows,
641
- currentFilters : p.currentFilters || []
687
+ currentFilters : p.currentFilters || [],
688
+ ajaxUrl : p.ajaxObject.url || '',
689
+ optAjaxUrl : p.ajaxUrl || ''
642
690
  };
643
691
  if (p.ajax) {
644
692
  getAjax(table, p);
@@ -722,11 +770,11 @@
722
770
  p.$container.find(p.cssPageDisplay).attr('id', info);
723
771
  c.$table.attr('aria-describedby', info);
724
772
  }
773
+ changeHeight(table, p);
725
774
  if ( triggered ) {
726
775
  c.$table.trigger('updateRows');
727
776
  setPageSize(table, p.size, p);
728
777
  hideRowsSetup(table, p);
729
- fixHeight(table, p);
730
778
  if (c.debug) {
731
779
  ts.log('pager enabled');
732
780
  }
@@ -781,7 +829,7 @@
781
829
  p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '|' + c.cssChildRow + ')');
782
830
 
783
831
  $t
784
- .unbind('filterStart filterEnd sortEnd disable enable destroy updateComplete pageSize '.split(' ').join('.pager '))
832
+ .unbind('filterStart filterEnd sortEnd disable enable destroy updateComplete pageSize pageSet '.split(' ').join('.pager '))
785
833
  .bind('filterStart.pager', function(e, filters) {
786
834
  p.currentFilters = filters;
787
835
  // don't change page is filters are the same (pager updating, etc)
@@ -796,11 +844,9 @@
796
844
  // make sure we have a copy of all table rows once the cache has been built
797
845
  updateCache(table);
798
846
  }
799
- // update page display first, so we update p.filteredPages
800
- updatePageDisplay(table, p, false);
801
847
  moveToPage(table, p, false);
802
848
  c.$table.trigger('applyWidgets');
803
- fixHeight(table, p);
849
+ updatePageDisplay(table, p, false);
804
850
  }
805
851
  })
806
852
  .bind('disable.pager', function(e){
@@ -819,7 +865,6 @@
819
865
  e.stopPropagation();
820
866
  // table can be unintentionally undefined in tablesorter v2.17.7 and earlier
821
867
  if ( !table || triggered ) { return; }
822
- fixHeight(table, p);
823
868
  var $rows = c.$tbodies.eq(0).children('tr').not(c.selectorRemove);
824
869
  p.totalRows = $rows.length - ( p.countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
825
870
  p.totalPages = Math.ceil( p.totalRows / p.size );
@@ -827,8 +872,12 @@
827
872
  // make a copy of all table rows once the cache has been built
828
873
  updateCache(table);
829
874
  }
830
- updatePageDisplay(table, p);
875
+ if ( p.page >= p.totalPages ) {
876
+ moveToLastPage(table, p);
877
+ }
831
878
  hideRows(table, p);
879
+ changeHeight(table, p);
880
+ updatePageDisplay(table, p, true);
832
881
  })
833
882
  .bind('pageSize.pager', function(e,v){
834
883
  e.stopPropagation();
@@ -912,11 +961,10 @@
912
961
  hideRowsSetup(table, p);
913
962
  }
914
963
 
915
- changeHeight(table, p);
916
-
917
964
  // pager initialized
918
965
  if (!p.ajax) {
919
966
  p.initialized = true;
967
+ updatePageDisplay(table, p, true);
920
968
  $(table).trigger('pagerInitialized', p);
921
969
  }
922
970
  });
@@ -1,5 +1,5 @@
1
1
  /**!
2
- * TableSorter 2.17.8 - Client-side table sorting with ease!
2
+ * TableSorter 2.18.0 - Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
5
5
  * Copyright (c) 2007 Christian Bach
@@ -24,7 +24,7 @@
24
24
 
25
25
  var ts = this;
26
26
 
27
- ts.version = "2.17.8";
27
+ ts.version = "2.18.0";
28
28
 
29
29
  ts.parsers = [];
30
30
  ts.widgets = [];
@@ -75,6 +75,7 @@
75
75
  zebra : [ 'even', 'odd' ] // zebra widget alternating row class names
76
76
  },
77
77
  initWidgets : true, // apply widgets on tablesorter initialization
78
+ widgetClass : 'widget-{name}', // table class name template to match to include a widget
78
79
 
79
80
  // *** callbacks
80
81
  initialized : null, // function(table){},
@@ -187,7 +188,7 @@
187
188
  }
188
189
 
189
190
  function detectParserForColumn(table, rows, rowIndex, cellIndex) {
190
- var cur,
191
+ var cur, $node,
191
192
  i = ts.parsers.length,
192
193
  node = false,
193
194
  nodeValue = '',
@@ -197,6 +198,7 @@
197
198
  if (rows[rowIndex]) {
198
199
  node = rows[rowIndex].cells[cellIndex];
199
200
  nodeValue = getElementText(table, node, cellIndex);
201
+ $node = $(node);
200
202
  if (table.config.debug) {
201
203
  log('Checking if value was empty on row ' + rowIndex + ', column: ' + cellIndex + ': "' + nodeValue + '"');
202
204
  }
@@ -207,7 +209,7 @@
207
209
  while (--i >= 0) {
208
210
  cur = ts.parsers[i];
209
211
  // ignore the default text parser because it will always be true
210
- if (cur && cur.id !== 'text' && cur.is && cur.is(nodeValue, table, node)) {
212
+ if (cur && cur.id !== 'text' && cur.is && cur.is(nodeValue, table, node, $node)) {
211
213
  return cur;
212
214
  }
213
215
  }
@@ -457,7 +459,8 @@
457
459
  }
458
460
  $(this).html('<div class="' + ts.css.headerIn + '">' + t + '</div>'); // faster than wrapInner
459
461
  }
460
- if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index]); }
462
+ if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index, c, c.$table]); }
463
+ // *** remove this.column value if no conflicts found
461
464
  this.column = parseInt( $(this).attr('data-column'), 10);
462
465
  this.order = formatSortingOrder( ts.getData($t, ch, 'sortInitialOrder') || c.sortInitialOrder ) ? [1,0,2] : [0,1,2];
463
466
  this.count = -1; // set to -1 because clicking on the header automatically adds one
@@ -648,7 +651,7 @@
648
651
  });
649
652
  }
650
653
  // get current column index
651
- indx = cell.column;
654
+ indx = parseInt( $(cell).attr('data-column'), 10 );
652
655
  // user only wants to sort on one column
653
656
  if (key) {
654
657
  // flush the sort list
@@ -1078,8 +1081,10 @@
1078
1081
  'aria-live' : 'polite',
1079
1082
  'aria-relevant' : 'all'
1080
1083
  });
1081
- if (c.$table.find('caption').length) {
1082
- c.$table.attr('aria-labelledby', 'theCaption');
1084
+ if (c.$table.children('caption').length) {
1085
+ k = c.$table.children('caption')[0];
1086
+ if (!k.id) { k.id = c.namespace.slice(1) + 'caption'; }
1087
+ c.$table.attr('aria-labelledby', k.id);
1083
1088
  }
1084
1089
  c.widgetInit = {}; // keep a list of initialized widgets
1085
1090
  // change textExtraction via data-attribute
@@ -1556,11 +1561,24 @@
1556
1561
  table = $(table)[0]; // in case this is called externally
1557
1562
  var c = table.config,
1558
1563
  wo = c.widgetOptions,
1564
+ tableClass = ' ' + c.table.className + ' ',
1559
1565
  widgets = [],
1560
- time, w, wd;
1566
+ time, time2, w, wd;
1561
1567
  // prevent numerous consecutive widget applications
1562
1568
  if (init !== false && table.hasInitialized && (table.isApplyingWidgets || table.isUpdating)) { return; }
1563
1569
  if (c.debug) { time = new Date(); }
1570
+ // look for widgets to apply from in table class
1571
+ // stop using \b otherwise this matches "ui-widget-content" & adds "content" widget
1572
+ wd = new RegExp( '\\s' + c.widgetClass.replace( /\{name\}/i, '([\\w-]+)' )+ '\\s', 'g' );
1573
+ if ( tableClass.match( wd ) ) {
1574
+ // extract out the widget id from the table class (widget id's can include dashes)
1575
+ w = tableClass.match( wd );
1576
+ if ( w ) {
1577
+ $.each( w, function( i,n ){
1578
+ c.widgets.push( n.replace( wd, '$1' ) );
1579
+ });
1580
+ }
1581
+ }
1564
1582
  if (c.widgets.length) {
1565
1583
  table.isApplyingWidgets = true;
1566
1584
  // ensure unique widget ids
@@ -1590,17 +1608,22 @@
1590
1608
  wo = table.config.widgetOptions = $.extend( true, {}, w.options, wo );
1591
1609
  }
1592
1610
  if (w.hasOwnProperty('init')) {
1611
+ if (c.debug) { time2 = new Date(); }
1593
1612
  w.init(table, w, c, wo);
1613
+ if (c.debug) { ts.benchmark('Initializing ' + w.id + ' widget', time2); }
1594
1614
  }
1595
1615
  }
1596
1616
  if (!init && w.hasOwnProperty('format')) {
1617
+ if (c.debug) { time2 = new Date(); }
1597
1618
  w.format(table, c, wo, false);
1619
+ if (c.debug) { ts.benchmark( ( init ? 'Initializing ' : 'Applying ' ) + w.id + ' widget', time2); }
1598
1620
  }
1599
1621
  }
1600
1622
  });
1601
1623
  }
1602
1624
  setTimeout(function(){
1603
1625
  table.isApplyingWidgets = false;
1626
+ $.data(table, 'lastWidgetApplication', new Date());
1604
1627
  }, 0);
1605
1628
  if (c.debug) {
1606
1629
  w = c.widgets.length;
@@ -1743,23 +1766,6 @@
1743
1766
  type: "numeric"
1744
1767
  });
1745
1768
 
1746
- ts.addParser({
1747
- id: "ipAddress",
1748
- is: function(s) {
1749
- return (/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/).test(s);
1750
- },
1751
- format: function(s, table) {
1752
- var i, a = s ? s.split(".") : '',
1753
- r = "",
1754
- l = a.length;
1755
- for (i = 0; i < l; i++) {
1756
- r += ("00" + a[i]).slice(-3);
1757
- }
1758
- return s ? ts.formatFloat(r, table) : s;
1759
- },
1760
- type: "numeric"
1761
- });
1762
-
1763
1769
  ts.addParser({
1764
1770
  id: "url",
1765
1771
  is: function(s) {
@@ -1778,7 +1784,8 @@
1778
1784
  return (/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/).test(s);
1779
1785
  },
1780
1786
  format: function(s, table) {
1781
- return s ? ts.formatFloat((s !== "") ? (new Date(s.replace(/-/g, "/")).getTime() || s) : "", table) : s;
1787
+ var date = s ? new Date( s.replace(/-/g, "/") ) : s;
1788
+ return date instanceof Date && isFinite(date) ? date.getTime() : s;
1782
1789
  },
1783
1790
  type: "numeric"
1784
1791
  });
@@ -1794,6 +1801,19 @@
1794
1801
  type: "numeric"
1795
1802
  });
1796
1803
 
1804
+ // added image parser to core v2.17.9
1805
+ ts.addParser({
1806
+ id: "image",
1807
+ is: function(s, table, node, $node){
1808
+ return $node.find('img').length > 0;
1809
+ },
1810
+ format: function(s, table, cell) {
1811
+ return $(cell).find('img').attr(table.config.imgAttr || 'alt') || s;
1812
+ },
1813
+ parsed : true, // filter widget flag
1814
+ type: "text"
1815
+ });
1816
+
1797
1817
  ts.addParser({
1798
1818
  id: "usLongDate",
1799
1819
  is: function(s) {
@@ -1802,7 +1822,8 @@
1802
1822
  return (/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i).test(s) || (/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i).test(s);
1803
1823
  },
1804
1824
  format: function(s, table) {
1805
- return s ? ts.formatFloat( (new Date(s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || s), table) : s;
1825
+ var date = s ? new Date( s.replace(/(\S)([AP]M)$/i, "$1 $2") ) : s;
1826
+ return date instanceof Date && isFinite(date) ? date.getTime() : s;
1806
1827
  },
1807
1828
  type: "numeric"
1808
1829
  });
@@ -1815,19 +1836,22 @@
1815
1836
  },
1816
1837
  format: function(s, table, cell, cellIndex) {
1817
1838
  if (s) {
1818
- var c = table.config,
1839
+ var date, d,
1840
+ c = table.config,
1819
1841
  ci = c.$headers.filter('[data-column=' + cellIndex + ']:last'),
1820
1842
  format = ci.length && ci[0].dateFormat || ts.getData( ci, ts.getColumnData( table, c.headers, cellIndex ), 'dateFormat') || c.dateFormat;
1821
- s = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/"); // escaped - because JSHint in Firefox was showing it as an error
1843
+ d = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/"); // escaped - because JSHint in Firefox was showing it as an error
1822
1844
  if (format === "mmddyyyy") {
1823
- s = s.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$1/$2");
1845
+ d = d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$1/$2");
1824
1846
  } else if (format === "ddmmyyyy") {
1825
- s = s.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$2/$1");
1847
+ d = d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$2/$1");
1826
1848
  } else if (format === "yyyymmdd") {
1827
- s = s.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$1/$2/$3");
1849
+ d = d.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$1/$2/$3");
1828
1850
  }
1851
+ date = new Date(d);
1852
+ return date instanceof Date && isFinite(date) ? date.getTime() : s;
1829
1853
  }
1830
- return s ? ts.formatFloat( (new Date(s).getTime() || s), table) : s;
1854
+ return s;
1831
1855
  },
1832
1856
  type: "numeric"
1833
1857
  });
@@ -1838,7 +1862,8 @@
1838
1862
  return (/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i).test(s);
1839
1863
  },
1840
1864
  format: function(s, table) {
1841
- return s ? ts.formatFloat( (new Date("2000/01/01 " + s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || s), table) : s;
1865
+ var date = s ? new Date( "2000/01/01 " + s.replace(/(\S)([AP]M)$/i, "$1 $2") ) : s;
1866
+ return date instanceof Date && isFinite(date) ? date.getTime() : s;
1842
1867
  },
1843
1868
  type: "numeric"
1844
1869
  });
@@ -1882,18 +1907,15 @@
1882
1907
  $tr.removeClass(wo.zebra[even ? 1 : 0]).addClass(wo.zebra[even ? 0 : 1]);
1883
1908
  });
1884
1909
  }
1885
- if (c.debug) {
1886
- ts.benchmark("Applying Zebra widget", time);
1887
- }
1888
1910
  },
1889
1911
  remove: function(table, c, wo){
1890
1912
  var k, $tb,
1891
1913
  b = c.$tbodies,
1892
1914
  rmv = (wo.zebra || [ "even", "odd" ]).join(' ');
1893
1915
  for (k = 0; k < b.length; k++ ){
1894
- $tb = $.tablesorter.processTbody(table, b.eq(k), true); // remove tbody
1916
+ $tb = ts.processTbody(table, b.eq(k), true); // remove tbody
1895
1917
  $tb.children().removeClass(rmv);
1896
- $.tablesorter.processTbody(table, $tb, false); // restore tbody
1918
+ ts.processTbody(table, $tb, false); // restore tbody
1897
1919
  }
1898
1920
  }
1899
1921
  });