oxidized-web 0.17.1 → 0.18.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.

Potentially problematic release.


This version of oxidized-web might be problematic. Click here for more details.

@@ -1,4 +1,4 @@
1
- /*! DataTables 2.3.2
1
+ /*! DataTables 2.3.5
2
2
  * © SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -166,6 +166,9 @@
166
166
  this.id = sId;
167
167
  }
168
168
 
169
+ // Replacing an existing colgroup with our own. Not ideal, but a merge could take a lot of code
170
+ $this.children('colgroup').remove();
171
+
169
172
  /* Create the settings object for this table and set some of the default parameters */
170
173
  var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
171
174
  "sDestroyWidth": $this[0].style.width,
@@ -731,7 +734,7 @@
731
734
  *
732
735
  * The extension options for ordering of data available here is complimentary
733
736
  * to the default type based ordering that DataTables typically uses. It
734
- * allows much greater control over the the data that is being used to
737
+ * allows much greater control over the data that is being used to
735
738
  * order a column, but is necessarily therefore more complex.
736
739
  *
737
740
  * This type of ordering is useful if you want to do ordering based on data
@@ -890,7 +893,7 @@
890
893
  * `{type}-asc` and `{type}-desc` together. It is generally recommended
891
894
  * that only `{type}-pre` is used, as this provides the optimal
892
895
  * implementation in terms of speed, although the others are provided
893
- * for compatibility with existing Javascript sort functions.
896
+ * for compatibility with existing JavaScript sort functions.
894
897
  *
895
898
  * `{type}-pre`: Functions defined take a single parameter:
896
899
  *
@@ -900,7 +903,7 @@
900
903
  *
901
904
  * * `{*}` Data to be sorted upon
902
905
  *
903
- * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
906
+ * `{type}-asc` and `{type}-desc`: Functions are typical JavaScript sort
904
907
  * functions, taking two parameters:
905
908
  *
906
909
  * 1. `{*}` Data to compare to the second parameter
@@ -1124,7 +1127,7 @@
1124
1127
  };
1125
1128
 
1126
1129
  // Convert from a formatted number with characters other than `.` as the
