datatables.net 3.0.0-beta.1 → 3.0.0-beta.2

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 3.0.0-beta.1
1
+ /*! DataTables 3.0.0-beta.2
2
2
  * Copyright (c) SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -46,9 +46,11 @@ const reRegexCharacters = new RegExp('(\\' +
46
46
  // implementations differ between browsers.
47
47
  const reDate = /^\d{2,4}[./-]\d{1,2}[./-]\d{1,2}([T ]{1}\d{1,2}[:.]\d{2}([.:]\d{2})?)?$/;
48
48
  const reNewLines = /[\r\n\u2028]/g;
49
+ const isoTimezone = /[T\s]\d{2}.*?(Z|[+-]\d{2}(?::?\d{2})?)$/;
49
50
 
50
51
  var regex = /*#__PURE__*/Object.freeze({
51
52
  __proto__: null,
53
+ isoTimezone: isoTimezone,
52
54
  reDate: reDate,
53
55
  reFormattedNumeric: reFormattedNumeric,
54
56
  reHtml: reHtml,
@@ -520,6 +522,13 @@ function ajax(optionsIn) {
520
522
  if (options.contentType && !(options.data instanceof FormData)) {
521
523
  xhr.setRequestHeader('Content-Type', options.contentType);
522
524
  }
525
+ // Add a X-Request-With header, as jQuery does so and some server-side
526
+ // platforms look for it. Only for same domain though.
527
+ if (options.headers &&
528
+ !options.headers['X-Requested-With'] &&
529
+ !isCrossDomain(options.url)) {
530
+ options.headers['X-Requested-With'] = 'XMLHttpRequest';
531
+ }
523
532
  each(options.headers, (key, val) => {
524
533
  xhr.setRequestHeader(key, val);
525
534
  });
@@ -617,6 +626,17 @@ function convertSpaces(sendData, options) {
617
626
  ? sendData.replace(/%20/g, '+')
618
627
  : sendData;
619
628
  }
629
+ /**
630
+ * Determine if a url is a cross domain request or not
631
+ *
632
+ * @param url URL to check
633
+ * @returns True if cross domain, false otherwise
634
+ */
635
+ function isCrossDomain(url) {
636
+ // Use the current page as the base to handle relative URLs correctly
637
+ const target = new URL(url, window.location.origin);
638
+ return target.origin !== window.location.origin;
639
+ }
620
640
  /**
621
641
  * Get the HTTP method from the Ajax request options
622
642
  *
@@ -1872,8 +1892,7 @@ class Dom {
1872
1892
  }
1873
1893
  }
1874
1894
  if (sort) {
1875
- Array.prototype.sort.call(this, documentOrder);
1876
- // this.sort(documentOrder);
1895
+ this.sort();
1877
1896
  }
1878
1897
  return this;
1879
1898
  }
@@ -2664,6 +2683,18 @@ class Dom {
2664
2683
  el.style.display = 'block';
2665
2684
  });
2666
2685
  }
2686
+ /**
2687
+ * Sort the DOM elements into document order.
2688
+ *
2689
+ * This is normally not needed as elements selected with a DOM selector are
2690
+ * automatically sorted in document order. However, in the case of elements
2691
+ * being added as an array, their order will be retained. In such as case
2692
+ * you might wish to sort them in document order.
2693
+ */
2694
+ sort() {
2695
+ Array.prototype.sort.call(this, documentOrder);
2696
+ return this;
2697
+ }
2667
2698
  text(txt) {
2668
2699
  if (txt === undefined) {
2669
2700
  return this.count() ? this[0].textContent : null;
@@ -3824,7 +3855,7 @@ const ext = {
3824
3855
  * Software version
3825
3856
  * @type string
3826
3857
  */
3827
- version: '3.0.0-beta.1'
3858
+ version: '3.0.0-beta.2'
3828
3859
  };
3829
3860
  //
3830
3861
  // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
@@ -4117,7 +4148,7 @@ function __mldObj(d, format, locale) {
4117
4148
  var dt;
4118
4149
  resolveWindowLibs();
4119
4150
  if (__moment) {
4120
- dt = __moment.utc(d, format, locale, true);
4151
+ dt = __moment(d, format, locale, true);
4121
4152
  if (!dt.isValid()) {
4122
4153
  return null;
4123
4154
  }
@@ -4220,6 +4251,15 @@ function __mlHelper(localeString) {
4220
4251
  !(d instanceof Date)) {
4221
4252
  return d;
4222
4253
  }
4254
+ // Determine if there is a timezone. If there is, we want to reuse
4255
+ // it for the output, so the timezone doesn't change between the
4256
+ // input and output.
4257
+ let options = {};
4258
+ let tzMatch = typeof d === 'string' ? d.match(util.regex.isoTimezone) : null;
4259
+ if (tzMatch) {
4260
+ options.timeZone = tzMatch[1] === 'Z' ? 'UTC' : tzMatch[1];
4261
+ }
4262
+ // Get a Date object (Luxon, moment or Date)
4223
4263
  var dt = __mldObj(d, from, locale);
4224
4264
  if (dt === null) {
4225
4265
  return d;
@@ -4228,7 +4268,7 @@ function __mlHelper(localeString) {
4228
4268
  return dt;
4229
4269
  }
4230
4270
  var formatted = to === null
4231
- ? __mld(dt, 'toDate', 'toJSDate', '')[localeString](navigator.language, { timeZone: 'UTC' })
4271
+ ? __mld(dt, 'toDate', 'toJSDate', '')[localeString](navigator.language, options)
4232
4272
  : __mld(dt, 'format', 'toFormat', 'toISOString', to);
4233
4273
  // XSS protection
4234
4274
  return type === 'display' ? util.escapeHtml(formatted) : formatted;
@@ -5384,8 +5424,8 @@ function featureTable(settings) {
5384
5424
  let captionSide = caption
5385
5425
  ? caption._captionSide
5386
5426
  : null;
5387
- let headerClone = table.clone(false);
5388
- let footerClone = table.clone(false);
5427
+ let tableCloneHeader = table.clone(false);
5428
+ let tableCloneFooter = table.clone(false);
5389
5429
  let footer = table.children('tfoot');
5390
5430
  let size = function (s) {
5391
5431
  return !s ? '100%' : stringToCss(s);
@@ -5406,11 +5446,10 @@ function featureTable(settings) {
5406
5446
  * table - scroll foot table
5407
5447
  * tfoot - tfoot
5408
5448
  */
5409
- let scroller = Dom
5410
- .c('div')
5449
+ let scroller = Dom.c('div')
5411
5450
  .classAdd(classes.container)
5412
- .append(Dom
5413
- .c('div')
5451
+ .attr('role', 'table')
5452
+ .append(Dom.c('div')
5414
5453
  .classAdd(classes.header.self)
5415
5454
  .css({
5416
5455
  overflow: 'hidden',
@@ -5418,40 +5457,41 @@ function featureTable(settings) {
5418
5457
  border: '0',
5419
5458
  width: scrollX ? size(scrollX) : '100%'
5420
5459
  })
5421
- .append(Dom
5422
- .c('div')
5460
+ .attr('role', 'none')
5461
+ .append(Dom.c('div')
5423
5462
  .classAdd(classes.header.inner)
5424
5463
  .css({
5425
5464
  'box-sizing': 'content-box',
5426
5465
  width: scroll.xInner || '100%'
5427
5466
  })
5428
- .append(headerClone
5467
+ .attr('role', 'none')
5468
+ .append(tableCloneHeader
5429
5469
  .attrRemove('id')
5430
5470
  .css('margin-left', '0')
5431
5471
  .append(captionSide === 'top' ? caption : null)
5432
5472
  .append(table.children('thead')))))
5433
- .append(Dom
5434
- .c('div')
5473
+ .append(Dom.c('div')
5435
5474
  .classAdd(classes.body)
5436
5475
  .css({
5437
5476
  position: 'relative',
5438
5477
  overflow: 'auto',
5439
5478
  width: size(scrollX)
5440
5479
  })
5480
+ .attr('role', 'none')
5441
5481
  .append(table));
5442
5482
  if (footer.count()) {
5443
- scroller.append(Dom
5444
- .c('div')
5483
+ scroller.append(Dom.c('div')
5445
5484
  .classAdd(classes.footer.self)
5446
5485
  .css({
5447
5486
  overflow: 'hidden',
5448
5487
  border: '0',
5449
5488
  width: scrollX ? size(scrollX) : '100%'
5450
5489
  })
5451
- .append(Dom
5452
- .c('div')
5490
+ .attr('role', 'none')
5491
+ .append(Dom.c('div')
5453
5492
  .classAdd(classes.footer.inner)
5454
- .append(footerClone
5493
+ .attr('role', 'none')
5494
+ .append(tableCloneFooter
5455
5495
  .attrRemove('id')
5456
5496
  .css('margin-left', '0')
5457
5497
  .append(captionSide === 'bottom' ? caption : null)
@@ -5489,6 +5529,22 @@ function featureTable(settings) {
5489
5529
  settings.scrollFoot = scrollFoot;
5490
5530
  // On redraw - align columns
5491
5531
  settings.callbacks.draw.push(scrollDraw);
5532
+ // Aria roles - because we break the table up into parts we need to be very
5533
+ // explicit with the roles to create the accessability tree for the table,
5534
+ // otherwise browser's attempt to "fix" the tree by filling in what it
5535
+ // thinks are gaps. The static elements that we can assign roles to are done
5536
+ // here. Dynamic ones are done in the draw function below.
5537
+ table.attr('role', 'none');
5538
+ table.find('tbody').attr('role', 'rowgroup');
5539
+ tableCloneHeader.attr('role', 'none');
5540
+ tableCloneFooter.attr('role', 'none');
5541
+ settings.colgroup.find('colgroup').attr('role', 'none');
5542
+ // Move the info feature's aria desc by to the new "table"
5543
+ let describedBy = table.attr('aria-describedby');
5544
+ if (describedBy) {
5545
+ scroller.attr('aria-describedby', describedBy);
5546
+ table.attrRemove('aria-describedby');
5547
+ }
5492
5548
  return scroller.get(0);
5493
5549
  }
5494
5550
  /**
@@ -5521,10 +5577,13 @@ function scrollDraw(settings) {
5521
5577
  else {
5522
5578
  settings.scrollBarVis = scrollBarVis;
5523
5579
  }
5580
+ header.find('thead').attr('role', 'rowgroup');
5581
+ footer.find('tfoot').attr('role', 'rowgroup');
5524
5582
  // 1. Re-create the table inside the scrolling div
5525
5583
  // Remove the old minimised thead and tfoot elements in the inner table
5526
5584
  table.children('thead, tfoot').remove();
5527
- // Clone the current header and footer elements and then place it into the inner table
5585
+ // Clone the current header and footer elements and then place it into the
5586
+ // inner table
5528
5587
  headerCopy = header.clone(true).prependTo(table);
5529
5588
  headerCopy.find('th, td').attrRemove('tabindex');
5530
5589
  headerCopy.find('[id]').attrRemove('id');
@@ -5559,8 +5618,7 @@ function scrollDraw(settings) {
5559
5618
  }
5560
5619
  }
5561
5620
  if (firstTr) {
5562
- let colSizes = Dom
5563
- .s(firstTr)
5621
+ let colSizes = Dom.s(firstTr)
5564
5622
  .children('th, td')
5565
5623
  .mapTo(function (cell, idx) {
5566
5624
  return {
@@ -5625,6 +5683,18 @@ function scrollDraw(settings) {
5625
5683
  }
5626
5684
  // Correct DOM ordering for colgroup - comes before the thead
5627
5685
  table.children('colgroup').prependTo(table);
5686
+ // Remove tabindex from the hidden row elements
5687
+ table.find('thead, tfoot').find('[tabindex]').attrRemove('tabindex');
5688
+ // Dynamic ARIA roles - see setup for details on why this is needed
5689
+ table
5690
+ .find('thead, tfoot')
5691
+ .attr('role', 'none')
5692
+ .find('[role]')
5693
+ .attrRemove('role');
5694
+ table.find('tbody tr:not([role])').attr('role', 'row');
5695
+ table.find('tbody td:not([role]), tbody th:not([role])').attr('role', 'cell');
5696
+ scrollAria(headerCopy);
5697
+ scrollAria(footerCopy);
5628
5698
  // Adjust the position of the header in case we loose the y-scrollbar
5629
5699
  divBody.trigger('scroll');
5630
5700
  // If sorting or filtering has occurred, jump the scrolling back to the top
@@ -5633,6 +5703,18 @@ function scrollDraw(settings) {
5633
5703
  divBodyEl.scrollTop(0);
5634
5704
  }
5635
5705
  }
5706
+ /**
5707
+ * Apply ARIA roles for the header / footer of a scrolling table
5708
+ * @param element
5709
+ */
5710
+ function scrollAria(element) {
5711
+ if (element) {
5712
+ element.find('tfoot:not([role])').attr('role', 'rowgroup');
5713
+ element.find('tr:not([role])').attr('role', 'row');
5714
+ element.find('th:not([role])').attr('role', 'columnheader');
5715
+ element.find('td:not([role])').attr('role', 'cell');
5716
+ }
5717
+ }
5636
5718
 
5637
5719
  /**
5638
5720
  * Add a column to the list used for the table with default values
@@ -8297,6 +8379,11 @@ function reDraw(settings, holdPosition, recompute) {
8297
8379
  if (holdPosition !== true) {
8298
8380
  settings.displayStart = 0;
8299
8381
  }
8382
+ else {
8383
+ // Keep position, but make sure that there is actually data to display,
8384
+ // otherwise we need to rewind a bit (e.g. if rows were deleted)
8385
+ lengthOverflow(settings);
8386
+ }
8300
8387
  // Let any modules know about the draw hold position state (used by
8301
8388
  // scrolling internally)
8302
8389
  settings.drawHold = holdPosition;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "js/dataTables.js",
5
5
  "module": "js/dataTables.mjs",
6
6
  "types": "./types/types.d.ts",
7
- "version": "3.0.0-beta.1",
7
+ "version": "3.0.0-beta.2",
8
8
  "files": [
9
9
  "js/**/*.js",
10
10
  "js/**/*.mjs",