datatables.net 2.0.3 → 2.0.5

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.
package/js/dataTables.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! DataTables 2.0.3
1
+ /*! DataTables 2.0.5
2
2
  * © SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -1043,7 +1043,8 @@ var _api_registerPlural; // DataTable.Api.registerPlural
1043
1043
 
1044
1044
  var _re_dic = {};
1045
1045
  var _re_new_lines = /[\r\n\u2028]/g;
1046
- var _re_html = /<.*?>/g;
1046
+ var _re_html = /<([^>]*>)/g;
1047
+ var _max_str_len = Math.pow(2, 28);
1047
1048
 
1048
1049
  // This is not strict ISO8601 - Date.parse() is quite lax, although
1049
1050
  // implementations differ between browsers.
@@ -1231,10 +1232,24 @@ var _removeEmpty = function ( a )
1231
1232
  };
1232
1233
 
1233
1234
  // Replaceable function in api.util
1234
- var _stripHtml = function ( d ) {
1235
- return d
1236
- .replace( _re_html, '' ) // Complete tags
1237
- .replace(/<script/i, ''); // Safety for incomplete script tag
1235
+ var _stripHtml = function (input) {
1236
+ // Irrelevant check to workaround CodeQL's false positive on the regex
1237
+ if (input.length > _max_str_len) {
1238
+ throw new Error('Exceeded max str len');
1239
+ }
1240
+
1241
+ var previous;
1242
+
1243
+ input = input.replace(_re_html, ''); // Complete tags
1244
+
1245
+ // Safety for incomplete script tag - use do / while to ensure that
1246
+ // we get all instances
1247
+ do {
1248
+ previous = input;
1249
+ input = input.replace(/<script/i, '');
1250
+ } while (input !== previous);
1251
+
1252
+ return previous;
1238
1253
  };
1239
1254
 
1240
1255
  // Replaceable function in api.util
@@ -1949,7 +1964,7 @@ function _fnAddColumn( oSettings )
1949
1964
  "mData": oDefaults.mData ? oDefaults.mData : iCol,
1950
1965
  idx: iCol,
1951
1966
  searchFixed: {},
1952
- colEl: $('<col>')
1967
+ colEl: $('<col>').attr('data-dt-column', iCol)
1953
1968
  } );
1954
1969
  oSettings.aoColumns.push( oCol );
1955
1970
 
@@ -2577,9 +2592,15 @@ function _fnGetCellData( settings, rowIdx, colIdx, type )
2577
2592
  type = 'sort';
2578
2593
  }
2579
2594
 
2595
+ var row = settings.aoData[rowIdx];
2596
+
2597
+ if (! row) {
2598
+ return undefined;
2599
+ }
2600
+
2580
2601
  var draw = settings.iDraw;
2581
2602
  var col = settings.aoColumns[colIdx];
2582
- var rowData = settings.aoData[rowIdx]._aData;
2603
+ var rowData = row._aData;
2583
2604
  var defaultContent = col.sDefaultContent;
2584
2605
  var cellData = col.fnGetData( rowData, type, {
2585
2606
  settings: settings,
@@ -3834,7 +3855,7 @@ function _fnDetectHeader ( settings, thead, write )
3834
3855
  }
3835
3856
 
3836
3857
  if (! columnDef.sTitle && unique) {
3837
- columnDef.sTitle = cell.innerHTML.replace( /<.*?>/g, "" );
3858
+ columnDef.sTitle = _stripHtml(cell.innerHTML);
3838
3859
  columnDef.autoTitle = true;
3839
3860
  }
3840
3861
  }
@@ -4455,7 +4476,7 @@ function _fnFilterCreateSearch( search, inOpts )
4455
4476
  word = '';
4456
4477
  }
4457
4478
 
4458
- return word.replace('"', '');
4479
+ return word.replace(/"/g, '');
4459
4480
  } );
4460
4481
 
4461
4482
  var match = not.length
@@ -4987,20 +5008,27 @@ function _fnScrollDraw ( settings )
4987
5008
  // uses a cell which has a longer string, but isn't the widest! For example
4988
5009
  // "Chief Executive Officer (CEO)" is the longest string in the demo, but
4989
5010
  // "Systems Administrator" is actually the widest string since it doesn't collapse.
5011
+ // Note the use of translating into a column index to get the `col` element. This
5012
+ // is because of Responsive which might remove `col` elements, knocking the alignment
5013
+ // of the indexes out.
4990
5014
  if (settings.aiDisplay.length) {
4991
5015
  // Get the column sizes from the first row in the table
4992
- var colSizes = table.find('tbody tr').eq(0).find('th, td').map(function () {
4993
- return $(this).outerWidth();
5016
+ var colSizes = table.find('tbody tr').eq(0).find('th, td').map(function (vis) {
5017
+ return {
5018
+ idx: _fnVisibleToColumnIndex(settings, vis),
5019
+ width: $(this).outerWidth()
5020
+ }
4994
5021
  });
4995
5022
 
4996
5023
  // Check against what the colgroup > col is set to and correct if needed
4997
- $('col', settings.colgroup).each(function (i) {
4998
- var colWidth = this.style.width.replace('px', '');
5024
+ for (var i=0 ; i<colSizes.length ; i++) {
5025
+ var colEl = settings.aoColumns[ colSizes[i].idx ].colEl[0];
5026
+ var colWidth = colEl.style.width.replace('px', '');
4999
5027
 
5000
- if (colWidth !== colSizes[i]) {
5001
- this.style.width = colSizes[i] + 'px';
5028
+ if (colWidth !== colSizes[i].width) {
5029
+ colEl.style.width = colSizes[i].width + 'px';
5002
5030
  }
5003
- });
5031
+ }
5004
5032
  }
5005
5033
 
5006
5034
  // 3. Copy the colgroup over to the header and footer
@@ -6796,6 +6824,10 @@ _Api.extend = function ( scope, obj, ext )
6796
6824
  for ( i=0, ien=ext.length ; i<ien ; i++ ) {
6797
6825
  struct = ext[i];
6798
6826
 
6827
+ if (struct.name === '__proto__') {
6828
+ continue;
6829
+ }
6830
+
6799
6831
  // Value
6800
6832
  obj[ struct.name ] = struct.type === 'function' ?
6801
6833
  _api_scope( scope, struct.val, struct ) :
@@ -7458,16 +7490,7 @@ var _selector_row_indexes = function ( settings, opts )
7458
7490
  order = opts.order, // applied, current, index (original - compatibility with 1.9)
7459
7491
  page = opts.page; // all, current
7460
7492
 
7461
- if ( _fnDataSource( settings ) == 'ssp' ) {
7462
- // In server-side processing mode, most options are irrelevant since
7463
- // rows not shown don't exist and the index order is the applied order
7464
- // Removed is a special case - for consistency just return an empty
7465
- // array
7466
- return search === 'removed' ?
7467
- [] :
7468
- _range( 0, displayMaster.length );
7469
- }
7470
- else if ( page == 'current' ) {
7493
+ if ( page == 'current' ) {
7471
7494
  // Current page implies that order=current and filter=applied, since it is
7472
7495
  // fairly senseless otherwise, regardless of what order and search actually
7473
7496
  // are
@@ -7736,11 +7759,6 @@ _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
7736
7759
  settings.aiDisplayMaster.splice(idx, 1);
7737
7760
  }
7738
7761
 
7739
- idx = settings.aiDisplay.indexOf(row);
7740
- if (idx !== -1) {
7741
- settings.aiDisplay.splice(idx, 1);
7742
- }
7743
-
7744
7762
  // For server-side processing tables - subtract the deleted row from the count
7745
7763
  if ( settings._iRecordsDisplay > 0 ) {
7746
7764
  settings._iRecordsDisplay--;
@@ -7890,8 +7908,9 @@ var __details_state_load = function (api, state)
7890
7908
  {
7891
7909
  if ( state && state.childRows ) {
7892
7910
  api
7893
- .rows( state.childRows.map(function (id){
7894
- return id.replace(/:/g, '\\:')
7911
+ .rows( state.childRows.map(function (id) {
7912
+ // Escape any `:` characters from the row id, unless previously escaped
7913
+ return id.replace(/(?<!\\):/g, '\\:');
7895
7914
  }) )
7896
7915
  .every( function () {
7897
7916
  _fnCallbackFire( api.settings()[0], null, 'requestChild', [ this ] )
@@ -8172,6 +8191,17 @@ var __columnData = function ( settings, column, r1, r2, rows, type ) {
8172
8191
  };
8173
8192
 
8174
8193
 
8194
+ var __column_header = function ( settings, column, row ) {
8195
+ var header = settings.aoHeader;
8196
+ var target = row !== undefined
8197
+ ? row
8198
+ : settings.bSortCellsTop // legacy support
8199
+ ? 0
8200
+ : header.length - 1;
8201
+
8202
+ return header[target][column].cell;
8203
+ };
8204
+
8175
8205
  var __column_selector = function ( settings, selector, opts )
8176
8206
  {
8177
8207
  var
@@ -8204,7 +8234,8 @@ var __column_selector = function ( settings, selector, opts )
8204
8234
  return columns.map(function (col, idx) {
8205
8235
  return s(
8206
8236
  idx,
8207
- __columnData( settings, idx, 0, 0, rows )
8237
+ __columnData( settings, idx, 0, 0, rows ),
8238
+ __column_header( settings, idx )
8208
8239
  ) ? idx : null;
8209
8240
  });
8210
8241
  }
@@ -8349,15 +8380,8 @@ _api_register( 'columns()', function ( selector, opts ) {
8349
8380
  } );
8350
8381
 
8351
8382
  _api_registerPlural( 'columns().header()', 'column().header()', function ( row ) {
8352
- return this.iterator( 'column', function ( settings, column ) {
8353
- var header = settings.aoHeader;
8354
- var target = row !== undefined
8355
- ? row
8356
- : settings.bSortCellsTop // legacy support
8357
- ? 0
8358
- : header.length - 1;
8359
-
8360
- return header[target][column].cell;
8383
+ return this.iterator( 'column', function (settings, column) {
8384
+ return __column_header(settings, column, row);
8361
8385
  }, 1 );
8362
8386
  } );
8363
8387
 
@@ -9510,7 +9534,7 @@ _api_register( 'i18n()', function ( token, def, plural ) {
9510
9534
  * @type string
9511
9535
  * @default Version number
9512
9536
  */