1127
- // decimal place, to a Javascript number
1130
+ // decimal place, to a JavaScript number
1128
1131
  var _numToDecimal = function ( num, decimalPoint ) {
1129
1132
  // Cache created regular expressions for speed as this function is called often
1130
1133
  if ( ! _re_dic[ decimalPoint ] ) {
@@ -1190,19 +1193,19 @@
1190
1193
 
1191
1194
  var _pluck = function ( a, prop, prop2 ) {
1192
1195
  var out = [];
1193
- var i=0, ien=a.length;
1196
+ var i=0, iLen=a.length;
1194
1197
 
1195
1198
  // Could have the test in the loop for slightly smaller code, but speed
1196
1199
  // is essential here
1197
1200
  if ( prop2 !== undefined ) {
1198
- for ( ; i<ien ; i++ ) {
1201
+ for ( ; i<iLen ; i++ ) {
1199
1202
  if ( a[i] && a[i][ prop ] ) {
1200
1203
  out.push( a[i][ prop ][ prop2 ] );
1201
1204
  }
1202
1205
  }
1203
1206
  }
1204
1207
  else {
1205
- for ( ; i<ien ; i++ ) {
1208
+ for ( ; i<iLen ; i++ ) {
1206
1209
  if ( a[i] ) {
1207
1210
  out.push( a[i][ prop ] );
1208
1211
  }
@@ -1218,19 +1221,19 @@
1218
1221
  var _pluck_order = function ( a, order, prop, prop2 )
1219
1222
  {
1220
1223
  var out = [];
1221
- var i=0, ien=order.length;
1224
+ var i=0, iLen=order.length;
1222
1225
 
1223
1226
  // Could have the test in the loop for slightly smaller code, but speed
1224
1227
  // is essential here
1225
1228
  if ( prop2 !== undefined ) {
1226
- for ( ; i<ien ; i++ ) {
1229
+ for ( ; i<iLen ; i++ ) {
1227
1230
  if ( a[ order[i] ] && a[ order[i] ][ prop ] ) {
1228
1231
  out.push( a[ order[i] ][ prop ][ prop2 ] );
1229
1232
  }
1230
1233
  }
1231
1234
  }
1232
1235
  else {
1233
- for ( ; i<ien ; i++ ) {
1236
+ for ( ; i<iLen ; i++ ) {
1234
1237
  if ( a[ order[i] ] ) {
1235
1238
  out.push( a[ order[i] ][ prop ] );
1236
1239
  }
@@ -1267,7 +1270,7 @@
1267
1270
  {
1268
1271
  var out = [];
1269
1272
 
1270
- for ( var i=0, ien=a.length ; i<ien ; i++ ) {
1273
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ ) {
1271
1274
  if ( a[i] ) { // careful - will remove all falsy values!
1272
1275
  out.push( a[i] );
1273
1276
  }
@@ -1353,7 +1356,7 @@
1353
1356
  var sorted = src.slice().sort();
1354
1357
  var last = sorted[0];
1355
1358
 
1356
- for ( var i=1, ien=sorted.length ; i<ien ; i++ ) {
1359
+ for ( var i=1, iLen=sorted.length ; i<iLen ; i++ ) {
1357
1360
  if ( sorted[i] === last ) {
1358
1361
  return false;
1359
1362
  }
@@ -1389,10 +1392,10 @@
1389
1392
  var
1390
1393
  out = [],
1391
1394
  val,
1392
- i, ien=src.length,
1395
+ i, iLen=src.length,
1393
1396
  j, k=0;
1394
1397
 
1395
- again: for ( i=0 ; i<ien ; i++ ) {
1398
+ again: for ( i=0 ; i<iLen ; i++ ) {
1396
1399
  val = src[i];
1397
1400
 
1398
1401
  for ( j=0 ; j<k ; j++ ) {
@@ -1926,7 +1929,7 @@
1926
1929
  var searchCols = init.aoSearchCols;
1927
1930
 
1928
1931
  if ( searchCols ) {
1929
- for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
1932
+ for ( var i=0, iLen=searchCols.length ; i<iLen ; i++ ) {
1930
1933
  if ( searchCols[i] ) {
1931
1934
  _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
1932
1935
  }
@@ -2079,7 +2082,7 @@
2079
2082
  oCol._sManualType = oOptions.sType;
2080
2083
  }
2081
2084
 
2082
- // `class` is a reserved word in Javascript, so we need to provide
2085
+ // `class` is a reserved word in JavaScript, so we need to provide
2083
2086
  // the ability to use a valid name for the camel case input
2084
2087
  if ( oOptions.className && ! oOptions.sClass )
2085
2088
  {
@@ -2236,14 +2239,14 @@
2236
2239
  * @returns {int} i the number of visible columns
2237
2240
  * @memberof DataTable#oApi
2238
2241
  */
2239
- function _fnVisbleColumns( settings )
2242
+ function _fnVisibleColumns( settings )
2240
2243
  {
2241
2244
  var layout = settings.aoHeader;
2242
2245
  var columns = settings.aoColumns;
2243
2246
  var vis = 0;
2244
2247
 
2245
2248
  if ( layout.length ) {
2246
- for ( var i=0, ien=layout[0].length ; i<ien ; i++ ) {
2249
+ for ( var i=0, iLen=layout[0].length ; i<iLen ; i++ ) {
2247
2250
  if ( columns[i].bVisible && $(layout[0][i].cell).css('display') !== 'none' ) {
2248
2251
  vis++;
2249
2252
  }
@@ -2278,7 +2281,7 @@
2278
2281
  /**
2279
2282
  * Allow the result from a type detection function to be `true` while
2280
2283
  * translating that into a string. Old type detection functions will
2281
- * return the type name if it passes. An obect store would be better,
2284
+ * return the type name if it passes. An object store would be better,
2282
2285
  * but not backwards compatible.
2283
2286
  *
2284
2287
  * @param {*} typeDetect Object or function for type detection
@@ -2301,11 +2304,11 @@
2301
2304
  var columns = settings.aoColumns;
2302
2305
  var data = settings.aoData;
2303
2306
  var types = DataTable.ext.type.detect;
2304
- var i, ien, j, jen, k, ken;
2307
+ var i, iLen, j, jen, k, ken;
2305
2308
  var col, detectedType, cache;
2306
2309
 
2307
2310
  // For each column, spin over the data type detection functions, seeing if one matches
2308
- for ( i=0, ien=columns.length ; i<ien ; i++ ) {
2311
+ for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
2309
2312
  col = columns[i];
2310
2313
  cache = [];
2311
2314
 
@@ -2575,7 +2578,7 @@
2575
2578
  var unit;
2576
2579
  var columns = settings.aoColumns;
2577
2580
 
2578
- for ( var i=0, ien=targets.length ; i<ien ; i++ ) {
2581
+ for ( var i=0, iLen=targets.length ; i<iLen ; i++ ) {
2579
2582
  var column = columns[ targets[i] ];
2580
2583
  var definedWidth = original ?
2581
2584
  column.sWidthOrig :
@@ -2621,7 +2624,7 @@
2621
2624
  }
2622
2625
  /**
2623
2626
  * Add a data array to the table, creating DOM node etc. This is the parallel to
2624
- * _fnGatherData, but for adding rows from a Javascript source, rather than a
2627
+ * _fnGatherData, but for adding rows from a JavaScript source, rather than a
2625
2628
  * DOM source.
2626
2629
  * @param {object} settings dataTables settings object
2627
2630
  * @param {array} data data array to be added
@@ -2761,10 +2764,10 @@
2761
2764
  }
2762
2765
 
2763
2766
  if ( type === 'filter' ) {
2764
- var fomatters = DataTable.ext.type.search;
2767
+ var formatters = DataTable.ext.type.search;
2765
2768
 
2766
- if ( fomatters[ col.sType ] ) {
2767
- cellData = fomatters[ col.sType ]( cellData );
2769
+ if ( formatters[ col.sType ] ) {
2770
+ cellData = formatters[ col.sType ]( cellData );
2768
2771
  }
2769
2772
  }
2770
2773
 
@@ -2894,7 +2897,7 @@
2894
2897
  function _fnInvalidate( settings, rowIdx, src, colIdx )
2895
2898
  {
2896
2899
  var row = settings.aoData[ rowIdx ];
2897
- var i, ien;
2900
+ var i, iLen;
2898
2901
 
2899
2902
  // Remove the cached data for the row
2900
2903
  row._aSortData = null;
@@ -2919,7 +2922,7 @@
2919
2922
  _fnWriteCell(cells[colIdx], display[colIdx]);
2920
2923
  }
2921
2924
  else {
2922
- for ( i=0, ien=cells.length ; i<ien ; i++ ) {
2925
+ for ( i=0, iLen=cells.length ; i<iLen ; i++ ) {
2923
2926
  _fnWriteCell(cells[i], display[i]);
2924
2927
  }
2925
2928
  }
@@ -2934,12 +2937,12 @@
2934
2937
 
2935
2938
  // Max length string. Its a fairly cheep recalculation, so not worth
2936
2939
  // something more complicated
2937
- cols[ colIdx ].maxLenString = null;
2940
+ cols[ colIdx ].wideStrings = null;
2938
2941
  }
2939
2942
  else {
2940
- for ( i=0, ien=cols.length ; i<ien ; i++ ) {
2943
+ for ( i=0, iLen=cols.length ; i<iLen ; i++ ) {
2941
2944
  cols[i].sType = null;
2942
- cols[i].maxLenString = null;
2945
+ cols[i].wideStrings = null;
2943
2946
  }
2944
2947
 
2945
2948
  // Update DataTables special `DT_*` attributes for the row
@@ -3236,7 +3239,7 @@
3236
3239
  {
3237
3240
  var classes = settings.oClasses;
3238
3241
  var columns = settings.aoColumns;
3239
- var i, ien, row;
3242
+ var i, iLen, row;
3240
3243
  var target = side === 'header'
3241
3244
  ? settings.nTHead
3242
3245
  : settings.nTFoot;
@@ -3264,7 +3267,7 @@
3264
3267
  cellCount += this.colSpan;
3265
3268
  });
3266
3269
 
3267
- for ( i=cellCount, ien=columns.length ; i<ien ; i++ ) {
3270
+ for ( i=cellCount, iLen=columns.length ; i<iLen ; i++ ) {
3268
3271
  $('<th/>')
3269
3272
  .html( columns[i][titleProp] || '' )
3270
3273
  .appendTo( row );
@@ -3480,6 +3483,14 @@
3480
3483
  {
3481
3484
  var iDataIndex = aiDisplay[j];
3482
3485
  var aoData = oSettings.aoData[ iDataIndex ];
3486
+
3487
+ // Row has been deleted - can't be displayed
3488
+ if (aoData === null)
3489
+ {
3490
+ continue;
3491
+ }
3492
+
3493
+ // Row node hasn't been created yet
3483
3494
  if ( aoData.nTr === null )
3484
3495
  {
3485
3496
  _fnCreateTr( oSettings, iDataIndex );
@@ -3608,7 +3619,7 @@
3608
3619
 
3609
3620
  return $( '<tr/>' )
3610
3621
  .append( $('<td />', {
3611
- 'colSpan': _fnVisbleColumns( settings ),
3622
+ 'colSpan': _fnVisibleColumns( settings ),
3612
3623
  'class': settings.oClasses.empty.row
3613
3624
  } ).html( zero ) )[0];
3614
3625
  }
@@ -3792,7 +3803,7 @@
3792
3803
 
3793
3804
  var line = row[ item ].contents;
3794
3805
 
3795
- for ( var i=0, ien=line.length ; i<ien ; i++ ) {
3806
+ for ( var i=0, iLen=line.length ; i<iLen ; i++ ) {
3796
3807
  if ( ! line[i] ) {
3797
3808
  continue;
3798
3809
  }
@@ -3956,7 +3967,7 @@
3956
3967
  /**
3957
3968
  * Use the DOM source to create up an array of header cells. The idea here is to
3958
3969
  * create a layout grid (array) of rows x columns, which contains a reference
3959
- * to the cell that that point in the grid (regardless of col/rowspan), such that
3970
+ * to the cell at that point in the grid (regardless of col/rowspan), such that
3960
3971
  * any column / row could be removed and the new grid constructed
3961
3972
  * @param {node} thead The header/footer element for the table
3962
3973
  * @returns {array} Calculated layout array
@@ -4158,24 +4169,21 @@
4158
4169
  * DataTables - may be augmented by developer callbacks
4159
4170
  * @param {function} fn Callback function to run when data is obtained
4160
4171
  */
4161
- function _fnBuildAjax( oSettings, data, fn )
4162
- {
4172
+ function _fnBuildAjax(oSettings, data, fn) {
4163
4173
  var ajaxData;
4164
4174
  var ajax = oSettings.ajax;
4165
4175
  var instance = oSettings.oInstance;
4166
- var callback = function ( json ) {
4167
- var status = oSettings.jqXHR
4168
- ? oSettings.jqXHR.status
4169
- : null;
4176
+ var callback = function (json) {
4177
+ var status = oSettings.jqXHR ? oSettings.jqXHR.status : null;
4170
4178
 
4171
- if ( json === null || (typeof status === 'number' && status == 204 ) ) {
4179
+ if (json === null || (typeof status === 'number' && status == 204)) {
4172
4180
  json = {};
4173
- _fnAjaxDataSrc( oSettings, json, [] );
4181
+ _fnAjaxDataSrc(oSettings, json, []);
4174
4182
  }
4175
4183
 
4176
4184
  var error = json.error || json.sError;
4177
- if ( error ) {
4178
- _fnLog( oSettings, 0, error );
4185
+ if (error) {
4186
+ _fnLog(oSettings, 0, error);
4179
4187
  }
4180
4188
 
4181
4189
  // Microsoft often wrap JSON as a string in another JSON object
@@ -4183,30 +4191,27 @@
4183
4191
  if (json.d && typeof json.d === 'string') {
4184
4192
  try {
4185
4193
  json = JSON.parse(json.d);
4186
- }
4187
- catch (e) {
4194
+ } catch (e) {
4188
4195
  // noop
4189
4196
  }
4190
4197
  }
4191
4198
 
4192
4199
  oSettings.json = json;
4193
4200
 
4194
- _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR], true );
4195
- fn( json );
4201
+ _fnCallbackFire(oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR], true);
4202
+ fn(json);
4196
4203
  };
4197
4204
 
4198
- if ( $.isPlainObject( ajax ) && ajax.data )
4199
- {
4205
+ if ($.isPlainObject(ajax) && ajax.data) {
4200
4206
  ajaxData = ajax.data;
4201
4207
 
4202
- var newData = typeof ajaxData === 'function' ?
4203
- ajaxData( data, oSettings ) : // fn can manipulate data or return
4204
- ajaxData; // an object object or array to merge
4208
+ var newData =
4209
+ typeof ajaxData === 'function'
4210
+ ? ajaxData(data, oSettings) // fn can manipulate data or return
4211
+ : ajaxData; // an object or array to merge
4205
4212
 
4206
4213
  // If the function returned something, use that alone
4207
- data = typeof ajaxData === 'function' && newData ?
4208
- newData :
4209
- $.extend( true, data, newData );
4214
+ data = typeof ajaxData === 'function' && newData ? newData : $.extend(true, data, newData);
4210
4215
 
4211
4216
  // Remove the data property as we've resolved it already and don't want
4212
4217
  // jQuery to do it again (it is restored at the end of the function)
@@ -4214,50 +4219,53 @@
4214
4219
  }
4215
4220
 
4216
4221
  var baseAjax = {
4217
- "url": typeof ajax === 'string' ?
4218
- ajax :
4219
- '',
4220
- "data": data,
4221
- "success": callback,
4222
- "dataType": "json",
4223
- "cache": false,
4224
- "type": oSettings.sServerMethod,
4225
- "error": function (xhr, error) {
4226
- var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR], true );
4227
-
4228
- if ( ret.indexOf(true) === -1 ) {
4229
- if ( error == "parsererror" ) {
4230
- _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
4222
+ url: typeof ajax === 'string' ? ajax : '',
4223
+ data: data,
4224
+ success: callback,
4225
+ dataType: 'json',
4226
+ cache: false,
4227
+ type: oSettings.sServerMethod,
4228
+ error: function (xhr, error) {
4229
+ var ret = _fnCallbackFire(
4230
+ oSettings,
4231
+ null,
4232
+ 'xhr',
4233
+ [oSettings, null, oSettings.jqXHR],
4234
+ true
4235
+ );
4236
+
4237
+ if (ret.indexOf(true) === -1) {
4238
+ if (error == 'parsererror') {
4239
+ _fnLog(oSettings, 0, 'Invalid JSON response', 1);
4231
4240
  }
4232
- else if ( xhr.readyState === 4 ) {
4233
- _fnLog( oSettings, 0, 'Ajax error', 7 );
4241
+ else if (xhr.readyState === 4) {
4242
+ _fnLog(oSettings, 0, 'Ajax error', 7);
4234
4243
  }
4235
4244
  }
4236
4245
 
4237
- _fnProcessingDisplay( oSettings, false );
4246
+ _fnProcessingDisplay(oSettings, false);
4238
4247
  }
4239
4248
  };
4240
4249
 
4241
4250
  // If `ajax` option is an object, extend and override our default base
4242
- if ( $.isPlainObject( ajax ) ) {
4243
- $.extend( baseAjax, ajax )
4251
+ if ($.isPlainObject(ajax)) {
4252
+ $.extend(baseAjax, ajax);
4244
4253
  }
4245
4254
 
4246
4255
  // Store the data submitted for the API
4247
4256
  oSettings.oAjaxData = data;
4248
4257
 
4249
4258
  // Allow plug-ins and external processes to modify the data
4250
- _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data, baseAjax], true );
4259
+ _fnCallbackFire(oSettings, null, 'preXhr', [oSettings, data, baseAjax], true);
4251
4260
 
4252
4261
  // Custom Ajax option to submit the parameters as a JSON string
4253
4262
  if (baseAjax.submitAs === 'json' && typeof data === 'object') {
4254
4263
  baseAjax.data = JSON.stringify(data);
4255
4264
  }
4256
4265
 
4257
- if ( typeof ajax === 'function' )
4258
- {
4266
+ if (typeof ajax === 'function') {
4259
4267
  // Is a function - let the caller define what needs to be done
4260
- oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
4268
+ oSettings.jqXHR = ajax.call(instance, data, callback, oSettings);
4261
4269
  }
4262
4270
  else if (ajax.url === '') {
4263
4271
  // No url, so don't load any data. Just apply an empty data array
@@ -4269,37 +4277,30 @@
4269
4277
  }
4270
4278
  else {
4271
4279
  // Object to extend the base settings
4272
- oSettings.jqXHR = $.ajax( baseAjax );
4280
+ oSettings.jqXHR = $.ajax(baseAjax);
4273
4281
  }
4274
4282
 
4275
4283
  // Restore for next time around
4276
- if ( ajaxData ) {
4284
+ if (ajaxData) {
4277
4285
  ajax.data = ajaxData;
4278
4286
  }
4279
4287
  }
4280
4288
 
4281
-
4282
4289
  /**
4283
4290
  * Update the table using an Ajax call
4284
4291
  * @param {object} settings dataTables settings object
4285
4292
  * @returns {boolean} Block the table drawing or not
4286
4293
  * @memberof DataTable#oApi
4287
4294
  */
4288
- function _fnAjaxUpdate( settings )
4289
- {
4295
+ function _fnAjaxUpdate(settings) {
4290
4296
  settings.iDraw++;
4291
- _fnProcessingDisplay( settings, true );
4297
+ _fnProcessingDisplay(settings, true);
4292
4298
 
4293
- _fnBuildAjax(
4294
- settings,
4295
- _fnAjaxParameters( settings ),
4296
- function(json) {
4297
- _fnAjaxUpdateDraw( settings, json );
4298
- }
4299
- );
4299
+ _fnBuildAjax(settings, _fnAjaxParameters(settings), function (json) {
4300
+ _fnAjaxUpdateDraw(settings, json);
4301
+ });
4300
4302
  }
4301
4303
 
4302
-
4303
4304
  /**
4304
4305
  * Build up the parameters in an object needed for a server-side processing
4305
4306
  * request.
@@ -4307,22 +4308,18 @@
4307
4308
  * @returns {bool} block the table drawing or not
4308
4309
  * @memberof DataTable#oApi
4309
4310
  */
4310
- function _fnAjaxParameters( settings )
4311
- {
4312
- var
4313
- columns = settings.aoColumns,
4311
+ function _fnAjaxParameters(settings) {
4312
+ var columns = settings.aoColumns,
4314
4313
  features = settings.oFeatures,
4315
4314
  preSearch = settings.oPreviousSearch,
4316
4315
  preColSearch = settings.aoPreSearchCols,
4317
- colData = function ( idx, prop ) {
4318
- return typeof columns[idx][prop] === 'function' ?
4319
- 'function' :
4320
- columns[idx][prop];
4316
+ colData = function (idx, prop) {
4317
+ return typeof columns[idx][prop] === 'function' ? 'function' : columns[idx][prop];
4321
4318
  };
4322
4319
 
4323
4320
  return {
4324
4321
  draw: settings.iDraw,
4325
- columns: columns.map( function ( column, i ) {
4322
+ columns: columns.map(function (column, i) {
4326
4323
  return {
4327
4324
  data: colData(i, 'mData'),
4328
4325
  name: column.sName,
@@ -4331,40 +4328,43 @@
4331
4328
  search: {
4332
4329
  value: preColSearch[i].search,
4333
4330
  regex: preColSearch[i].regex,
4334
- fixed: Object.keys(column.searchFixed).map( function(name) {
4335
- return {
4336
- name: name,
4337
- term: column.searchFixed[name].toString()
4338
- }
4339
- })
4331
+ fixed: Object.keys(column.searchFixed)
4332
+ .map(function (name) {
4333
+ return {
4334
+ name: name,
4335
+ term: typeof column.searchFixed[name] !== 'function'
4336
+ ? column.searchFixed[name].toString()
4337
+ : 'function'
4338
+ };
4339
+ })
4340
4340
  }
4341
4341
  };
4342
- } ),
4343
- order: _fnSortFlatten( settings ).map( function ( val ) {
4342
+ }),
4343
+ order: _fnSortFlatten(settings).map(function (val) {
4344
4344
  return {
4345
4345
  column: val.col,
4346
4346
  dir: val.dir,
4347
4347
  name: colData(val.col, 'sName')
4348
4348
  };
4349
- } ),
4349
+ }),
4350
4350
  start: settings._iDisplayStart,
4351
- length: features.bPaginate ?
4352
- settings._iDisplayLength :
4353
- -1,
4351
+ length: features.bPaginate ? settings._iDisplayLength : -1,
4354
4352
  search: {
4355
4353
  value: preSearch.search,
4356
4354
  regex: preSearch.regex,
4357
- fixed: Object.keys(settings.searchFixed).map( function(name) {
4358
- return {
4359
- name: name,
4360
- term: settings.searchFixed[name].toString()
4361
- }
4362
- })
4355
+ fixed: Object.keys(settings.searchFixed)
4356
+ .map(function (name) {
4357
+ return {
4358
+ name: name,
4359
+ term: typeof settings.searchFixed[name] !== 'function'
4360
+ ? settings.searchFixed[name].toString()
4361
+ : 'function'
4362
+ };
4363
+ })
4363
4364
  }
4364
4365
  };
4365
4366
  }
4366
4367
 
4367
-
4368
4368
  /**
4369
4369
  * Data the data from the server (nuking the old) and redraw the table
4370
4370
  * @param {object} oSettings dataTables settings object
@@ -4376,42 +4376,40 @@
4376
4376
  * @param {string} [json.sColumns] Column ordering (sName, comma separated)
4377
4377
  * @memberof DataTable#oApi
4378
4378
  */
4379
- function _fnAjaxUpdateDraw ( settings, json )
4380
- {
4379
+ function _fnAjaxUpdateDraw(settings, json) {
4381
4380
  var data = _fnAjaxDataSrc(settings, json);
4382
4381
  var draw = _fnAjaxDataSrcParam(settings, 'draw', json);
4383
4382
  var recordsTotal = _fnAjaxDataSrcParam(settings, 'recordsTotal', json);
4384
4383
  var recordsFiltered = _fnAjaxDataSrcParam(settings, 'recordsFiltered', json);
4385
4384
 
4386
- if ( draw !== undefined ) {
4385
+ if (draw !== undefined) {
4387
4386
  // Protect against out of sequence returns
4388
- if ( draw*1 < settings.iDraw ) {
4387
+ if (draw * 1 < settings.iDraw) {
4389
4388
  return;
4390
4389
  }
4391
4390
  settings.iDraw = draw * 1;
4392
4391
  }
4393
4392
 
4394
4393
  // No data in returned object, so rather than an array, we show an empty table
4395
- if ( ! data ) {
4394
+ if (!data) {
4396
4395
  data = [];
4397
4396
  }
4398
4397
 
4399
- _fnClearTable( settings );
4400
- settings._iRecordsTotal = parseInt(recordsTotal, 10);
4398
+ _fnClearTable(settings);
4399
+ settings._iRecordsTotal = parseInt(recordsTotal, 10);
4401
4400
  settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
4402
4401
 
4403
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
4404
- _fnAddData( settings, data[i] );
4402
+ for (var i = 0, iLen = data.length; i < iLen; i++) {
4403
+ _fnAddData(settings, data[i]);
4405
4404
  }
4406
4405
  settings.aiDisplay = settings.aiDisplayMaster.slice();
4407
4406
 
4408
4407
  _fnColumnTypes(settings);
4409
- _fnDraw( settings, true );
4410
- _fnInitComplete( settings );
4411
- _fnProcessingDisplay( settings, false );
4408
+ _fnDraw(settings, true);
4409
+ _fnInitComplete(settings);
4410
+ _fnProcessingDisplay(settings, false);
4412
4411
  }
4413
4412
 
4414
-
4415
4413
  /**
4416
4414
  * Get the data from the JSON data source to use for drawing a table. Using
4417
4415
  * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
@@ -4420,11 +4418,10 @@
4420
4418
  * @param {object} json Data source object / array from the server
4421
4419
  * @return {array} Array of data to use
4422
4420
  */
4423
- function _fnAjaxDataSrc ( settings, json, write )
4424
- {
4421
+ function _fnAjaxDataSrc(settings, json, write) {
4425
4422
  var dataProp = 'data';
4426
4423
 
4427
- if ($.isPlainObject( settings.ajax ) && settings.ajax.dataSrc !== undefined) {
4424
+ if ($.isPlainObject(settings.ajax) && settings.ajax.dataSrc !== undefined) {
4428
4425
  // Could in inside a `dataSrc` object, or not!
4429
4426
  var dataSrc = settings.ajax.dataSrc;
4430
4427
 
@@ -4437,20 +4434,18 @@
4437
4434
  }
4438
4435
  }
4439
4436
 
4440
- if ( ! write ) {
4441
- if ( dataProp === 'data' ) {
4437
+ if (!write) {
4438
+ if (dataProp === 'data') {
4442
4439
  // If the default, then we still want to support the old style, and safely ignore
4443
4440
  // it if possible
4444
4441
  return json.aaData || json[dataProp];
4445
4442
  }
4446
4443
 
4447
- return dataProp !== "" ?
4448
- _fnGetObjectDataFn( dataProp )( json ) :
4449
- json;
4444
+ return dataProp !== '' ? _fnGetObjectDataFn(dataProp)(json) : json;
4450
4445
  }
4451
-
4446
+
4452
4447
  // set
4453
- _fnSetObjectDataFn( dataProp )( json, write );
4448
+ _fnSetObjectDataFn(dataProp)(json, write);
4454
4449
  }
4455
4450
 
4456
4451
  /**
@@ -4460,14 +4455,12 @@
4460
4455
  * @param {*} json JSON data
4461
4456
  * @returns Resolved value
4462
4457
  */
4463
- function _fnAjaxDataSrcParam (settings, param, json) {
4464
- var dataSrc = $.isPlainObject( settings.ajax )
4465
- ? settings.ajax.dataSrc
4466
- : null;
4458
+ function _fnAjaxDataSrcParam(settings, param, json) {
4459
+ var dataSrc = $.isPlainObject(settings.ajax) ? settings.ajax.dataSrc : null;
4467
4460
 
4468
4461
  if (dataSrc && dataSrc[param]) {
4469
4462
  // Get from custom location
4470
- return _fnGetObjectDataFn( dataSrc[param] )( json );
4463
+ return _fnGetObjectDataFn(dataSrc[param])(json);
4471
4464
  }
4472
4465
 
4473
4466
  // else - Default behaviour
@@ -4484,9 +4477,7 @@
4484
4477
  old = 'iTotalDisplayRecords';
4485
4478
  }
4486
4479
 
4487
- return json[old] !== undefined
4488
- ? json[old]
4489
- : json[param];
4480
+ return json[old] !== undefined ? json[old] : json[param];
4490
4481
  }
4491
4482
 
4492
4483
 
@@ -4559,7 +4550,7 @@
4559
4550
  var displayRows = settings.aiDisplay;
4560
4551
  var row, rowIdx;
4561
4552
 
4562
- for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
4553
+ for ( var i=0, iLen=filters.length ; i<iLen ; i++ ) {
4563
4554
  var rows = [];
4564
4555
 
4565
4556
  // Loop over each row and see if it should be included
@@ -4627,7 +4618,7 @@
4627
4618
  * @param {string} sSearch string to search for
4628
4619
  * @param {bool} bRegex treat as a regular expression or not
4629
4620
  * @param {bool} bSmart perform smart filtering or not
4630
- * @param {bool} bCaseInsensitive Do case insensitive matching or not
4621
+ * @param {bool} bCaseInsensitive Do case-insensitive matching or not
4631
4622
  * @returns {RegExp} constructed object
4632
4623
  * @memberof DataTable#oApi
4633
4624
  */
@@ -5370,7 +5361,7 @@
5370
5361
  }
5371
5362
 
5372
5363
  // 4. Clean up
5373
- // Figure out if there are scrollbar present - if so then we need a the header and footer to
5364
+ // Figure out if there are scrollbar present - if so then we need the header and footer to
5374
5365
  // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
5375
5366
  var isScrolling = Math.floor(table.height()) > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
5376
5367
  var paddingSide = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
@@ -5425,7 +5416,7 @@
5425
5416
  visibleColumns = _fnGetColumns( settings, 'bVisible' ),
5426
5417
  tableWidthAttr = table.getAttribute('width'), // from DOM element
5427
5418
  tableContainer = table.parentNode,
5428
- i, column, columnIdx;
5419
+ i, j, column, columnIdx;
5429
5420
 
5430
5421
  var styleWidth = table.style.width;
5431
5422
  var containerWidth = _fnWrapperWidth(settings);
@@ -5459,17 +5450,16 @@
5459
5450
  false
5460
5451
  );
5461
5452
 
5462
- // Construct a single row, worst case, table with the widest
5463
- // node in the data, assign any user defined widths, then insert it into
5464
- // the DOM and allow the browser to do all the hard work of calculating
5465
- // table widths
5453
+ // Construct a worst case table with the widest, assign any user defined
5454
+ // widths, then insert it into the DOM and allow the browser to do all
5455
+ // the hard work of calculating table widths
5466
5456
  var tmpTable = $(table.cloneNode())
5467
5457
  .css( 'visibility', 'hidden' )
5458
+ .css( 'margin', 0 )
5468
5459
  .removeAttr( 'id' );
5469
5460
 
5470
5461
  // Clean up the table body
5471
- tmpTable.append('<tbody>')
5472
- var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
5462
+ tmpTable.append('<tbody/>')
5473
5463
 
5474
5464
  // Clone the table header and footer - we can't use the header / footer
5475
5465
  // from the cloned table, since if scrolling is active, the table's
@@ -5509,23 +5499,37 @@
5509
5499
  }
5510
5500
  } );
5511
5501
 
5512
- // Find the widest piece of data for each column and put it into the table
5502
+ // Get the widest strings for each of the visible columns and add them to
5503
+ // our table to create a "worst case"
5504
+ var longestData = [];
5505
+
5513
5506
  for ( i=0 ; i<visibleColumns.length ; i++ ) {
5514
- columnIdx = visibleColumns[i];
5515
- column = columns[ columnIdx ];
5516
-
5517
- var longest = _fnGetMaxLenString(settings, columnIdx);
5518
- var autoClass = _ext.type.className[column.sType];
5519
- var text = longest + column.sContentPadding;
5520
- var insert = longest.indexOf('<') === -1
5521
- ? document.createTextNode(text)
5522
- : text
5523
-
5524
- $('<td/>')
5525
- .addClass(autoClass)
5526
- .addClass(column.sClass)
5527
- .append(insert)
5528
- .appendTo(tr);
5507
+ longestData.push(_fnGetWideStrings(settings, visibleColumns[i]));
5508
+ }
5509
+
5510
+ if (longestData.length) {
5511
+ for ( i=0 ; i<longestData[0].length ; i++ ) {
5512
+ var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
5513
+
5514
+ for ( j=0 ; j<visibleColumns.length ; j++ ) {
5515
+ columnIdx = visibleColumns[j];
5516
+ column = columns[ columnIdx ];
5517
+
5518
+ var longest = longestData[j][i] || '';
5519
+ var autoClass = _ext.type.className[column.sType];
5520
+ var padding = column.sContentPadding || (scrollX ? '-' : '');
5521
+ var text = longest + padding;
5522
+ var insert = longest.indexOf('<') === -1
5523
+ ? document.createTextNode(text)
5524
+ : text
5525
+
5526
+ $('<td/>')
5527
+ .addClass(autoClass)
5528
+ .addClass(column.sClass)
5529
+ .append(insert)
5530
+ .appendTo(tr);
5531
+ }
5532
+ }
5529
5533
  }
5530
5534
 
5531
5535
  // Tidy the temporary table - remove name attributes so there aren't
@@ -5664,20 +5668,32 @@
5664
5668
  }
5665
5669
 
5666
5670
  /**
5667
- * Get the maximum strlen for each data column
5671
+ * Get the widest strings for each column.
5672
+ *
5673
+ * It is very difficult to determine what the widest string actually is due to variable character
5674
+ * width and kerning. Doing an exact calculation with the DOM or even Canvas would kill performance
5675
+ * and this is a critical point, so we use two techniques to determine a collection of the longest
5676
+ * strings from the column, which will likely contain the widest strings:
5677
+ *
5678
+ * 1) Get the top three longest strings from the column
5679
+ * 2) Get the top three widest words (i.e. an unbreakable phrase)
5680
+ *
5668
5681
  * @param {object} settings dataTables settings object
5669
5682
  * @param {int} colIdx column of interest
5670
- * @returns {string} string of the max length
5683
+ * @returns {string[]} Array of the longest strings
5671
5684
  * @memberof DataTable#oApi
5672
5685
  */
5673
- function _fnGetMaxLenString( settings, colIdx )
5686
+ function _fnGetWideStrings( settings, colIdx )
5674
5687
  {
5675
5688
  var column = settings.aoColumns[colIdx];
5676
5689
 
5677
- if (! column.maxLenString) {
5678
- var s, max='', maxLen = -1;
5679
-
5680
- for ( var i=0, ien=settings.aiDisplayMaster.length ; i<ien ; i++ ) {
5690
+ // Do we need to recalculate (i.e. was invalidated), or just use the cached data?
5691
+ if (! column.wideStrings) {
5692
+ var allStrings = [];
5693
+ var collection = [];
5694
+
5695
+ // Create an array with the string information for the column
5696
+ for ( var i=0, iLen=settings.aiDisplayMaster.length ; i<iLen ; i++ ) {
5681
5697
  var rowIdx = settings.aiDisplayMaster[i];
5682
5698
  var data = _fnGetRowDisplay(settings, rowIdx)[colIdx];
5683
5699
 
@@ -5691,21 +5707,49 @@
5691
5707
  .replace(/id=".*?"/g, '')
5692
5708
  .replace(/name=".*?"/g, '');
5693
5709
 
5694
- s = _stripHtml(cellString)
5710
+ var s = _stripHtml(cellString)
5695
5711
  .replace( /&nbsp;/g, ' ' );
5696
5712
 
5697
- if ( s.length > maxLen ) {
5698
- // We want the HTML in the string, but the length that
5699
- // is important is the stripped string
5700
- max = cellString;
5701
- maxLen = s.length;
5702
- }
5713
+ collection.push({
5714
+ str: s,
5715
+ len: s.length
5716
+ });
5717
+
5718
+ allStrings.push(s);
5719
+ }
5720
+
5721
+ // Order and then cut down to the size we need
5722
+ collection
5723
+ .sort(function (a, b) {
5724
+ return b.len - a.len;
5725
+ })
5726
+ .splice(3);
5727
+
5728
+ column.wideStrings = collection.map(function (item) {
5729
+ return item.str;
5730
+ });
5731
+
5732
+ // Longest unbroken string
5733
+ let parts = allStrings.join(' ').split(' ');
5734
+
5735
+ parts.sort(function (a, b) {
5736
+ return b.length - a.length;
5737
+ });
5738
+
5739
+ if (parts.length) {
5740
+ column.wideStrings.push(parts[0]);
5741
+ }
5742
+
5743
+ if (parts.length > 1) {
5744
+ column.wideStrings.push(parts[1]);
5703
5745
  }
5704
5746
 
5705
- column.maxLenString = max;
5747
+ if (parts.length > 2) {
5748
+ column.wideStrings.push(parts[3]);
5749
+ }
5706
5750
  }
5707
5751
 
5708
- return column.maxLenString;
5752
+ return column.wideStrings;
5709
5753
  }
5710
5754
 
5711
5755
 
@@ -5799,7 +5843,7 @@
5799
5843
  : [column];
5800
5844
 
5801
5845
  if ( columns.length ) {
5802
- for ( var i=0, ien=columns.length ; i<ien ; i++ ) {
5846
+ for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) {
5803
5847
  var ret = _fnSortAdd( settings, columns[i], i, e.shiftKey );
5804
5848
 
5805
5849
  if (ret !== false) {
@@ -5848,7 +5892,7 @@
5848
5892
  masterMap[master[i]] = i;
5849
5893
  }
5850
5894
 
5851
- // And then cache what would be the indexOf fom the display
5895
+ // And then cache what would be the indexOf from the display
5852
5896
  for (i=0 ; i<display.length ; i++) {
5853
5897
  map[display[i]] = masterMap[display[i]];
5854
5898
  }
@@ -5974,7 +6018,7 @@
5974
6018
  function _fnSort ( oSettings, col, dir )
5975
6019
  {
5976
6020
  var
5977
- i, ien, iLen,
6021
+ i, iLen,
5978
6022
  aiOrig = [],
5979
6023
  extSort = DataTable.ext.type.order,
5980
6024
  aoData = oSettings.aoData,
@@ -6005,7 +6049,7 @@
6005
6049
  aSort = _fnSortFlatten( oSettings );
6006
6050
  }
6007
6051
 
6008
- for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
6052
+ for ( i=0, iLen=aSort.length ; i<iLen ; i++ ) {
6009
6053
  sortCol = aSort[i];
6010
6054
 
6011
6055
  // Load the data needed for the sort, for each cell
@@ -6028,7 +6072,7 @@
6028
6072
 
6029
6073
  /* Do the sort - here we want multi-column sorting based on a given data source (column)
6030
6074
  * and sorting function (from oSort) in a certain direction. It's reasonably complex to
6031
- * follow on it's own, but this is what we want (example two column sorting):
6075
+ * follow on its own, but this is what we want (example two column sorting):
6032
6076
  * fnLocalSorting = function(a,b){
6033
6077
  * var test;
6034
6078
  * test = oSort['string-asc']('data11', 'data12');
@@ -6152,7 +6196,7 @@
6152
6196
  nextSortIdx = 0; // can't remove sorting completely
6153
6197
  }
6154
6198
 
6155
- if ( nextSortIdx === null ) {
6199
+ if ( nextSortIdx === null || asSorting[ nextSortIdx ] === '' ) {
6156
6200
  sorting.splice( sortIdx, 1 );
6157
6201
  }
6158
6202
  else {
@@ -6202,11 +6246,11 @@
6202
6246
  var sortClass = settings.oClasses.order.position;
6203
6247
  var sort = _fnSortFlatten( settings );
6204
6248
  var features = settings.oFeatures;
6205
- var i, ien, colIdx;
6249
+ var i, iLen, colIdx;
6206
6250
 
6207
6251
  if ( features.bSort && features.bSortClasses ) {
6208
6252
  // Remove old sorting classes
6209
- for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
6253
+ for ( i=0, iLen=oldSort.length ; i<iLen ; i++ ) {
6210
6254
  colIdx = oldSort[i].src;
6211
6255
 
6212
6256
  // Remove column sorting
@@ -6215,7 +6259,7 @@
6215
6259
  }
6216
6260
 
6217
6261
  // Add new column sorting
6218
- for ( i=0, ien=sort.length ; i<ien ; i++ ) {
6262
+ for ( i=0, iLen=sort.length ; i<iLen ; i++ ) {
6219
6263
  colIdx = sort[i].src;
6220
6264
 
6221
6265
  $( _pluck( settings.aoData, 'anCells', colIdx ) )
@@ -6349,7 +6393,7 @@
6349
6393
  }
6350
6394
 
6351
6395
  function _fnImplementState ( settings, s, callback) {
6352
- var i, ien;
6396
+ var i, iLen;
6353
6397
  var columns = settings.aoColumns;
6354
6398
  var currentNames = _pluck(settings.aoColumns, 'sName');
6355
6399
 
@@ -6478,7 +6522,7 @@
6478
6522
 
6479
6523
  // If the number of columns to restore is different from current, then all bets are off.
6480
6524
  if (set.length === columns.length) {
6481
- for ( i=0, ien=set.length ; i<ien ; i++ ) {
6525
+ for ( i=0, iLen=set.length ; i<iLen ; i++ ) {
6482
6526
  var col = set[i];
6483
6527
 
6484
6528
  // Visibility
@@ -6501,7 +6545,9 @@
6501
6545
 
6502
6546
  // If the api is defined then we need to adjust the columns once the visibility has been changed
6503
6547
  if (api) {
6504
- api.columns.adjust();
6548
+ api.one('draw', function () {
6549
+ api.columns.adjust();
6550
+ });
6505
6551
  }
6506
6552
  }
6507
6553
  }
@@ -6632,7 +6678,7 @@
6632
6678
 
6633
6679
 
6634
6680
  /**
6635
- * Bind an event handers to allow a click or return key to activate the callback.
6681
+ * Bind an event handler to allow a click or return key to activate the callback.
6636
6682
  * This is good for accessibility since a return on the keyboard will have the
6637
6683
  * same effect as a click, if the element has focus.
6638
6684
  * @param {element} n Element to bind the action to
@@ -6821,7 +6867,7 @@
6821
6867
  }
6822
6868
 
6823
6869
  /**
6824
- * Add elements to an array as quickly as possible, but stack stafe.
6870
+ * Add elements to an array as quickly as possible, but stack safe.
6825
6871
  *
6826
6872
  * @param {*} arr Array to add the data to
6827
6873
  * @param {*} data Data array that is to be added
@@ -7097,7 +7143,7 @@
7097
7143
 
7098
7144
  each: function ( fn )
7099
7145
  {
7100
- for ( var i=0, ien=this.length ; i<ien; i++ ) {
7146
+ for ( var i=0, iLen=this.length ; i<iLen; i++ ) {
7101
7147
  fn.call( this, this[i], i, this );
7102
7148
  }
7103
7149
 
@@ -7143,7 +7189,7 @@
7143
7189
  iterator: function ( flatten, type, fn, alwaysNew ) {
7144
7190
  var
7145
7191
  a = [], ret,
7146
- i, ien, j, jen,
7192
+ i, iLen, j, jen,
7147
7193
  context = this.context,
7148
7194
  rows, items, item,
7149
7195
  selector = this.selector;
@@ -7156,7 +7202,7 @@
7156
7202
  flatten = false;
7157
7203
  }
7158
7204
 
7159
- for ( i=0, ien=context.length ; i<ien ; i++ ) {
7205
+ for ( i=0, iLen=context.length ; i<iLen ; i++ ) {
7160
7206
  var apiInst = new _Api( context[i] );
7161
7207
 
7162
7208
  if ( type === 'table' ) {
@@ -7278,18 +7324,18 @@
7278
7324
  } );
7279
7325
 
7280
7326
 
7281
- function _api_scope( scope, fn, struc ) {
7327
+ function _api_scope( scope, fn, struct ) {
7282
7328
  return function () {
7283
7329
  var ret = fn.apply( scope || this, arguments );
7284
7330
 
7285
7331
  // Method extension
7286
- _Api.extend( ret, ret, struc.methodExt );
7332
+ _Api.extend( ret, ret, struct.methodExt );
7287
7333
  return ret;
7288
7334
  };
7289
7335
  }
7290
7336
 
7291
7337
  function _api_find( src, name ) {
7292
- for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7338
+ for ( var i=0, iLen=src.length ; i<iLen ; i++ ) {
7293
7339
  if ( src[i].name === name ) {
7294
7340
  return src[i];
7295
7341
  }
@@ -7307,10 +7353,10 @@
7307
7353
  }
7308
7354
 
7309
7355
  var
7310
- i, ien,
7356
+ i, iLen,
7311
7357
  struct;
7312
7358
 
7313
- for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7359
+ for ( i=0, iLen=ext.length ; i<iLen ; i++ ) {
7314
7360
  struct = ext[i];
7315
7361
 
7316
7362
  if (struct.name === '__proto__') {
@@ -7365,12 +7411,12 @@
7365
7411
  }
7366
7412
 
7367
7413
  var
7368
- i, ien,
7414
+ i, iLen,
7369
7415
  heir = name.split('.'),
7370
7416
  struct = __apiStruct,
7371
7417
  key, method;
7372
7418
 
7373
- for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7419
+ for ( i=0, iLen=heir.length ; i<iLen ; i++ ) {
7374
7420
  method = heir[i].indexOf('()') !== -1;
7375
7421
  key = method ?
7376
7422
  heir[i].replace('()', '') :
@@ -7388,7 +7434,7 @@
7388
7434
  struct.push( src );
7389
7435
  }
7390
7436
 
7391
- if ( i === ien-1 ) {
7437
+ if ( i === iLen-1 ) {
7392
7438
  src.val = val;
7393
7439
  src.type = typeof val === 'function' ?
7394
7440
  'function' :
@@ -7730,7 +7776,7 @@
7730
7776
  */
7731
7777
  _api_register( 'page.len()', function ( len ) {
7732
7778
  // Note that we can't call this function 'length()' because `length`
7733
- // is a Javascript property of functions which defines how many arguments
7779
+ // is a JavaScript property of functions which defines how many arguments
7734
7780
  // the function expects.
7735
7781
  if ( len === undefined ) {
7736
7782
  return this.context.length !== 0 ?
@@ -7773,7 +7819,7 @@
7773
7819
  _fnClearTable( settings );
7774
7820
 
7775
7821
  var data = _fnAjaxDataSrc( settings, json );
7776
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7822
+ for ( var i=0, iLen=data.length ; i<iLen ; i++ ) {
7777
7823
  _fnAddData( settings, data[i] );
7778
7824
  }
7779
7825
 
@@ -7896,7 +7942,7 @@
7896
7942
  {
7897
7943
  var
7898
7944
  out = [], res,
7899
- i, ien,
7945
+ i, iLen,
7900
7946
  selectorType = typeof selector;
7901
7947
 
7902
7948
  // Can't just check for isArray here, as an API or jQuery instance might be
@@ -7905,7 +7951,7 @@
7905
7951
  selector = [ selector ];
7906
7952
  }
7907
7953
 
7908
- for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7954
+ for ( i=0, iLen=selector.length ; i<iLen ; i++ ) {
7909
7955
  res = selectFn( typeof selector[i] === 'string' ? selector[i].trim() : selector[i] );
7910
7956
 
7911
7957
  // Remove empty items
@@ -7921,7 +7967,7 @@
7921
7967
  // selector extensions
7922
7968
  var ext = _ext.selector[ type ];
7923
7969
  if ( ext.length ) {
7924
- for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7970
+ for ( i=0, iLen=ext.length ; i<iLen ; i++ ) {
7925
7971
  out = ext[i]( settings, opts, out );
7926
7972
  }
7927
7973
  }
@@ -7976,7 +8022,7 @@
7976
8022
  var _selector_row_indexes = function ( settings, opts )
7977
8023
  {
7978
8024
  var
7979
- i, ien, tmp, a=[],
8025
+ i, iLen, tmp, a=[],
7980
8026
  displayFiltered = settings.aiDisplay,
7981
8027
  displayMaster = settings.aiDisplayMaster;
7982
8028
 
@@ -7999,7 +8045,7 @@
7999
8045
  // Current page implies that order=current and filter=applied, since it is
8000
8046
  // fairly senseless otherwise, regardless of what order and search actually
8001
8047
  // are
8002
- for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
8048
+ for ( i=settings._iDisplayStart, iLen=settings.fnDisplayEnd() ; i<iLen ; i++ ) {
8003
8049
  a.push( displayFiltered[i] );
8004
8050
  }
8005
8051
  }
@@ -8014,7 +8060,7 @@
8014
8060
  // O(n+m) solution by creating a hash map
8015
8061
  var displayFilteredMap = {};
8016
8062
 
8017
- for ( i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
8063
+ for ( i=0, iLen=displayFiltered.length ; i<iLen ; i++ ) {
8018
8064
  displayFilteredMap[displayFiltered[i]] = null;
8019
8065
  }
8020
8066
 
@@ -8026,7 +8072,7 @@
8026
8072
  }
8027
8073
  }
8028
8074
  else if ( order == 'index' || order == 'original' ) {
8029
- for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
8075
+ for ( i=0, iLen=settings.aoData.length ; i<iLen ; i++ ) {
8030
8076
  if (! settings.aoData[i]) {
8031
8077
  continue;
8032
8078
  }
@@ -8243,7 +8289,7 @@
8243
8289
  var context = this.context;
8244
8290
 
8245
8291
  // `iterator` will drop undefined values, but in this case we want them
8246
- for ( var i=0, ien=context.length ; i<ien ; i++ ) {
8292
+ for ( var i=0, iLen=context.length ; i<iLen ; i++ ) {
8247
8293
  for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
8248
8294
  var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
8249
8295
  a.push( (hash === true ? '#' : '' )+ id );
@@ -8287,10 +8333,10 @@
8287
8333
 
8288
8334
  _api_register( 'rows.add()', function ( rows ) {
8289
8335
  var newRows = this.iterator( 'table', function ( settings ) {
8290
- var row, i, ien;
8336
+ var row, i, iLen;
8291
8337
  var out = [];
8292
8338
 
8293
- for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8339
+ for ( i=0, iLen=rows.length ; i<iLen ; i++ ) {
8294
8340
  row = rows[i];
8295
8341
 
8296
8342
  if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
@@ -8437,7 +8483,7 @@
8437
8483
  var addRow = function ( r, k ) {
8438
8484
  // Recursion to allow for arrays of jQuery objects
8439
8485
  if ( Array.isArray( r ) || r instanceof $ ) {
8440
- for ( var i=0, ien=r.length ; i<ien ; i++ ) {
8486
+ for ( var i=0, iLen=r.length ; i<iLen ; i++ ) {
8441
8487
  addRow( r[i], k );
8442
8488
  }
8443
8489
  return;
@@ -8457,7 +8503,7 @@
8457
8503
 
8458
8504
  $('td', created)
8459
8505
  .addClass( k )
8460
- .html( r )[0].colSpan = _fnVisbleColumns( ctx );
8506
+ .html( r )[0].colSpan = _fnVisibleColumns( ctx );
8461
8507
 
8462
8508
  rows.push( created[0] );
8463
8509
  }
@@ -8495,7 +8541,7 @@
8495
8541
  var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8496
8542
 
8497
8543
  if ( row && row._details ) {
8498
- row._details.remove();
8544
+ row._details.detach();
8499
8545
 
8500
8546
  row._detailsShow = undefined;
8501
8547
  row._details = undefined;
@@ -8569,9 +8615,9 @@
8569
8615
 
8570
8616
  // Update the colspan for the details rows (note, only if it already has
8571
8617
  // a colspan)
8572
- var row, visible = _fnVisbleColumns( ctx );
8618
+ var row, visible = _fnVisibleColumns( ctx );
8573
8619
 
8574
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8620
+ for ( var i=0, iLen=data.length ; i<iLen ; i++ ) {
8575
8621
  row = data[i];
8576
8622
 
8577
8623
  if ( row && row._details ) {
@@ -8592,7 +8638,7 @@
8592
8638
  return;
8593
8639
  }
8594
8640
 
8595
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8641
+ for ( var i=0, iLen=data.length ; i<iLen ; i++ ) {
8596
8642
  if ( data[i] && data[i]._details ) {
8597
8643
  __details_remove( api, i );
8598
8644
  }
@@ -8696,7 +8742,7 @@
8696
8742
  // iterator callback in columns().data()
8697
8743
  var __columnData = function ( settings, column, r1, r2, rows, type ) {
8698
8744
  var a = [];
8699
- for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8745
+ for ( var row=0, iLen=rows.length ; row<iLen ; row++ ) {
8700
8746
  a.push( _fnGetCellData( settings, rows[row], column, type ) );
8701
8747
  }
8702
8748
  return a;
@@ -8896,7 +8942,7 @@
8896
8942
  cols = settings.aoColumns,
8897
8943
  col = cols[ column ],
8898
8944
  data = settings.aoData,
8899
- cells, i, ien, tr;
8945
+ cells, i, iLen, tr;
8900
8946
 
8901
8947
  // Get
8902
8948
  if ( vis === undefined ) {
@@ -8914,7 +8960,7 @@
8914
8960
  // Need to decide if we should use appendChild or insertBefore
8915
8961
  var insertBefore = _pluck(cols, 'bVisible').indexOf(true, column+1);
8916
8962
 
8917
- for ( i=0, ien=data.length ; i<ien ; i++ ) {
8963
+ for ( i=0, iLen=data.length ; i<iLen ; i++ ) {
8918
8964
  if (data[i]) {
8919
8965
  tr = data[i].nTr;
8920
8966
  cells = data[i].anCells;
@@ -9044,13 +9090,16 @@
9044
9090
 
9045
9091
  _api_registerPlural( 'columns().types()', 'column().type()', function () {
9046
9092
  return this.iterator( 'column', function ( settings, column ) {
9047
- var type = settings.aoColumns[column].sType;
9093
+ var colObj = settings.aoColumns[column]
9094
+ var type = colObj.sType;
9048
9095
 
9049
9096
  // If the type was invalidated, then resolve it. This actually does
9050
9097
  // all columns at the moment. Would only happen once if getting all
9051
9098
  // column's data types.
9052
9099
  if (! type) {
9053
9100
  _fnColumnTypes(settings);
9101
+
9102
+ type = colObj.sType;
9054
9103
  }
9055
9104
 
9056
9105
  return type;
@@ -9080,7 +9129,7 @@
9080
9129
  // Update colspan for no records display. Child rows and extensions will use their own
9081
9130
  // listeners to do this - only need to update the empty table item here
9082
9131
  if ( ! settings.aiDisplay.length ) {
9083
- $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
9132
+ $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisibleColumns(settings));
9084
9133
  }
9085
9134
 
9086
9135
  _fnSaveState( settings );
@@ -9166,7 +9215,7 @@
9166
9215
  var allCells = $(_flatten( [], cells ));
9167
9216
  var row;
9168
9217
  var columns = settings.aoColumns.length;
9169
- var a, i, ien, j, o, host;
9218
+ var a, i, iLen, j, o, host;
9170
9219
 
9171
9220
  var run = function ( s ) {
9172
9221
  var fnSelector = typeof s === 'function';
@@ -9175,7 +9224,7 @@
9175
9224
  // All cells and function selectors
9176
9225
  a = [];
9177
9226
 
9178
- for ( i=0, ien=rows.length ; i<ien ; i++ ) {
9227
+ for ( i=0, iLen=rows.length ; i<iLen ; i++ ) {
9179
9228
  row = rows[i];
9180
9229
 
9181
9230
  for ( j=0 ; j<columns ; j++ ) {
@@ -9280,12 +9329,12 @@
9280
9329
  // Row + column selector
9281
9330
  var columns = this.columns( columnSelector, internalOpts );
9282
9331
  var rows = this.rows( rowSelector, internalOpts );
9283
- var i, ien, j, jen;
9332
+ var i, iLen, j, jen;
9284
9333
 
9285
9334
  var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) {
9286
9335
  var a = [];
9287
9336
 
9288
- for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
9337
+ for ( i=0, iLen=rows[idx].length ; i<iLen ; i++ ) {
9289
9338
  for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
9290
9339
  a.push( {
9291
9340
  row: rows[idx][i],
@@ -9497,7 +9546,7 @@
9497
9546
  return this.iterator( 'column', function ( settings, idx ) {
9498
9547
  var sort = _fnSortFlatten( settings );
9499
9548
 
9500
- for ( var i=0, ien=sort.length ; i<ien ; i++ ) {
9549
+ for ( var i=0, iLen=sort.length ; i<iLen ; i++ ) {
9501
9550
  if ( sort[i].col === idx ) {
9502
9551
  return sort[i].dir;
9503
9552
  }
@@ -10188,9 +10237,11 @@
10188
10237
  }
10189
10238
 
10190
10239
  if ( $.isPlainObject( resolved ) ) {
10191
- resolved = plural !== undefined && resolved[ plural ] !== undefined ?
10192
- resolved[ plural ] :
10193
- resolved._;
10240
+ resolved = plural !== undefined && resolved[ plural ] !== undefined
10241
+ ? resolved[ plural ]
10242
+ : plural === false
10243
+ ? resolved
10244
+ : resolved._;
10194
10245
  }
10195
10246
 
10196
10247
  return typeof resolved === 'string'
@@ -10219,7 +10270,7 @@
10219
10270
  * @type string
10220
10271
  * @default Version number
10221
10272
  */
10222
- DataTable.version = "2.3.2";
10273
+ DataTable.version = "2.3.5";
10223
10274
 
10224
10275
  /**
10225
10276
  * Private data store, containing all of the settings objects that are
@@ -10252,7 +10303,7 @@
10252
10303
  */
10253
10304
  DataTable.models.oSearch = {
10254
10305
  /**
10255
- * Flag to indicate if the filtering should be case insensitive or not
10306
+ * Flag to whether or not the filtering should be case-insensitive
10256
10307
  */
10257
10308
  "caseInsensitive": true,
10258
10309
 
@@ -10521,8 +10572,8 @@
10521
10572
  */
10522
10573
  "sWidthOrig": null,
10523
10574
 
10524
- /** Cached string which is the longest in the column */
10525
- maxLenString: null,
10575
+ /** Cached longest strings from a column */
10576
+ wideStrings: null,
10526
10577
 
10527
10578
  /**
10528
10579
  * Store for named searches
@@ -10537,7 +10588,7 @@
10537
10588
  * from v1.10 onwards the primary interface is camel case. In order to avoid
10538
10589
  * breaking backwards compatibility utterly with this change, the Hungarian
10539
10590
  * version is still, internally the primary interface, but is is not documented
10540
- * - hence the @name tags in each doc comment. This allows a Javascript function
10591
+ * - hence the @name tags in each doc comment. This allows a JavaScript function
10541
10592
  * to create a map from Hungarian notation to camel case (going the other direction
10542
10593
  * would require each property to be listed, which would add around 3K to the size
10543
10594
  * of DataTables, while this method is about a 0.5K hit).
@@ -10556,7 +10607,7 @@
10556
10607
  /**
10557
10608
  * An array of data to use for the table, passed in at initialisation which
10558
10609
  * will be used in preference to any data which is already in the DOM. This is
10559
- * particularly useful for constructing tables purely in Javascript, for
10610
+ * particularly useful for constructing tables purely in JavaScript, for
10560
10611
  * example with a custom Ajax call.
10561
10612
  */
10562
10613
  "aaData": null,
@@ -10623,7 +10674,7 @@
10623
10674
  * * `dataSrc` - By default DataTables will look for the property `data` (or
10624
10675
  * `aaData` for compatibility with DataTables 1.9-) when obtaining data
10625
10676
  * from an Ajax source or for server-side processing - this parameter
10626
- * allows that property to be changed. You can use Javascript dotted
10677
+ * allows that property to be changed. You can use JavaScript dotted
10627
10678
  * object notation to get a data source for multiple levels of nesting, or
10628
10679
  * it my be used as a function. As a function it takes a single parameter,
10629
10680
  * the JSON returned from the server, which can be manipulated as
@@ -10747,13 +10798,13 @@
10747
10798
  "bFilter": true,
10748
10799
 
10749
10800
  /**
10750
- * Used only for compatiblity with DT1
10801
+ * Used only for compatibility with DT1
10751
10802
  * @deprecated
10752
10803
  */
10753
10804
  "bInfo": true,
10754
10805
 
10755
10806
  /**
10756
- * Used only for compatiblity with DT1
10807
+ * Used only for compatibility with DT1
10757
10808
  * @deprecated
10758
10809
  */
10759
10810
  "bLengthChange": true,
@@ -10844,7 +10895,7 @@
10844
10895
  * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10845
10896
  * used to save table display information such as pagination information,
10846
10897
  * display length, filtering and sorting. As such when the end user reloads
10847
- * the page the display display will match what thy had previously set up.
10898
+ * the page the display will match what thy had previously set up.
10848
10899
  */
10849
10900
  "bStateSave": false,
10850
10901
 
@@ -11201,7 +11252,7 @@
11201
11252
  /**
11202
11253
  * When using Ajax sourced data and during the first draw when DataTables is
11203
11254
  * gathering the data, this message is shown in an empty row in the table to
11204
- * indicate to the end user the the data is being loaded. Note that this
11255
+ * indicate to the end user the data is being loaded. Note that this
11205
11256
  * parameter is not used when loading data by server-side processing, just
11206
11257
  * Ajax sourced data with client-side processing.
11207
11258
  */
@@ -11462,8 +11513,8 @@
11462
11513
  * * `string` - read an object property from the data source. There are
11463
11514
  * three 'special' options that can be used in the string to alter how
11464
11515
  * DataTables reads the data from the source object:
11465
- * * `.` - Dotted Javascript notation. Just as you use a `.` in
11466
- * Javascript to read from nested objects, so to can the options
11516
+ * * `.` - Dotted JavaScript notation. Just as you use a `.` in
11517
+ * JavaScript to read from nested objects, so to can the options
11467
11518
  * specified in `data`. For example: `browser.version` or
11468
11519
  * `browser.name`. If your object parameter name contains a period, use
11469
11520
  * `\\` to escape it - i.e. `first\\.name`.
@@ -11521,7 +11572,7 @@
11521
11572
  * This property is the rendering partner to `data` and it is suggested that
11522
11573
  * when you want to manipulate data for display (including filtering,
11523
11574
  * sorting etc) without altering the underlying data for the table, use this
11524
- * property. `render` can be considered to be the the read only companion to
11575
+ * property. `render` can be considered to be the read only companion to
11525
11576
  * `data` which is read / write (then as such more complex). Like `data`
11526
11577
  * this option can be given in a number of different ways to effect its
11527
11578
  * behaviour:
@@ -11531,8 +11582,8 @@
11531
11582
  * * `string` - read an object property from the data source. There are
11532
11583
  * three 'special' options that can be used in the string to alter how
11533
11584
  * DataTables reads the data from the source object:
11534
- * * `.` - Dotted Javascript notation. Just as you use a `.` in
11535
- * Javascript to read from nested objects, so to can the options
11585
+ * * `.` - Dotted JavaScript notation. Just as you use a `.` in
11586
+ * JavaScript to read from nested objects, so to can the options
11536
11587
  * specified in `data`. For example: `browser.version` or
11537
11588
  * `browser.name`. If your object parameter name contains a period, use
11538
11589
  * `\\` to escape it - i.e. `first\\.name`.
@@ -11635,7 +11686,7 @@
11635
11686
  * The type allows you to specify how the data for this column will be
11636
11687
  * ordered. Four types (string, numeric, date and html (which will strip
11637
11688
  * HTML tags before ordering)) are currently available. Note that only date
11638
- * formats understood by Javascript's Date() object will be accepted as type
11689
+ * formats understood by JavaScript's Date() object will be accepted as type
11639
11690
  * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
11640
11691
  * 'numeric', 'date' or 'html' (by default). Further types can be adding
11641
11692
  * through plug-ins.
@@ -11687,7 +11738,7 @@
11687
11738
  /**
11688
11739
  * Delay the creation of TR and TD elements until they are actually
11689
11740
  * needed by a driven page draw. This can give a significant speed
11690
- * increase for Ajax source and Javascript source data, but makes no
11741
+ * increase for Ajax source and JavaScript source data, but makes no
11691
11742
  * difference at all for DOM and server-side processing tables.
11692
11743
  * Note that this parameter will be set by the initialisation routine. To
11693
11744
  * set a default use {@link DataTable.defaults}.
@@ -11704,13 +11755,13 @@
11704
11755
  "bFilter": null,
11705
11756
 
11706
11757
  /**
11707
- * Used only for compatiblity with DT1
11758
+ * Used only for compatibility with DT1
11708
11759
  * @deprecated
11709
11760
  */
11710
11761
  "bInfo": true,
11711
11762
 
11712
11763
  /**
11713
- * Used only for compatiblity with DT1
11764
+ * Used only for compatibility with DT1
11714
11765
  * @deprecated
11715
11766
  */
11716
11767
  "bLengthChange": true,
@@ -12581,7 +12632,7 @@
12581
12632
  },
12582
12633
  order: {
12583
12634
  pre: function (d) {
12584
- // The renderer gives us Moment, Luxon or Date obects for the sorting, all of which have a
12635
+ // The renderer gives us Moment, Luxon or Date objects for the sorting, all of which have a
12585
12636
  // `valueOf` which gives milliseconds epoch
12586
12637
  return d.valueOf();
12587
12638
  }
@@ -12636,7 +12687,10 @@
12636
12687
  }
12637
12688
 
12638
12689
  var formatted = to === null
12639
- ? __mld(dt, 'toDate', 'toJSDate', '')[localeString]()
12690
+ ? __mld(dt, 'toDate', 'toJSDate', '')[localeString](
12691
+ navigator.language,
12692
+ { timeZone: "UTC" }
12693
+ )
12640
12694
  : __mld(dt, 'format', 'toFormat', 'toISOString', to);
12641
12695
 
12642
12696
  // XSS protection
@@ -13147,7 +13201,7 @@
13147
13201
 
13148
13202
  // If a decimal place other than `.` is used, it needs to be given to the
13149
13203
  // function so we can detect it and replace with a `.` which is the only
13150
- // decimal place Javascript recognises - it is not locale aware.
13204
+ // decimal place JavaScript recognises - it is not locale aware.
13151
13205
  if ( decimalPlace ) {
13152
13206
  d = _numToDecimal( d, decimalPlace );
13153
13207
  }
@@ -13205,7 +13259,7 @@
13205
13259
  // on destroy, while the `dt` namespaced event is the one we are
13206
13260
  // listening for
13207
13261
  $(settings.nTable).on( 'order.dt.DT column-visibility.dt.DT', function ( e, ctx, column ) {
13208
- if ( settings !== ctx ) { // need to check this this is the host
13262
+ if ( settings !== ctx ) { // need to check if this is the host
13209
13263
  return; // table, not a nested one
13210
13264
  }
13211
13265