9513
- DataTable.version = "2.0.3";
9537
+ DataTable.version = "2.0.5";
9514
9538
 
9515
9539
  /**
9516
9540
  * Private data store, containing all of the settings objects that are
@@ -10365,24 +10389,24 @@ DataTable.defaults = {
10365
10389
  */
10366
10390
  "oPaginate": {
10367
10391
  /**
10368
- * Label and character for first page button
10392
+ * Label and character for first page button («)
10369
10393
  */
10370
- "sFirst": "«",
10394
+ "sFirst": "\u00AB",
10371
10395
 
10372
10396
  /**
10373
- * Last page button
10397
+ * Last page button (»)
10374
10398
  */
10375
- "sLast": "»",
10399
+ "sLast": "\u00BB",
10376
10400
 
10377
10401
  /**
10378
- * Next page button
10402
+ * Next page button (›)
10379
10403
  */
10380
- "sNext": "",
10404
+ "sNext": "\u203A",
10381
10405
 
10382
10406
  /**
10383
- * Previous page button
10407
+ * Previous page button (‹)
10384
10408
  */
10385
- "sPrevious": "",
10409
+ "sPrevious": "\u2039",
10386
10410
  },
10387
10411
 
10388
10412
  /**
@@ -11611,657 +11635,95 @@ DataTable.models.oSettings = {
11611
11635
  */
11612
11636
 
11613
11637
 
11614
- /**
11615
- * DataTables extensions
11616
- *
11617
- * This namespace acts as a collection area for plug-ins that can be used to
11618
- * extend DataTables capabilities. Indeed many of the build in methods
11619
- * use this method to provide their own capabilities (sorting methods for
11620
- * example).
11621
- *
11622
- * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
11623
- * reasons
11624
- *
11625
- * @namespace
11626
- */
11627
- DataTable.ext = _ext = {
11628
- /**
11629
- * Buttons. For use with the Buttons extension for DataTables. This is
11630
- * defined here so other extensions can define buttons regardless of load
11631
- * order. It is _not_ used by DataTables core.
11632
- *
11633
- * @type object
11634
- * @default {}
11635
- */
11636
- buttons: {},
11638
+ var extPagination = DataTable.ext.pager;
11637
11639
 
11640
+ // Paging buttons configuration
11641
+ $.extend( extPagination, {
11642
+ simple: function () {
11643
+ return [ 'previous', 'next' ];
11644
+ },
11638
11645
 
11639
- /**
11640
- * Element class names
11641
- *
11642
- * @type object
11643
- * @default {}
11644
- */
11645
- classes: {},
11646
+ full: function () {
11647
+ return [ 'first', 'previous', 'next', 'last' ];
11648
+ },
11646
11649
 
11650
+ numbers: function () {
11651
+ return [ 'numbers' ];
11652
+ },
11647
11653
 
11648
- /**
11649
- * DataTables build type (expanded by the download builder)
11650
- *
11651
- * @type string
11652
- */
11653
- builder: "-source-",
11654
+ simple_numbers: function () {
11655
+ return [ 'previous', 'numbers', 'next' ];
11656
+ },
11654
11657
 
11658
+ full_numbers: function () {
11659
+ return [ 'first', 'previous', 'numbers', 'next', 'last' ];
11660
+ },
11661
+
11662
+ first_last: function () {
11663
+ return ['first', 'last'];
11664
+ },
11665
+
11666
+ first_last_numbers: function () {
11667
+ return ['first', 'numbers', 'last'];
11668
+ },
11655
11669
 
11656
- /**
11657
- * Error reporting.
11658
- *
11659
- * How should DataTables report an error. Can take the value 'alert',
11660
- * 'throw', 'none' or a function.
11661
- *
11662
- * @type string|function
11663
- * @default alert
11664
- */
11665
- errMode: "alert",
11670
+ // For testing and plug-ins to use
11671
+ _numbers: _pagingNumbers,
11666
11672
 
11673
+ // Number of number buttons - legacy, use `numbers` option for paging feature
11674
+ numbers_length: 7
11675
+ } );
11667
11676
 
11668
- /**
11669
- * Legacy so v1 plug-ins don't throw js errors on load
11670
- */
11671
- feature: [],
11672
11677
 
11673
- /**
11674
- * Feature plug-ins.
11675
- *
11676
- * This is an object of callbacks which provide the features for DataTables
11677
- * to be initialised via the `layout` option.
11678
- */
11679
- features: {},
11678
+ $.extend( true, DataTable.ext.renderer, {
11679
+ pagingButton: {
11680
+ _: function (settings, buttonType, content, active, disabled) {
11681
+ var classes = settings.oClasses.paging;
11682
+ var btnClasses = [classes.button];
11683
+ var btn;
11680
11684
 
11685
+ if (active) {
11686
+ btnClasses.push(classes.active);
11687
+ }
11681
11688
 
11682
- /**
11683
- * Row searching.
11684
- *
11685
- * This method of searching is complimentary to the default type based
11686
- * searching, and a lot more comprehensive as it allows you complete control
11687
- * over the searching logic. Each element in this array is a function
11688
- * (parameters described below) that is called for every row in the table,
11689
- * and your logic decides if it should be included in the searching data set
11690
- * or not.
11691
- *
11692
- * Searching functions have the following input parameters:
11693
- *
11694
- * 1. `{object}` DataTables settings object: see
11695
- * {@link DataTable.models.oSettings}
11696
- * 2. `{array|object}` Data for the row to be processed (same as the
11697
- * original format that was passed in as the data source, or an array
11698
- * from a DOM data source
11699
- * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
11700
- * can be useful to retrieve the `TR` element if you need DOM interaction.
11701
- *
11702
- * And the following return is expected:
11703
- *
11704
- * * {boolean} Include the row in the searched result set (true) or not
11705
- * (false)
11706
- *
11707
- * Note that as with the main search ability in DataTables, technically this
11708
- * is "filtering", since it is subtractive. However, for consistency in
11709
- * naming we call it searching here.
11710
- *
11711
- * @type array
11712
- * @default []
11713
- *
11714
- * @example
11715
- * // The following example shows custom search being applied to the
11716
- * // fourth column (i.e. the data[3] index) based on two input values
11717
- * // from the end-user, matching the data in a certain range.
11718
- * $.fn.dataTable.ext.search.push(
11719
- * function( settings, data, dataIndex ) {
11720
- * var min = document.getElementById('min').value * 1;
11721
- * var max = document.getElementById('max').value * 1;
11722
- * var version = data[3] == "-" ? 0 : data[3]*1;
11723
- *
11724
- * if ( min == "" && max == "" ) {
11725
- * return true;
11726
- * }
11727
- * else if ( min == "" && version < max ) {
11728
- * return true;
11729
- * }
11730
- * else if ( min < version && "" == max ) {
11731
- * return true;
11732
- * }
11733
- * else if ( min < version && version < max ) {
11734
- * return true;
11735
- * }
11736
- * return false;
11737
- * }
11738
- * );
11739
- */
11740
- search: [],
11689
+ if (disabled) {
11690
+ btnClasses.push(classes.disabled)
11691
+ }
11741
11692
 
11693
+ if (buttonType === 'ellipsis') {
11694
+ btn = $('<span class="ellipsis"></span>').html(content)[0];
11695
+ }
11696
+ else {
11697
+ btn = $('<button>', {
11698
+ class: btnClasses.join(' '),
11699
+ role: 'link',
11700
+ type: 'button'
11701
+ }).html(content);
11702
+ }
11742
11703
 
11743
- /**
11744
- * Selector extensions
11745
- *
11746
- * The `selector` option can be used to extend the options available for the
11747
- * selector modifier options (`selector-modifier` object data type) that
11748
- * each of the three built in selector types offer (row, column and cell +
11749
- * their plural counterparts). For example the Select extension uses this
11750
- * mechanism to provide an option to select only rows, columns and cells
11751
- * that have been marked as selected by the end user (`{selected: true}`),
11752
- * which can be used in conjunction with the existing built in selector
11753
- * options.
11754
- *
11755
- * Each property is an array to which functions can be pushed. The functions
11756
- * take three attributes:
11757
- *
11758
- * * Settings object for the host table
11759
- * * Options object (`selector-modifier` object type)
11760
- * * Array of selected item indexes
11761
- *
11762
- * The return is an array of the resulting item indexes after the custom
11763
- * selector has been applied.
11764
- *
11765
- * @type object
11766
- */
11767
- selector: {
11768
- cell: [],
11769
- column: [],
11770
- row: []
11704
+ return {
11705
+ display: btn,
11706
+ clicker: btn
11707
+ }
11708
+ }
11771
11709
  },
11772
11710
 
11711
+ pagingContainer: {
11712
+ _: function (settings, buttons) {
11713
+ // No wrapping element - just append directly to the host
11714
+ return buttons;
11715
+ }
11716
+ }
11717
+ } );
11773
11718
 
11774
- /**
11775
- * Legacy configuration options. Enable and disable legacy options that
11776
- * are available in DataTables.
11777
- *
11778
- * @type object
11779
- */
11780
- legacy: {
11781
- /**
11782
- * Enable / disable DataTables 1.9 compatible server-side processing
11783
- * requests
11784
- *
11785
- * @type boolean
11786
- * @default null
11787
- */
11788
- ajax: null
11789
- },
11719
+ // Common function to remove new lines, strip HTML and diacritic control
11720
+ var _filterString = function (stripHtml, normalize) {
11721
+ return function (str) {
11722
+ if (_empty(str) || typeof str !== 'string') {
11723
+ return str;
11724
+ }
11790
11725
 
11791
-
11792
- /**
11793
- * Pagination plug-in methods.
11794
- *
11795
- * Each entry in this object is a function and defines which buttons should
11796
- * be shown by the pagination rendering method that is used for the table:
11797
- * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
11798
- * buttons are displayed in the document, while the functions here tell it
11799
- * what buttons to display. This is done by returning an array of button
11800
- * descriptions (what each button will do).
11801
- *
11802
- * Pagination types (the four built in options and any additional plug-in
11803
- * options defined here) can be used through the `paginationType`
11804
- * initialisation parameter.
11805
- *
11806
- * The functions defined take two parameters:
11807
- *
11808
- * 1. `{int} page` The current page index
11809
- * 2. `{int} pages` The number of pages in the table
11810
- *
11811
- * Each function is expected to return an array where each element of the
11812
- * array can be one of:
11813
- *
11814
- * * `first` - Jump to first page when activated
11815
- * * `last` - Jump to last page when activated
11816
- * * `previous` - Show previous page when activated
11817
- * * `next` - Show next page when activated
11818
- * * `{int}` - Show page of the index given
11819
- * * `{array}` - A nested array containing the above elements to add a
11820
- * containing 'DIV' element (might be useful for styling).
11821
- *
11822
- * Note that DataTables v1.9- used this object slightly differently whereby
11823
- * an object with two functions would be defined for each plug-in. That
11824
- * ability is still supported by DataTables 1.10+ to provide backwards
11825
- * compatibility, but this option of use is now decremented and no longer
11826
- * documented in DataTables 1.10+.
11827
- *
11828
- * @type object
11829
- * @default {}
11830
- *
11831
- * @example
11832
- * // Show previous, next and current page buttons only
11833
- * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
11834
- * return [ 'previous', page, 'next' ];
11835
- * };
11836
- */
11837
- pager: {},
11838
-
11839
-
11840
- renderer: {
11841
- pageButton: {},
11842
- header: {}
11843
- },
11844
-
11845
-
11846
- /**
11847
- * Ordering plug-ins - custom data source
11848
- *
11849
- * The extension options for ordering of data available here is complimentary
11850
- * to the default type based ordering that DataTables typically uses. It
11851
- * allows much greater control over the the data that is being used to
11852
- * order a column, but is necessarily therefore more complex.
11853
- *
11854
- * This type of ordering is useful if you want to do ordering based on data
11855
- * live from the DOM (for example the contents of an 'input' element) rather
11856
- * than just the static string that DataTables knows of.
11857
- *
11858
- * The way these plug-ins work is that you create an array of the values you
11859
- * wish to be ordering for the column in question and then return that
11860
- * array. The data in the array much be in the index order of the rows in
11861
- * the table (not the currently ordering order!). Which order data gathering
11862
- * function is run here depends on the `dt-init columns.orderDataType`
11863
- * parameter that is used for the column (if any).
11864
- *
11865
- * The functions defined take two parameters:
11866
- *
11867
- * 1. `{object}` DataTables settings object: see
11868
- * {@link DataTable.models.oSettings}
11869
- * 2. `{int}` Target column index
11870
- *
11871
- * Each function is expected to return an array:
11872
- *
11873
- * * `{array}` Data for the column to be ordering upon
11874
- *
11875
- * @type array
11876
- *
11877
- * @example
11878
- * // Ordering using `input` node values
11879
- * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
11880
- * {
11881
- * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
11882
- * return $('input', td).val();
11883
- * } );
11884
- * }
11885
- */
11886
- order: {},
11887
-
11888
-
11889
- /**
11890
- * Type based plug-ins.
11891
- *
11892
- * Each column in DataTables has a type assigned to it, either by automatic
11893
- * detection or by direct assignment using the `type` option for the column.
11894
- * The type of a column will effect how it is ordering and search (plug-ins
11895
- * can also make use of the column type if required).
11896
- *
11897
- * @namespace
11898
- */
11899
- type: {
11900
- /**
11901
- * Automatic column class assignment
11902
- */
11903
- className: {},
11904
-
11905
- /**
11906
- * Type detection functions.
11907
- *
11908
- * The functions defined in this object are used to automatically detect
11909
- * a column's type, making initialisation of DataTables super easy, even
11910
- * when complex data is in the table.
11911
- *
11912
- * The functions defined take two parameters:
11913
- *
11914
- * 1. `{*}` Data from the column cell to be analysed
11915
- * 2. `{settings}` DataTables settings object. This can be used to
11916
- * perform context specific type detection - for example detection
11917
- * based on language settings such as using a comma for a decimal
11918
- * place. Generally speaking the options from the settings will not
11919
- * be required
11920
- *
11921
- * Each function is expected to return:
11922
- *
11923
- * * `{string|null}` Data type detected, or null if unknown (and thus
11924
- * pass it on to the other type detection functions.
11925
- *
11926
- * @type array
11927
- *
11928
- * @example
11929
- * // Currency type detection plug-in:
11930
- * $.fn.dataTable.ext.type.detect.push(
11931
- * function ( data, settings ) {
11932
- * // Check the numeric part
11933
- * if ( ! data.substring(1).match(/[0-9]/) ) {
11934
- * return null;
11935
- * }
11936
- *
11937
- * // Check prefixed by currency
11938
- * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
11939
- * return 'currency';
11940
- * }
11941
- * return null;
11942
- * }
11943
- * );
11944
- */
11945
- detect: [],
11946
-
11947
- /**
11948
- * Automatic renderer assignment
11949
- */
11950
- render: {},
11951
-
11952
-
11953
- /**
11954
- * Type based search formatting.
11955
- *
11956
- * The type based searching functions can be used to pre-format the
11957
- * data to be search on. For example, it can be used to strip HTML
11958
- * tags or to de-format telephone numbers for numeric only searching.
11959
- *
11960
- * Note that is a search is not defined for a column of a given type,
11961
- * no search formatting will be performed.
11962
- *
11963
- * Pre-processing of searching data plug-ins - When you assign the sType
11964
- * for a column (or have it automatically detected for you by DataTables
11965
- * or a type detection plug-in), you will typically be using this for
11966
- * custom sorting, but it can also be used to provide custom searching
11967
- * by allowing you to pre-processing the data and returning the data in
11968
- * the format that should be searched upon. This is done by adding
11969
- * functions this object with a parameter name which matches the sType
11970
- * for that target column. This is the corollary of <i>afnSortData</i>
11971
- * for searching data.
11972
- *
11973
- * The functions defined take a single parameter:
11974
- *
11975
- * 1. `{*}` Data from the column cell to be prepared for searching
11976
- *
11977
- * Each function is expected to return:
11978
- *
11979
- * * `{string|null}` Formatted string that will be used for the searching.
11980
- *
11981
- * @type object
11982
- * @default {}
11983
- *
11984
- * @example
11985
- * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
11986
- * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
11987
- * }
11988
- */
11989
- search: {},
11990
-
11991
-
11992
- /**
11993
- * Type based ordering.
11994
- *
11995
- * The column type tells DataTables what ordering to apply to the table
11996
- * when a column is sorted upon. The order for each type that is defined,
11997
- * is defined by the functions available in this object.
11998
- *
11999
- * Each ordering option can be described by three properties added to
12000
- * this object:
12001
- *
12002
- * * `{type}-pre` - Pre-formatting function
12003
- * * `{type}-asc` - Ascending order function
12004
- * * `{type}-desc` - Descending order function
12005
- *
12006
- * All three can be used together, only `{type}-pre` or only
12007
- * `{type}-asc` and `{type}-desc` together. It is generally recommended
12008
- * that only `{type}-pre` is used, as this provides the optimal
12009
- * implementation in terms of speed, although the others are provided
12010
- * for compatibility with existing Javascript sort functions.
12011
- *
12012
- * `{type}-pre`: Functions defined take a single parameter:
12013
- *
12014
- * 1. `{*}` Data from the column cell to be prepared for ordering
12015
- *
12016
- * And return:
12017
- *
12018
- * * `{*}` Data to be sorted upon
12019
- *
12020
- * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
12021
- * functions, taking two parameters:
12022
- *
12023
- * 1. `{*}` Data to compare to the second parameter
12024
- * 2. `{*}` Data to compare to the first parameter
12025
- *
12026
- * And returning:
12027
- *
12028
- * * `{*}` Ordering match: <0 if first parameter should be sorted lower
12029
- * than the second parameter, ===0 if the two parameters are equal and
12030
- * >0 if the first parameter should be sorted height than the second
12031
- * parameter.
12032
- *
12033
- * @type object
12034
- * @default {}
12035
- *
12036
- * @example
12037
- * // Numeric ordering of formatted numbers with a pre-formatter
12038
- * $.extend( $.fn.dataTable.ext.type.order, {
12039
- * "string-pre": function(x) {
12040
- * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
12041
- * return parseFloat( a );
12042
- * }
12043
- * } );
12044
- *
12045
- * @example
12046
- * // Case-sensitive string ordering, with no pre-formatting method
12047
- * $.extend( $.fn.dataTable.ext.order, {
12048
- * "string-case-asc": function(x,y) {
12049
- * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
12050
- * },
12051
- * "string-case-desc": function(x,y) {
12052
- * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
12053
- * }
12054
- * } );
12055
- */
12056
- order: {}
12057
- },
12058
-
12059
- /**
12060
- * Unique DataTables instance counter
12061
- *
12062
- * @type int
12063
- * @private
12064
- */
12065
- _unique: 0,
12066
-
12067
-
12068
- //
12069
- // Depreciated
12070
- // The following properties are retained for backwards compatibility only.
12071
- // The should not be used in new projects and will be removed in a future
12072
- // version
12073
- //
12074
-
12075
- /**
12076
- * Version check function.
12077
- * @type function
12078
- * @depreciated Since 1.10
12079
- */
12080
- fnVersionCheck: DataTable.fnVersionCheck,
12081
-
12082
-
12083
- /**
12084
- * Index for what 'this' index API functions should use
12085
- * @type int
12086
- * @deprecated Since v1.10
12087
- */
12088
- iApiIndex: 0,
12089
-
12090
-
12091
- /**
12092
- * Software version
12093
- * @type string
12094
- * @deprecated Since v1.10
12095
- */
12096
- sVersion: DataTable.version
12097
- };
12098
-
12099
-
12100
- //
12101
- // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
12102
- //
12103
- $.extend( _ext, {
12104
- afnFiltering: _ext.search,
12105
- aTypes: _ext.type.detect,
12106
- ofnSearch: _ext.type.search,
12107
- oSort: _ext.type.order,
12108
- afnSortData: _ext.order,
12109
- aoFeatures: _ext.feature,
12110
- oStdClasses: _ext.classes,
12111
- oPagination: _ext.pager
12112
- } );
12113
-
12114
-
12115
- $.extend( DataTable.ext.classes, {
12116
- container: 'dt-container',
12117
- empty: {
12118
- row: 'dt-empty'
12119
- },
12120
- info: {
12121
- container: 'dt-info'
12122
- },
12123
- length: {
12124
- container: 'dt-length',
12125
- select: 'dt-input'
12126
- },
12127
- order: {
12128
- canAsc: 'dt-orderable-asc',
12129
- canDesc: 'dt-orderable-desc',
12130
- isAsc: 'dt-ordering-asc',
12131
- isDesc: 'dt-ordering-desc',
12132
- none: 'dt-orderable-none',
12133
- position: 'sorting_'
12134
- },
12135
- processing: {
12136
- container: 'dt-processing'
12137
- },
12138
- scrolling: {
12139
- body: 'dt-scroll-body',
12140
- container: 'dt-scroll',
12141
- footer: {
12142
- self: 'dt-scroll-foot',
12143
- inner: 'dt-scroll-footInner'
12144
- },
12145
- header: {
12146
- self: 'dt-scroll-head',
12147
- inner: 'dt-scroll-headInner'
12148
- }
12149
- },
12150
- search: {
12151
- container: 'dt-search',
12152
- input: 'dt-input'
12153
- },
12154
- table: 'dataTable',
12155
- tbody: {
12156
- cell: '',
12157
- row: ''
12158
- },
12159
- thead: {
12160
- cell: '',
12161
- row: ''
12162
- },
12163
- tfoot: {
12164
- cell: '',
12165
- row: ''
12166
- },
12167
- paging: {
12168
- active: 'current',
12169
- button: 'dt-paging-button',
12170
- container: 'dt-paging',
12171
- disabled: 'disabled'
12172
- }
12173
- } );
12174
-
12175
-
12176
- var extPagination = DataTable.ext.pager;
12177
-
12178
- // Paging buttons configuration
12179
- $.extend( extPagination, {
12180
- simple: function () {
12181
- return [ 'previous', 'next' ];
12182
- },
12183
-
12184
- full: function () {
12185
- return [ 'first', 'previous', 'next', 'last' ];
12186
- },
12187
-
12188
- numbers: function () {
12189
- return [ 'numbers' ];
12190
- },
12191
-
12192
- simple_numbers: function () {
12193
- return [ 'previous', 'numbers', 'next' ];
12194
- },
12195
-
12196
- full_numbers: function () {
12197
- return [ 'first', 'previous', 'numbers', 'next', 'last' ];
12198
- },
12199
-
12200
- first_last: function () {
12201
- return ['first', 'last'];
12202
- },
12203
-
12204
- first_last_numbers: function () {
12205
- return ['first', 'numbers', 'last'];
12206
- },
12207
-
12208
- // For testing and plug-ins to use
12209
- _numbers: _pagingNumbers,
12210
-
12211
- // Number of number buttons - legacy, use `numbers` option for paging feature
12212
- numbers_length: 7
12213
- } );
12214
-
12215
-
12216
- $.extend( true, DataTable.ext.renderer, {
12217
- pagingButton: {
12218
- _: function (settings, buttonType, content, active, disabled) {
12219
- var classes = settings.oClasses.paging;
12220
- var btnClasses = [classes.button];
12221
- var btn;
12222
-
12223
- if (active) {
12224
- btnClasses.push(classes.active);
12225
- }
12226
-
12227
- if (disabled) {
12228
- btnClasses.push(classes.disabled)
12229
- }
12230
-
12231
- if (buttonType === 'ellipsis') {
12232
- btn = $('<span class="ellipsis"></span>').html(content)[0];
12233
- }
12234
- else {
12235
- btn = $('<button>', {
12236
- class: btnClasses.join(' '),
12237
- role: 'link',
12238
- type: 'button'
12239
- }).html(content);
12240
- }
12241
-
12242
- return {
12243
- display: btn,
12244
- clicker: btn
12245
- }
12246
- }
12247
- },
12248
-
12249
- pagingContainer: {
12250
- _: function (settings, buttons) {
12251
- // No wrapping element - just append directly to the host
12252
- return buttons;
12253
- }
12254
- }
12255
- } );
12256
-
12257
- // Common function to remove new lines, strip HTML and diacritic control
12258
- var _filterString = function (stripHtml, normalize) {
12259
- return function (str) {
12260
- if (_empty(str) || typeof str !== 'string') {
12261
- return str;
12262
- }
12263
-
12264
- str = str.replace( _re_new_lines, " " );
11726
+ str = str.replace( _re_new_lines, " " );
12265
11727
 
12266
11728
  if (stripHtml) {
12267
11729
  str = _stripHtml(str);
@@ -13036,7 +12498,7 @@ DataTable.feature.register( 'info', function ( settings, opts ) {
13036
12498
  });
13037
12499
 
13038
12500
  // For the first info display in the table, we add a callback and aria information.
13039
- if (! $('#' + tid+'_info', settings.nWrapper).length) {
12501
+ if (! settings._infoEl) {
13040
12502
  n.attr({
13041
12503
  'aria-live': 'polite',
13042
12504
  id: tid+'_info',
@@ -13045,6 +12507,8 @@ DataTable.feature.register( 'info', function ( settings, opts ) {
13045
12507
 
13046
12508
  // Table is described by our info div
13047
12509
  $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
12510
+
12511
+ settings._infoEl = n;
13048
12512
  }
13049
12513
 
13050
12514
  return n;
@@ -13202,7 +12666,7 @@ DataTable.feature.register( 'search', function ( settings, opts ) {
13202
12666
 
13203
12667
  // opts
13204
12668
  // - type - button configuration
13205
- // - numbers - number of buttons to show - must be odd
12669
+ // - buttons - number of buttons to show - must be odd
13206
12670
  DataTable.feature.register( 'paging', function ( settings, opts ) {
13207
12671
  // Don't show the paging input if the table doesn't have paging enabled
13208
12672
  if (! settings.oFeatures.bPaginate) {
@@ -13210,9 +12674,15 @@ DataTable.feature.register( 'paging', function ( settings, opts ) {
13210
12674
  }
13211
12675
 
13212
12676
  opts = $.extend({
13213
- numbers: DataTable.ext.pager.numbers_length,
13214
- type: settings.sPaginationType
13215
- }, opts)
12677
+ buttons: DataTable.ext.pager.numbers_length,
12678
+ type: settings.sPaginationType,
12679
+ boundaryNumbers: true
12680
+ }, opts);
12681
+
12682
+ // To be removed in 2.1
12683
+ if (opts.numbers) {
12684
+ opts.buttons = opts.numbers;
12685
+ }
13216
12686
 
13217
12687
  var host = $('<div/>').addClass( settings.oClasses.paging.container + ' paging_' + opts.type );
13218
12688
  var draw = function () {
@@ -13244,7 +12714,7 @@ function _pagingDraw(settings, host, opts) {
13244
12714
  buttons = plugin()
13245
12715
  .map(function (val) {
13246
12716
  return val === 'numbers'
13247
- ? _pagingNumbers(page, pages, opts.numbers)
12717
+ ? _pagingNumbers(page, pages, opts.buttons, opts.boundaryNumbers)
13248
12718
  : val;
13249
12719
  })
13250
12720
  .flat();
@@ -13386,12 +12856,15 @@ function _pagingButtonInfo(settings, button, page, pages) {
13386
12856
  * @param {*} page Current page
13387
12857
  * @param {*} pages Total number of pages
13388
12858
  * @param {*} buttons Target number of number buttons
12859
+ * @param {boolean} addFirstLast Indicate if page 1 and end should be included
13389
12860
  * @returns Buttons to show
13390
12861
  */
13391
- function _pagingNumbers ( page, pages, buttons ) {
12862
+ function _pagingNumbers ( page, pages, buttons, addFirstLast ) {
13392
12863
  var
13393
12864
  numbers = [],
13394
- half = Math.floor(buttons / 2);
12865
+ half = Math.floor(buttons / 2),
12866
+ before = addFirstLast ? 2 : 1,
12867
+ after = addFirstLast ? 1 : 0;
13395
12868
 
13396
12869
  if ( pages <= buttons ) {
13397
12870
  numbers = _range(0, pages);
@@ -13414,17 +12887,30 @@ function _pagingNumbers ( page, pages, buttons ) {
13414
12887
  }
13415
12888
  }
13416
12889
  else if ( page <= half ) {
13417
- numbers = _range(0, buttons-2);
13418
- numbers.push('ellipsis', pages-1);
12890
+ numbers = _range(0, buttons-before);
12891
+ numbers.push('ellipsis');
12892
+
12893
+ if (addFirstLast) {
12894
+ numbers.push(pages-1);
12895
+ }
13419
12896
  }
13420
12897
  else if ( page >= pages - 1 - half ) {
13421
- numbers = _range(pages-(buttons-2), pages);
13422
- numbers.unshift(0, 'ellipsis');
12898
+ numbers = _range(pages-(buttons-before), pages);
12899
+ numbers.unshift('ellipsis');
12900
+
12901
+ if (addFirstLast) {
12902
+ numbers.unshift(0);
12903
+ }
13423
12904
  }
13424
12905
  else {
13425
- numbers = _range(page-half+2, page+half-1);
13426
- numbers.push('ellipsis', pages-1);
13427
- numbers.unshift(0, 'ellipsis');
12906
+ numbers = _range(page-half+before, page+half-after);
12907
+ numbers.push('ellipsis');
12908
+ numbers.unshift('ellipsis');
12909
+
12910
+ if (addFirstLast) {
12911
+ numbers.push(pages-1);
12912
+ numbers.unshift(0);
12913
+ }
13428
12914
  }
13429
12915
 
13430
12916
  return numbers;