bootswatch_rails 3.3.4.1 → 3.3.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2cbfa3cb7ab265d4f1dde548659850109808a60e
4
- data.tar.gz: 4789138b89eb65245c526dd2f4e98c6d152418e5
3
+ metadata.gz: fcf441dece37acb641b61d7e05e90a52c4b838f7
4
+ data.tar.gz: 4349e23a547afbed1af9f5afffd2f8bd11e89776
5
5
  SHA512:
6
- metadata.gz: 40ccc6cc72938f58864787e6e6075941a0b34fdc729e7fb86a8cfdde9458e8c3fb3664309271173da42900ee1a8c699ba6e894d0245a48af16d8f49f5d10fb23
7
- data.tar.gz: 8bb6efba9d0aa62a55980b85daf5b0fa5526956578384b8498c440631981e588b56adf83cec236562c463eaa902303e72c09b6901a61f98982fa6a0c6bce270d
6
+ metadata.gz: 79536b9f9c49b55a1353654a15b290199a1c79b21004a3ebb0b269833bcdde5d3c41b3aaf4f125dbc4f459651846061745bf0cd7727640b0e5ff1dd0bed3c550
7
+ data.tar.gz: 8521c0b3ab49cf00fe97225f256810941b9fd79b60616a5b4e8af19b17bd60391e442845ee1c3714c4a194ee6dfbde3b152d1d9eae3df60adf72270af08713d8
Binary file
data/generate.sh CHANGED
@@ -11,7 +11,15 @@
11
11
  set -e
12
12
 
13
13
  if [ "$1" != "local" ] ; then
14
- git submodule foreach git pull
14
+ if [ -d ../bootswatch ] ; then
15
+ pushd ../bootswatch
16
+ git pull
17
+ popd
18
+ else
19
+ pushd ..
20
+ git clone https://github.com/thomaspark/bootswatch.git
21
+ popd
22
+ fi
15
23
  fi
16
24
 
17
25
  _assets="vendor/assets"
@@ -27,17 +35,17 @@ done
27
35
 
28
36
  _themes_css=""
29
37
  _themes_raw=""
30
- for _file in $(ls -1 bootswatch/*/bootstrap.css) ; do
31
- _file=${_file#bootswatch/}
38
+ for _file in $(ls -1 ../bootswatch/*/bootstrap.css) ; do
39
+ _file=${_file#../bootswatch/}
32
40
  _theme=${_file%/bootstrap.css}
33
- _src="bootswatch/$_file"
41
+ _src="../bootswatch/$_file"
34
42
  _dst="$_assets/stylesheets/$_theme.css"
35
43
  rm -f /tmp/css.tmp
36
44
  sed -e 's#\.\./fonts/#/assets/#g' $_src >/tmp/css.tmp
37
45
  if cmp -s /tmp/css.tmp $_dst ; then
38
46
  rm -f /tmp/css.tmp
39
47
  else
40
- echo "copy: $_theme.css"
48
+ echo "copy1: $_theme.css"
41
49
  mv /tmp/css.tmp $_dst
42
50
  fi
43
51
  if [ -z "$_themes_css" ] ; then
@@ -57,8 +65,8 @@ done
57
65
  ###### Setup DataTables
58
66
  #################################################################################
59
67
 
60
- DT_VER="1.10.6"
61
- DT_RESP="1.0.5"
68
+ DT_VER="1.10.9"
69
+ DT_RESP="1.0.7"
62
70
 
63
71
  if [ "$1" != "local" ] ; then
64
72
  wget -N -P datatables "http://datatables.net/releases/DataTables-$DT_VER.zip"
@@ -70,14 +78,14 @@ unzip -q -d /tmp datatables/DataTables-$DT_VER.zip
70
78
  _src="/tmp/DataTables-$DT_VER/media/js/jquery.dataTables.js"
71
79
  _dst="$_assets/javascripts/jquery.dataTables.js"
72
80
  if ! cmp -s $_src $_dst ; then
73
- echo "copy: jquery.dataTables.js"
81
+ echo "copy2: jquery.dataTables.js"
74
82
  cp $_src $_dst
75
83
  fi
76
84
 
77
85
  _src="/tmp/DataTables-$DT_VER/extensions/Responsive/js/dataTables.responsive.js"
78
86
  _dst="$_assets/javascripts/dataTables.responsive.js"
79
87
  if ! cmp -s $_src $_dst ; then
80
- echo "copy: dataTables.responsive.js"
88
+ echo "copy3: dataTables.responsive.js"
81
89
  cp $_src $_dst
82
90
  fi
83
91
 
@@ -88,21 +96,21 @@ sed -e 's#\.\./images/#/assets/#g' $_src >/tmp/css.tmp
88
96
  if cmp -s /tmp/css.tmp $_dst ; then
89
97
  rm -f /tmp/css.tmp
90
98
  else
91
- echo "copy: jquery.dataTables.css"
99
+ echo "copy4: jquery.dataTables.css"
92
100
  mv /tmp/css.tmp $_dst
93
101
  fi
94
102
 
95
- _src="/tmp/DataTables-$DT_VER/extensions/Responsive/css/dataTables.responsive.css"
96
- _dst="$_assets/stylesheets/dataTables.responsive.css"
103
+ _src="/tmp/DataTables-$DT_VER/extensions/Responsive/css/responsive.dataTables.css"
104
+ _dst="$_assets/stylesheets/responsive.dataTables.css"
97
105
  rm -f /tmp/css.tmp
98
106
  sed -e 's#\.\./images/#/assets/#g' $_src >/tmp/css.tmp
99
107
  if cmp -s /tmp/css.tmp $_dst ; then
100
108
  rm -f /tmp/css.tmp
101
109
  else
102
- echo "copy: dataTables.responsive.css"
110
+ echo "copy5: responsive.dataTables.css"
103
111
  mv /tmp/css.tmp $_dst
104
112
  fi
105
- _themes_css="jquery.dataTables.css dataTables.responsive.css $_themes_css"
113
+ _themes_css="jquery.dataTables.css responsive.dataTables.css $_themes_css"
106
114
 
107
115
 
108
116
  #################################################################################
@@ -114,7 +122,7 @@ for _file in /tmp/DataTables-$DT_VER/media/images/*.png ; do
114
122
  _src="/tmp/DataTables-$DT_VER/media/images/$_file"
115
123
  _dst="$_assets/images/$_file"
116
124
  if ! cmp -s $_src $_dst ; then
117
- echo "copy: $_file"
125
+ echo "copy6: $_file"
118
126
  cp $_src $_dst
119
127
  fi
120
128
  done
@@ -133,7 +141,7 @@ if [ -s $_engine ] ; then
133
141
  if cmp -s /tmp/engine.tmp $_engine ; then
134
142
  rm -f /tmp/engine.tmp
135
143
  else
136
- echo "edit: $_engine"
144
+ echo "edit1: $_engine"
137
145
  mv /tmp/engine.tmp $_engine
138
146
  fi
139
147
  fi
@@ -152,7 +160,7 @@ if [ -s $_version ] ; then
152
160
  if cmp -s /tmp/version.tmp $_version ; then
153
161
  rm -f /tmp/version.tmp
154
162
  else
155
- echo "edit: $_version"
163
+ echo "edit2: $_version"
156
164
  mv /tmp/version.tmp $_version
157
165
  fi
158
166
  fi
@@ -162,12 +170,12 @@ fi
162
170
  ###### Copy font files
163
171
  #################################################################################
164
172
 
165
- for _file in bootswatch/fonts/*.* ; do
173
+ for _file in ../bootswatch/fonts/*.* ; do
166
174
  _file=${_file##*/}
167
- _src="bootswatch/fonts/$_file"
175
+ _src="../bootswatch/fonts/$_file"
168
176
  _dst="$_assets/fonts/$_file"
169
177
  if ! cmp -s $_src $_dst ; then
170
- echo "copy: $_file"
178
+ echo "copy7: $_file"
171
179
  cp $_src $_dst
172
180
  fi
173
181
  done
@@ -184,7 +192,7 @@ if [ -s cleditor/jquery.cleditor.js ] ; then
184
192
  if cmp -s /tmp/cleditor.tmp $_dst ; then
185
193
  rm -f /tmp/cleditor.tmp
186
194
  else
187
- echo "edit: $_dst"
195
+ echo "edit3: $_dst"
188
196
  mv /tmp/cleditor.tmp $_dst
189
197
  fi
190
198
 
@@ -195,7 +203,7 @@ if [ -s cleditor/jquery.cleditor.js ] ; then
195
203
  if cmp -s /tmp/cleditor.tmp $_dst ; then
196
204
  rm -f /tmp/cleditor.tmp
197
205
  else
198
- echo "edit: $_dst"
206
+ echo "edit4: $_dst"
199
207
  mv /tmp/cleditor.tmp $_dst
200
208
  fi
201
209
 
@@ -203,7 +211,7 @@ if [ -s cleditor/jquery.cleditor.js ] ; then
203
211
  for _file in toolbar.gif buttons.gif ; do
204
212
  _src="cleditor/images/$_file"
205
213
  if ! cmp -s $_src $_dir/$_file ; then
206
- echo "copy: $_src"
214
+ echo "copy8: $_src"
207
215
  cp $_src $_dir/$_file
208
216
  fi
209
217
  done
@@ -54,7 +54,7 @@ module BootswatchRails
54
54
  ActiveSupport.on_load(:action_view) do
55
55
  include BootswatchRails::ActionViewExtensions
56
56
  end
57
- app.config.assets.precompile += %w(jquery.dataTables.css dataTables.responsive.css cerulean.css cosmo.css custom.css cyborg.css darkly.css flatly.css journal.css lumen.css paper.css readable.css sandstone.css simplex.css slate.css spacelab.css superhero.css united.css yeti.css)
57
+ app.config.assets.precompile += %w(jquery.dataTables.css responsive.dataTables.css cerulean.css cosmo.css custom.css cyborg.css darkly.css flatly.css journal.css lumen.css paper.css readable.css sandstone.css simplex.css slate.css spacelab.css superhero.css united.css yeti.css)
58
58
  app.config.assets.paths << File.expand_path('../../../vendor/assets/fonts', __FILE__)
59
59
  end
60
60
  end
@@ -1,10 +1,10 @@
1
1
  module BootswatchRails
2
- BOOTSTRAP = "3.3.4"
3
- BOOTSWATCH = "3.3.4"
4
- FONT_AWESOME = "4.3.0"
5
- DATATABLES = "1.10.6"
6
- RESPONSIVE = "1.0.5"
7
- VERSION = "3.3.4.1"
2
+ BOOTSTRAP = "3.3.5"
3
+ BOOTSWATCH = "3.3.5"
4
+ FONT_AWESOME = "4.4.0"
5
+ DATATABLES = "1.10.9"
6
+ RESPONSIVE = "1.0.7"
7
+ VERSION = "3.3.5.1"
8
8
 
9
9
  THEMES = [:cerulean, :cosmo, :custom, :cyborg, :darkly, :flatly, :journal, :lumen, :paper, :readable, :sandstone, :simplex, :slate, :spacelab, :superhero, :united, :yeti]
10
10
  DEFAULT = 0
@@ -1,11 +1,11 @@
1
- /*! Responsive 1.0.5
1
+ /*! Responsive 1.0.7
2
2
  * 2014-2015 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary Responsive
7
7
  * @description Responsive tables plug-in for DataTables
8
- * @version 1.0.5
8
+ * @version 1.0.7
9
9
  * @file dataTables.responsive.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
@@ -646,14 +646,25 @@ Responsive.prototype = {
646
646
  .append( cells )
647
647
  .appendTo( clonedHeader );
648
648
 
649
+ // In the inline case extra padding is applied to the first column to
650
+ // give space for the show / hide icon. We need to use this in the
651
+ // calculation
652
+ if ( this.c.details.type === 'inline' ) {
653
+ $(clonedTable).addClass( 'dtr-inline collapsed' );
654
+ }
655
+
649
656
  var inserted = $('<div/>')
650
657
  .css( {
651
658
  width: 1,
652
659
  height: 1,
653
660
  overflow: 'hidden'
654
661
  } )
655
- .append( clonedTable )
656
- .insertBefore( dt.table().node() );
662
+ .append( clonedTable );
663
+
664
+ // Remove columns which are not to be included
665
+ inserted.find('th.never, td.never').remove();
666
+
667
+ inserted.insertBefore( dt.table().node() );
657
668
 
658
669
  // The cloned header now contains the smallest that each column can be
659
670
  dt.columns().eq(0).each( function ( idx ) {
@@ -815,7 +826,7 @@ Api.register( 'responsive.recalc()', function () {
815
826
  * @name Responsive.version
816
827
  * @static
817
828
  */
818
- Responsive.version = '1.0.5';
829
+ Responsive.version = '1.0.7';
819
830
 
820
831
 
821
832
  $.fn.dataTable.Responsive = Responsive;
@@ -833,8 +844,6 @@ $(document).on( 'init.dt.dtr', function (e, settings, json) {
833
844
  settings.oInit.responsive ||
834
845
  DataTable.defaults.responsive
835
846
  ) {
836
- console.log( e.namespace );
837
-
838
847
  var init = settings.oInit.responsive;
839
848
 
840
849
  if ( init !== false ) {
@@ -1,15 +1,15 @@
1
- /*! DataTables 1.10.6
2
- * ©2008-2014 SpryMedia Ltd - datatables.net/license
1
+ /*! DataTables 1.10.9
2
+ * ©2008-2015 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary DataTables
7
7
  * @description Paginate, search and order HTML tables
8
- * @version 1.10.6
8
+ * @version 1.10.9
9
9
  * @file jquery.dataTables.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
12
- * @copyright Copyright 2008-2014 SpryMedia Ltd.
12
+ * @copyright Copyright 2008-2015 SpryMedia Ltd.
13
13
  *
14
14
  * This source file is free software, available under the following license:
15
15
  * MIT license - http://datatables.net/license
@@ -22,7 +22,7 @@
22
22
  */
23
23
 
24
24
  /*jslint evil: true, undef: true, browser: true */
25
- /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
25
+ /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
26
26
 
27
27
  (/** @lends <global> */function( window, document, undefined ) {
28
28
 
@@ -33,10 +33,10 @@
33
33
  // Define as an AMD module if possible
34
34
  define( 'datatables', ['jquery'], factory );
35
35
  }
36
- else if ( typeof exports === 'object' ) {
37
- // Node/CommonJS
38
- module.exports = factory( require( 'jquery' ) );
39
- }
36
+ else if ( typeof exports === 'object' ) {
37
+ // Node/CommonJS
38
+ module.exports = factory( require( 'jquery' ) );
39
+ }
40
40
  else if ( jQuery && !jQuery.fn.dataTable ) {
41
41
  // Define using browser globals otherwise
42
42
  // Prevent multiple instantiations if the script is loaded twice
@@ -467,6 +467,11 @@
467
467
  _fnCompatMap( init, 'pageLength', 'iDisplayLength' );
468
468
  _fnCompatMap( init, 'searching', 'bFilter' );
469
469
 
470
+ // Boolean initialisation of x-scrolling
471
+ if ( typeof init.sScrollX === 'boolean' ) {
472
+ init.sScrollX = init.sScrollX ? '100%' : '';
473
+ }
474
+
470
475
  // Column search objects are in an array, so it needs to be converted
471
476
  // element by element
472
477
  var searchCols = init.aoSearchCols;
@@ -509,49 +514,76 @@
509
514
  */
510
515
  function _fnBrowserDetect( settings )
511
516
  {
512
- var browser = settings.oBrowser;
517
+ // We don't need to do this every time DataTables is constructed, the values
518
+ // calculated are specific to the browser and OS configuration which we
519
+ // don't expect to change between initialisations
520
+ if ( ! DataTable.__browser ) {
521
+ var browser = {};
522
+ DataTable.__browser = browser;
523
+
524
+ // Scrolling feature / quirks detection
525
+ var n = $('<div/>')
526
+ .css( {
527
+ position: 'fixed',
528
+ top: 0,
529
+ left: 0,
530
+ height: 1,
531
+ width: 1,
532
+ overflow: 'hidden'
533
+ } )
534
+ .append(
535
+ $('<div/>')
536
+ .css( {
537
+ position: 'absolute',
538
+ top: 1,
539
+ left: 1,
540
+ width: 100,
541
+ overflow: 'scroll'
542
+ } )
543
+ .append(
544
+ $('<div/>')
545
+ .css( {
546
+ width: '100%',
547
+ height: 10
548
+ } )
549
+ )
550
+ )
551
+ .appendTo( 'body' );
513
552
 
514
- // Scrolling feature / quirks detection
515
- var n = $('<div/>')
516
- .css( {
517
- position: 'absolute',
518
- top: 0,
519
- left: 0,
520
- height: 1,
521
- width: 1,
522
- overflow: 'hidden'
523
- } )
524
- .append(
525
- $('<div/>')
526
- .css( {
527
- position: 'absolute',
528
- top: 1,
529
- left: 1,
530
- width: 100,
531
- overflow: 'scroll'
532
- } )
533
- .append(
534
- $('<div class="test"/>')
535
- .css( {
536
- width: '100%',
537
- height: 10
538
- } )
539
- )
540
- )
541
- .appendTo( 'body' );
553
+ var outer = n.children();
554
+ var inner = outer.children();
542
555
 
543
- var test = n.find('.test');
556
+ // Numbers below, in order, are:
557
+ // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
558
+ //
559
+ // IE6 XP: 100 100 100 83
560
+ // IE7 Vista: 100 100 100 83
561
+ // IE 8+ Windows: 83 83 100 83
562
+ // Evergreen Windows: 83 83 100 83
563
+ // Evergreen Mac with scrollbars: 85 85 100 85
564
+ // Evergreen Mac without scrollbars: 100 100 100 100
544
565
 
545
- // IE6/7 will oversize a width 100% element inside a scrolling element, to
546
- // include the width of the scrollbar, while other browsers ensure the inner
547
- // element is contained without forcing scrolling
548
- browser.bScrollOversize = test[0].offsetWidth === 100;
566
+ // Get scrollbar width
567
+ browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
549
568
 
550
- // In rtl text layout, some browsers (most, but not all) will place the
551
- // scrollbar on the left, rather than the right.
552
- browser.bScrollbarLeft = Math.round( test.offset().left ) !== 1;
569
+ // IE6/7 will oversize a width 100% element inside a scrolling element, to
570
+ // include the width of the scrollbar, while other browsers ensure the inner
571
+ // element is contained without forcing scrolling
572
+ //console.log( inner.offsetWidth );
573
+ browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
553
574
 
554
- n.remove();
575
+ // In rtl text layout, some browsers (most, but not all) will place the
576
+ // scrollbar on the left, rather than the right.
577
+ browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
578
+
579
+ // IE8- don't provide height and width for getBoundingClientRect
580
+ browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
581
+
582
+ n.remove();
583
+ }
584
+
585
+ $.extend( settings.oBrowser, DataTable.__browser );
586
+ settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
555
587
  }
556
588
 
557
589
 
@@ -1008,7 +1040,8 @@
1008
1040
  /* Create the object for storing information about this new row */
1009
1041
  var iRow = oSettings.aoData.length;
1010
1042
  var oData = $.extend( true, {}, DataTable.models.oRow, {
1011
- src: nTr ? 'dom' : 'data'
1043
+ src: nTr ? 'dom' : 'data',
1044
+ idx: iRow
1012
1045
  } );
1013
1046
 
1014
1047
  oData._aData = aDataIn;
@@ -1017,20 +1050,21 @@
1017
1050
  /* Create the cells */
1018
1051
  var nTd, sThisType;
1019
1052
  var columns = oSettings.aoColumns;
1053
+
1054
+ // Invalidate the column types as the new data needs to be revalidated
1020
1055
  for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
1021
1056
  {
1022
- // When working with a row, the data source object must be populated. In
1023
- // all other cases, the data source object is already populated, so we
1024
- // don't overwrite it, which might break bindings etc
1025
- if ( nTr ) {
1026
- _fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
1027
- }
1028
1057
  columns[i].sType = null;
1029
1058
  }
1030
1059
 
1031
1060
  /* Add to the display array */
1032
1061
  oSettings.aiDisplayMaster.push( iRow );
1033
1062
 
1063
+ var id = oSettings.rowIdFn( aDataIn );
1064
+ if ( id !== undefined ) {
1065
+ oSettings.aIds[ id ] = oData;
1066
+ }
1067
+
1034
1068
  /* Create the DOM information, or register it if already present */
1035
1069
  if ( nTr || ! oSettings.oFeatures.bDeferRender )
1036
1070
  {
@@ -1174,7 +1208,7 @@
1174
1208
  */
1175
1209
  function _fnSplitObjNotation( str )
1176
1210
  {
1177
- return $.map( str.match(/(\\.|[^\.])+/g), function ( s ) {
1211
+ return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
1178
1212
  return s.replace(/\\./g, '.');
1179
1213
  } );
1180
1214
  }
@@ -1257,8 +1291,10 @@
1257
1291
  innerSrc = a.join('.');
1258
1292
 
1259
1293
  // Traverse each entry in the array getting the properties requested
1260
- for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
1261
- out.push( fetchData( data[j], type, innerSrc ) );
1294
+ if ( $.isArray( data ) ) {
1295
+ for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
1296
+ out.push( fetchData( data[j], type, innerSrc ) );
1297
+ }
1262
1298
  }
1263
1299
 
1264
1300
  // If a string is given in between the array notation indicators, that
@@ -1358,11 +1394,21 @@
1358
1394
  innerSrc = b.join('.');
1359
1395
 
1360
1396
  // Traverse each entry in the array setting the properties requested
1361
- for ( var j=0, jLen=val.length ; j<jLen ; j++ )
1397
+ if ( $.isArray( val ) )
1398
+ {
1399
+ for ( var j=0, jLen=val.length ; j<jLen ; j++ )
1400
+ {
1401
+ o = {};
1402
+ setData( o, val[j], innerSrc );
1403
+ data[ a[i] ].push( o );
1404
+ }
1405
+ }
1406
+ else
1362
1407
  {
1363
- o = {};
1364
- setData( o, val[j], innerSrc );
1365
- data[ a[i] ].push( o );
1408
+ // We've been asked to save data to an array, but it
1409
+ // isn't array data to be saved. Best that can be done
1410
+ // is to just save the value.
1411
+ data[ a[i] ] = val;
1366
1412
  }
1367
1413
 
1368
1414
  // The inner call to setData has already traversed through the remainder
@@ -1435,6 +1481,7 @@
1435
1481
  settings.aoData.length = 0;
1436
1482
  settings.aiDisplayMaster.length = 0;
1437
1483
  settings.aiDisplay.length = 0;
1484
+ settings.aIds = {};
1438
1485
  }
1439
1486
 
1440
1487
 
@@ -1540,7 +1587,7 @@
1540
1587
  }
1541
1588
 
1542
1589
  // Update DataTables special `DT_*` attributes for the row
1543
- _fnRowAttributes( row );
1590
+ _fnRowAttributes( settings, row );
1544
1591
  }
1545
1592
  }
1546
1593
 
@@ -1572,7 +1619,11 @@
1572
1619
  objectRead = settings._rowReadObject;
1573
1620
 
1574
1621
  // Allow the data object to be passed in, or construct
1575
- d = d || objectRead ? {} : [];
1622
+ d = d !== undefined ?
1623
+ d :
1624
+ objectRead ?
1625
+ {} :
1626
+ [];
1576
1627
 
1577
1628
  var attr = function ( str, td ) {
1578
1629
  if ( typeof str === 'string' ) {
@@ -1635,12 +1686,23 @@
1635
1686
  else {
1636
1687
  // Existing row object passed in
1637
1688
  tds = row.anCells;
1638
-
1689
+
1639
1690
  for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
1640
1691
  cellProcess( tds[j] );
1641
1692
  }
1642
1693
  }
1643
1694
 
1695
+ // Read the ID from the DOM if present
1696
+ var rowNode = td ? row : row.nTr;
1697
+
1698
+ if ( rowNode ) {
1699
+ var id = rowNode.getAttribute( 'id' );
1700
+
1701
+ if ( id ) {
1702
+ _fnSetObjectDataFn( settings.rowId )( d, id );
1703
+ }
1704
+ }
1705
+
1644
1706
  return {
1645
1707
  data: d,
1646
1708
  cells: tds
@@ -1678,7 +1740,7 @@
1678
1740
  nTr._DT_RowIndex = iRow;
1679
1741
 
1680
1742
  /* Special parameters can be given by the data source to be used on the row */
1681
- _fnRowAttributes( row );
1743
+ _fnRowAttributes( oSettings, row );
1682
1744
 
1683
1745
  /* Process each column */
1684
1746
  for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
@@ -1730,17 +1792,20 @@
1730
1792
  /**
1731
1793
  * Add attributes to a row based on the special `DT_*` parameters in a data
1732
1794
  * source object.
1795
+ * @param {object} settings DataTables settings object
1733
1796
  * @param {object} DataTables row object for the row to be modified
1734
1797
  * @memberof DataTable#oApi
1735
1798
  */
1736
- function _fnRowAttributes( row )
1799
+ function _fnRowAttributes( settings, row )
1737
1800
  {
1738
1801
  var tr = row.nTr;
1739
1802
  var data = row._aData;
1740
1803
 
1741
1804
  if ( tr ) {
1742
- if ( data.DT_RowId ) {
1743
- tr.id = data.DT_RowId;
1805
+ var id = settings.rowIdFn( data );
1806
+
1807
+ if ( id ) {
1808
+ tr.id = id;
1744
1809
  }
1745
1810
 
1746
1811
  if ( data.DT_RowClass ) {
@@ -1805,7 +1870,7 @@
1805
1870
  }
1806
1871
  }
1807
1872
 
1808
- if ( column.sTitle != cell.html() ) {
1873
+ if ( column.sTitle != cell[0].innerHTML ) {
1809
1874
  cell.html( column.sTitle );
1810
1875
  }
1811
1876
 
@@ -2277,6 +2342,7 @@
2277
2342
 
2278
2343
  /* Built our DOM structure - replace the holding div with what we want */
2279
2344
  holding.replaceWith( insert );
2345
+ oSettings.nHolding = null;
2280
2346
  }
2281
2347
 
2282
2348
 
@@ -2435,7 +2501,7 @@
2435
2501
  var ajax = oSettings.ajax;
2436
2502
  var instance = oSettings.oInstance;
2437
2503
  var callback = function ( json ) {
2438
- _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json] );
2504
+ _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
2439
2505
  fn( json );
2440
2506
  };
2441
2507
 
@@ -2462,7 +2528,7 @@
2462
2528
  "success": function (json) {
2463
2529
  var error = json.error || json.sError;
2464
2530
  if ( error ) {
2465
- oSettings.oApi._fnLog( oSettings, 0, error );
2531
+ _fnLog( oSettings, 0, error );
2466
2532
  }
2467
2533
 
2468
2534
  oSettings.json = json;
@@ -2472,13 +2538,15 @@
2472
2538
  "cache": false,
2473
2539
  "type": oSettings.sServerMethod,
2474
2540
  "error": function (xhr, error, thrown) {
2475
- var log = oSettings.oApi._fnLog;
2541
+ var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
2476
2542
 
2477
- if ( error == "parsererror" ) {
2478
- log( oSettings, 0, 'Invalid JSON response', 1 );
2479
- }
2480
- else if ( xhr.readyState === 4 ) {
2481
- log( oSettings, 0, 'Ajax error', 7 );
2543
+ if ( $.inArray( true, ret ) === -1 ) {
2544
+ if ( error == "parsererror" ) {
2545
+ _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
2546
+ }
2547
+ else if ( xhr.readyState === 4 ) {
2548
+ _fnLog( oSettings, 0, 'Ajax error', 7 );
2549
+ }
2482
2550
  }
2483
2551
 
2484
2552
  _fnProcessingDisplay( oSettings, false );
@@ -2907,7 +2975,7 @@
2907
2975
  // So the array reference doesn't break set the results into the
2908
2976
  // existing array
2909
2977
  displayRows.length = 0;
2910
- displayRows.push.apply( displayRows, rows );
2978
+ $.merge( displayRows, rows );
2911
2979
  }
2912
2980
  }
2913
2981
 
@@ -3018,7 +3086,7 @@
3018
3086
  *
3019
3087
  * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
3020
3088
  */
3021
- var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || '', function ( word ) {
3089
+ var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
3022
3090
  if ( word.charAt(0) === '"' ) {
3023
3091
  var m = word.match( /^"(.*)"$/ );
3024
3092
  word = m ? m[1] : word;
@@ -3263,6 +3331,7 @@
3263
3331
  var i, iLen, iAjaxStart=settings.iInitDisplayStart;
3264
3332
  var columns = settings.aoColumns, column;
3265
3333
  var features = settings.oFeatures;
3334
+ var deferLoading = settings.bDeferLoading; // value modified by the draw
3266
3335
 
3267
3336
  /* Ensure that the table data is fully initialised */
3268
3337
  if ( ! settings.bInitialised ) {
@@ -3294,6 +3363,8 @@
3294
3363
  }
3295
3364
  }
3296
3365
 
3366
+ _fnCallbackFire( settings, null, 'preInit', [settings] );
3367
+
3297
3368
  // If there is default sorting required - let's do it. The sort function
3298
3369
  // will do the drawing for us. Otherwise we draw the table regardless of the
3299
3370
  // Ajax source - this allows the table to look initialised for Ajax sourcing
@@ -3302,7 +3373,7 @@
3302
3373
 
3303
3374
  // Server-side processing init complete is done by _fnAjaxUpdateDraw
3304
3375
  var dataSrc = _fnDataSource( settings );
3305
- if ( dataSrc != 'ssp' ) {
3376
+ if ( dataSrc != 'ssp' || deferLoading ) {
3306
3377
  // if there is an ajax source load the data
3307
3378
  if ( dataSrc == 'ajax' ) {
3308
3379
  _fnBuildAjax( settings, [], function(json) {
@@ -3343,9 +3414,9 @@
3343
3414
  {
3344
3415
  settings._bInitComplete = true;
3345
3416
 
3346
- // On an Ajax load we now have data and therefore want to apply the column
3347
- // sizing
3348
- if ( json ) {
3417
+ // When data was added after the initialisation (data or Ajax) we need to
3418
+ // calculate the column sizing
3419
+ if ( json || settings.oInit.aaData ) {
3349
3420
  _fnAdjustColumnSizing( settings );
3350
3421
  }
3351
3422
 
@@ -3685,8 +3756,8 @@
3685
3756
  .append(
3686
3757
  $(_div, { 'class': classes.sScrollBody } )
3687
3758
  .css( {
3759
+ position: 'relative',
3688
3760
  overflow: 'auto',
3689
- height: size( scrollY ),
3690
3761
  width: size( scrollX )
3691
3762
  } )
3692
3763
  .append( table )
@@ -3733,6 +3804,11 @@
3733
3804
  } );
3734
3805
  }
3735
3806
 
3807
+ $(scrollBody).css(
3808
+ scrollY && scroll.bCollapse ? 'max-height' : 'height',
3809
+ scrollY
3810
+ );
3811
+
3736
3812
  settings.nScrollHead = scrollHead;
3737
3813
  settings.nScrollBody = scrollBody;
3738
3814
  settings.nScrollFoot = scrollFoot;
@@ -3849,13 +3925,6 @@
3849
3925
  }, footerSrcEls );
3850
3926
  }
3851
3927
 
3852
- // If scroll collapse is enabled, when we put the headers back into the body for sizing, we
3853
- // will end up forcing the scrollbar to appear, making our measurements wrong for when we
3854
- // then hide it (end of this function), so add the header height to the body scroller.
3855
- if ( scroll.bCollapse && scrollY !== "" ) {
3856
- divBodyStyle.height = (divBody[0].offsetHeight + header[0].offsetHeight)+"px";
3857
- }
3858
-
3859
3928
  // Size the table as a whole
3860
3929
  sanityWidth = table.outerWidth();
3861
3930
  if ( scrollX === "" ) {
@@ -3870,32 +3939,17 @@
3870
3939
  ) {
3871
3940
  tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
3872
3941
  }
3942
+
3943
+ // Recalculate the sanity width
3944
+ sanityWidth = table.outerWidth();
3873
3945
  }
3874
- else
3875
- {
3876
- // x scrolling
3877
- if ( scrollXInner !== "" ) {
3878
- // x scroll inner has been given - use it
3879
- tableStyle.width = _fnStringToCss(scrollXInner);
3880
- }
3881
- else if ( sanityWidth == divBody.width() && divBody.height() < table.height() ) {
3882
- // There is y-scrolling - try to take account of the y scroll bar
3883
- tableStyle.width = _fnStringToCss( sanityWidth-barWidth );
3884
- if ( table.outerWidth() > sanityWidth-barWidth ) {
3885
- // Not possible to take account of it
3886
- tableStyle.width = _fnStringToCss( sanityWidth );
3887
- }
3888
- }
3889
- else {
3890
- // When all else fails
3891
- tableStyle.width = _fnStringToCss( sanityWidth );
3892
- }
3893
- }
3946
+ else if ( scrollXInner !== "" ) {
3947
+ // legacy x scroll inner has been given - use it
3948
+ tableStyle.width = _fnStringToCss(scrollXInner);
3894
3949
 
3895
- // Recalculate the sanity width - now that we've applied the required width,
3896
- // before it was a temporary variable. This is required because the column
3897
- // width calculation is done before this table DOM is created.
3898
- sanityWidth = table.outerWidth();
3950
+ // Recalculate the sanity width
3951
+ sanityWidth = table.outerWidth();
3952
+ }
3899
3953
 
3900
3954
  // Hidden header should have zero height, so remove padding and borders. Then
3901
3955
  // set the width based on the real headers
@@ -4003,18 +4057,6 @@
4003
4057
  }
4004
4058
  }
4005
4059
 
4006
- if ( scrollY && scroll.bCollapse ) {
4007
- divBodyStyle.height = _fnStringToCss( scrollY );
4008
-
4009
- var iExtra = (scrollX && tableEl.offsetWidth > divBodyEl.offsetWidth) ?
4010
- barWidth :
4011
- 0;
4012
-
4013
- if ( tableEl.offsetHeight < divBodyEl.offsetHeight ) {
4014
- divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+iExtra );
4015
- }
4016
- }
4017
-
4018
4060
  /* Finally set the width's of the header and footer tables */
4019
4061
  var iOuterWidth = table.outerWidth();
4020
4062
  divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
@@ -4106,7 +4148,9 @@
4106
4148
  tableWidthAttr = table.getAttribute('width'), // from DOM element
4107
4149
  tableContainer = table.parentNode,
4108
4150
  userInputs = false,
4109
- i, column, columnIdx, width, outerWidth;
4151
+ i, column, columnIdx, width, outerWidth,
4152
+ browser = oSettings.oBrowser,
4153
+ ie67 = browser.bScrollOversize;
4110
4154
 
4111
4155
  var styleWidth = table.style.width;
4112
4156
  if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
@@ -4129,32 +4173,43 @@
4129
4173
  * the web- browser. No custom sizes can be set in order for this to happen,
4130
4174
  * nor scrolling used
4131
4175
  */
4132
- if ( ! userInputs && ! scrollX && ! scrollY &&
4133
- columnCount == _fnVisbleColumns( oSettings ) &&
4134
- columnCount == headerCells.length
4176
+ if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
4177
+ columnCount == _fnVisbleColumns( oSettings ) &&
4178
+ columnCount == headerCells.length
4135
4179
  ) {
4136
4180
  for ( i=0 ; i<columnCount ; i++ ) {
4137
- columns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );
4181
+ var colIdx = _fnVisibleToColumnIndex( oSettings, i );
4182
+
4183
+ if ( colIdx ) {
4184
+ columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
4185
+ }
4138
4186
  }
4139
4187
  }
4140
4188
  else
4141
4189
  {
4142
- // Otherwise construct a single row table with the widest node in the
4143
- // data, assign any user defined widths, then insert it into the DOM and
4144
- // allow the browser to do all the hard work of calculating table widths
4190
+ // Otherwise construct a single row, worst case, table with the widest
4191
+ // node in the data, assign any user defined widths, then insert it into
4192
+ // the DOM and allow the browser to do all the hard work of calculating
4193
+ // table widths
4145
4194
  var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
4146
- .empty()
4147
4195
  .css( 'visibility', 'hidden' )
4148
- .removeAttr( 'id' )
4149
- .append( $(oSettings.nTHead).clone( false ) )
4150
- .append( $(oSettings.nTFoot).clone( false ) )
4151
- .append( $('<tbody><tr/></tbody>') );
4196
+ .removeAttr( 'id' );
4197
+
4198
+ // Clean up the table body
4199
+ tmpTable.find('tbody tr').remove();
4200
+ var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
4201
+
4202
+ // Clone the table header and footer - we can't use the header / footer
4203
+ // from the cloned table, since if scrolling is active, the table's
4204
+ // real header and footer are contained in different table tags
4205
+ tmpTable.find('thead, tfoot').remove();
4206
+ tmpTable
4207
+ .append( $(oSettings.nTHead).clone() )
4208
+ .append( $(oSettings.nTFoot).clone() );
4152
4209
 
4153
4210
  // Remove any assigned widths from the footer (from scrolling)
4154
4211
  tmpTable.find('tfoot th, tfoot td').css('width', '');
4155
4212
 
4156
- var tr = tmpTable.find( 'tbody tr' );
4157
-
4158
4213
  // Apply custom sizing to the cloned header
4159
4214
  headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
4160
4215
 
@@ -4179,8 +4234,24 @@
4179
4234
  }
4180
4235
  }
4181
4236
 
4182
- // Table has been built, attach to the document so we can work with it
4183
- tmpTable.appendTo( tableContainer );
4237
+ // Table has been built, attach to the document so we can work with it.
4238
+ // A holding element is used, positioned at the top of the container
4239
+ // with minimal height, so it has no effect on if the container scrolls
4240
+ // or not. Otherwise it might trigger scrolling when it actually isn't
4241
+ // needed
4242
+ var holder = $('<div/>').css( scrollX || scrollY ?
4243
+ {
4244
+ position: 'absolute',
4245
+ top: 0,
4246
+ left: 0,
4247
+ height: 1,
4248
+ right: 0,
4249
+ overflow: 'hidden'
4250
+ } :
4251
+ {}
4252
+ )
4253
+ .append( tmpTable )
4254
+ .appendTo( tableContainer );
4184
4255
 
4185
4256
  // When scrolling (X or Y) we want to set the width of the table as
4186
4257
  // appropriate. However, when not scrolling leave the table width as it
@@ -4191,20 +4262,17 @@
4191
4262
  else if ( scrollX ) {
4192
4263
  tmpTable.css( 'width', 'auto' );
4193
4264
 
4194
- if ( tmpTable.width() < tableContainer.offsetWidth ) {
4195
- tmpTable.width( tableContainer.offsetWidth );
4265
+ if ( tmpTable.width() < tableContainer.clientWidth ) {
4266
+ tmpTable.width( tableContainer.clientWidth );
4196
4267
  }
4197
4268
  }
4198
4269
  else if ( scrollY ) {
4199
- tmpTable.width( tableContainer.offsetWidth );
4270
+ tmpTable.width( tableContainer.clientWidth );
4200
4271
  }
4201
4272
  else if ( tableWidthAttr ) {
4202
4273
  tmpTable.width( tableWidthAttr );
4203
4274
  }
4204
4275
 
4205
- // Take into account the y scrollbar
4206
- _fnScrollingWidthAdjust( oSettings, tmpTable[0] );
4207
-
4208
4276
  // Browsers need a bit of a hand when a width is assigned to any columns
4209
4277
  // when x-scrolling as they tend to collapse the table to the min-width,
4210
4278
  // even if we sent the column widths. So we need to keep track of what
@@ -4216,7 +4284,12 @@
4216
4284
 
4217
4285
  for ( i=0 ; i<visibleColumns.length ; i++ ) {
4218
4286
  column = columns[ visibleColumns[i] ];
4219
- outerWidth = $(headerCells[i]).outerWidth();
4287
+
4288
+ // Much prefer to use getBoundingClientRect due to its sub-pixel
4289
+ // resolution, but IE8- do not support the width property.
4290
+ outerWidth = browser.bBounding ?
4291
+ headerCells[i].getBoundingClientRect().width :
4292
+ $(headerCells[i]).outerWidth();
4220
4293
 
4221
4294
  total += column.sWidthOrig === null ?
4222
4295
  outerWidth :
@@ -4240,7 +4313,7 @@
4240
4313
  table.style.width = _fnStringToCss( tmpTable.css('width') );
4241
4314
 
4242
4315
  // Finished with the table - ditch it
4243
- tmpTable.remove();
4316
+ holder.remove();
4244
4317
  }
4245
4318
 
4246
4319
  // If there is a width attr, we want to attach an event listener which
@@ -4252,9 +4325,20 @@
4252
4325
  }
4253
4326
 
4254
4327
  if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
4255
- $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
4256
- _fnAdjustColumnSizing( oSettings );
4257
- } ) );
4328
+ var bindResize = function () {
4329
+ $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
4330
+ _fnAdjustColumnSizing( oSettings );
4331
+ } ) );
4332
+ };
4333
+
4334
+ // IE6/7 will crash if we bind a resize event handler on page load.
4335
+ // To be removed in 1.11 which drops IE6/7 support
4336
+ if ( ie67 ) {
4337
+ setTimeout( bindResize, 1000 );
4338
+ }
4339
+ else {
4340
+ bindResize();
4341
+ }
4258
4342
 
4259
4343
  oSettings._reszEvt = true;
4260
4344
  }
@@ -4321,27 +4405,6 @@
4321
4405
  }
4322
4406
 
4323
4407
 
4324
- /**
4325
- * Adjust a table's width to take account of vertical scroll bar
4326
- * @param {object} oSettings dataTables settings object
4327
- * @param {node} n table node
4328
- * @memberof DataTable#oApi
4329
- */
4330
-
4331
- function _fnScrollingWidthAdjust ( settings, n )
4332
- {
4333
- var scroll = settings.oScroll;
4334
-
4335
- if ( scroll.sX || scroll.sY ) {
4336
- // When y-scrolling only, we want to remove the width of the scroll bar
4337
- // so the table + scroll bar will fit into the area available, otherwise
4338
- // we fix the table at its current size with no adjustment
4339
- var correction = ! scroll.sX ? scroll.iBarWidth : 0;
4340
- n.style.width = _fnStringToCss( $(n).outerWidth() - correction );
4341
- }
4342
- }
4343
-
4344
-
4345
4408
  /**
4346
4409
  * Get the widest node
4347
4410
  * @param {object} settings dataTables settings object
@@ -4413,40 +4476,6 @@
4413
4476
  }
4414
4477
 
4415
4478
 
4416
- /**
4417
- * Get the width of a scroll bar in this browser being used
4418
- * @returns {int} width in pixels
4419
- * @memberof DataTable#oApi
4420
- */
4421
- function _fnScrollBarWidth ()
4422
- {
4423
- // On first run a static variable is set, since this is only needed once.
4424
- // Subsequent runs will just use the previously calculated value
4425
- var width = DataTable.__scrollbarWidth;
4426
-
4427
- if ( width === undefined ) {
4428
- var sizer = $('<p/>').css( {
4429
- position: 'absolute',
4430
- top: 0,
4431
- left: 0,
4432
- width: '100%',
4433
- height: 150,
4434
- padding: 0,
4435
- overflow: 'scroll',
4436
- visibility: 'hidden'
4437
- } )
4438
- .appendTo('body');
4439
-
4440
- width = sizer[0].offsetWidth - sizer[0].clientWidth;
4441
- DataTable.__scrollbarWidth = width;
4442
-
4443
- sizer.remove();
4444
- }
4445
-
4446
- return width;
4447
- }
4448
-
4449
-
4450
4479
 
4451
4480
  function _fnSortFlatten ( settings )
4452
4481
  {
@@ -4466,7 +4495,7 @@
4466
4495
  }
4467
4496
  else {
4468
4497
  // 2D array
4469
- nestedSort.push.apply( nestedSort, a );
4498
+ $.merge( nestedSort, a );
4470
4499
  }
4471
4500
  };
4472
4501
 
@@ -5043,7 +5072,7 @@
5043
5072
  function _fnLog( settings, level, msg, tn )
5044
5073
  {
5045
5074
  msg = 'DataTables warning: '+
5046
- (settings!==null ? 'table id='+settings.sTableId+' - ' : '')+msg;
5075
+ (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
5047
5076
 
5048
5077
  if ( tn ) {
5049
5078
  msg += '. For more information about this error, please see '+
@@ -5055,7 +5084,9 @@
5055
5084
  var ext = DataTable.ext;
5056
5085
  var type = ext.sErrMode || ext.errMode;
5057
5086
 
5058
- _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
5087
+ if ( settings ) {
5088
+ _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
5089
+ }
5059
5090
 
5060
5091
  if ( type == 'alert' ) {
5061
5092
  alert( msg );
@@ -5208,13 +5239,13 @@
5208
5239
  * @param {object} settings dataTables settings object
5209
5240
  * @param {string} callbackArr Name of the array storage for the callbacks in
5210
5241
  * oSettings
5211
- * @param {string} event Name of the jQuery custom event to trigger. If null no
5212
- * trigger is fired
5242
+ * @param {string} eventName Name of the jQuery custom event to trigger. If
5243
+ * null no trigger is fired
5213
5244
  * @param {array} args Array of arguments to pass to the callback function /
5214
5245
  * trigger
5215
5246
  * @memberof DataTable#oApi
5216
5247
  */
5217
- function _fnCallbackFire( settings, callbackArr, e, args )
5248
+ function _fnCallbackFire( settings, callbackArr, eventName, args )
5218
5249
  {
5219
5250
  var ret = [];
5220
5251
 
@@ -5224,8 +5255,12 @@
5224
5255
  } );
5225
5256
  }
5226
5257
 
5227
- if ( e !== null ) {
5228
- $(settings.nTable).trigger( e+'.dt', args );
5258
+ if ( eventName !== null ) {
5259
+ var e = $.Event( eventName+'.dt' );
5260
+
5261
+ $(settings.nTable).trigger( e, args );
5262
+
5263
+ ret.push( e.result );
5229
5264
  }
5230
5265
 
5231
5266
  return ret;
@@ -6226,6 +6261,7 @@
6226
6261
  "fnStateSaveCallback",
6227
6262
  "renderer",
6228
6263
  "searchDelay",
6264
+ "rowId",
6229
6265
  [ "iCookieDuration", "iStateDuration" ], // backwards compat
6230
6266
  [ "oSearch", "oPreviousSearch" ],
6231
6267
  [ "aoSearchCols", "aoPreSearchCols" ],
@@ -6253,6 +6289,11 @@
6253
6289
  _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
6254
6290
  _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
6255
6291
 
6292
+ oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
6293
+
6294
+ /* Browser support detection */
6295
+ _fnBrowserDetect( oSettings );
6296
+
6256
6297
  var oClasses = oSettings.oClasses;
6257
6298
 
6258
6299
  // @todo Remove in 1.11
@@ -6282,14 +6323,6 @@
6282
6323
  }
6283
6324
  $this.addClass( oClasses.sTable );
6284
6325
 
6285
- /* Calculate the scroll bar width and cache it for use later on */
6286
- if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
6287
- {
6288
- oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
6289
- }
6290
- if ( oSettings.oScroll.sX === true ) { // Easy initialisation of x-scrolling
6291
- oSettings.oScroll.sX = '100%';
6292
- }
6293
6326
 
6294
6327
  if ( oSettings.iInitDisplayStart === undefined )
6295
6328
  {
@@ -6400,7 +6433,7 @@
6400
6433
  return cell.getAttribute( 'data-'+name ) !== null ? name : null;
6401
6434
  };
6402
6435
 
6403
- $.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, function (i, cell) {
6436
+ $( rowOne[0] ).children('th, td').each( function (i, cell) {
6404
6437
  var col = oSettings.aoColumns[i];
6405
6438
 
6406
6439
  if ( col.mData === i ) {
@@ -6482,9 +6515,6 @@
6482
6515
  * Cache the header, body and footer as required, creating them if needed
6483
6516
  */
6484
6517
 
6485
- /* Browser support detection */
6486
- _fnBrowserDetect( oSettings );
6487
-
6488
6518
  // Work around for Webkit bug 83867 - store the caption-side before removing from doc
6489
6519
  var captions = $this.children('caption').each( function () {
6490
6520
  this._captionSide = $this.css('caption-side');
@@ -6722,17 +6752,15 @@
6722
6752
  */
6723
6753
  _Api = function ( context, data )
6724
6754
  {
6725
- if ( ! this instanceof _Api ) {
6726
- throw 'DT API must be constructed as a new object';
6727
- // or should it do the 'new' for the caller?
6728
- // return new _Api.apply( this, arguments );
6755
+ if ( ! (this instanceof _Api) ) {
6756
+ return new _Api( context, data );
6729
6757
  }
6730
6758
 
6731
6759
  var settings = [];
6732
6760
  var ctxSettings = function ( o ) {
6733
6761
  var a = _toSettings( o );
6734
6762
  if ( a ) {
6735
- settings.push.apply( settings, a );
6763
+ settings = settings.concat( a );
6736
6764
  }
6737
6765
  };
6738
6766
 
@@ -6750,7 +6778,7 @@
6750
6778
 
6751
6779
  // Initial data
6752
6780
  if ( data ) {
6753
- this.push.apply( this, data.toArray ? data.toArray() : data );
6781
+ $.merge( this, data );
6754
6782
  }
6755
6783
 
6756
6784
  // selector
@@ -6765,25 +6793,27 @@
6765
6793
 
6766
6794
  DataTable.Api = _Api;
6767
6795
 
6768
- _Api.prototype = /** @lends DataTables.Api */{
6769
- /**
6770
- * Return a new Api instance, comprised of the data held in the current
6771
- * instance, join with the other array(s) and/or value(s).
6772
- *
6773
- * An alias for `Array.prototype.concat`.
6774
- *
6775
- * @type method
6776
- * @param {*} value1 Arrays and/or values to concatenate.
6777
- * @param {*} [...] Additional arrays and/or values to concatenate.
6778
- * @returns {DataTables.Api} New API instance, comprising of the combined
6779
- * array.
6780
- */
6796
+ // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6797
+ // isPlainObject.
6798
+ $.extend( _Api.prototype, {
6799
+ any: function ()
6800
+ {
6801
+ return this.count() !== 0;
6802
+ },
6803
+
6804
+
6781
6805
  concat: __arrayProto.concat,
6782
6806
 
6783
6807
 
6784
6808
  context: [], // array of table settings objects
6785
6809
 
6786
6810
 
6811
+ count: function ()
6812
+ {
6813
+ return this.flatten().length;
6814
+ },
6815
+
6816
+
6787
6817
  each: function ( fn )
6788
6818
  {
6789
6819
  for ( var i=0, ien=this.length ; i<ien; i++ ) {
@@ -6844,7 +6874,6 @@
6844
6874
  return -1;
6845
6875
  },
6846
6876
 
6847
- // Note that `alwaysNew` is internal - use iteratorNew externally
6848
6877
  iterator: function ( flatten, type, fn, alwaysNew ) {
6849
6878
  var
6850
6879
  a = [], ret,
@@ -7012,7 +7041,7 @@
7012
7041
 
7013
7042
 
7014
7043
  unshift: __arrayProto.unshift
7015
- };
7044
+ } );
7016
7045
 
7017
7046
 
7018
7047
  _Api.extend = function ( scope, obj, ext )
@@ -7267,15 +7296,21 @@
7267
7296
 
7268
7297
  /**
7269
7298
  * Redraw the tables in the current context.
7270
- *
7271
- * @param {boolean} [reset=true] Reset (default) or hold the current paging
7272
- * position. A full re-sort and re-filter is performed when this method is
7273
- * called, which is why the pagination reset is the default action.
7274
- * @returns {DataTables.Api} this
7275
7299
  */
7276
- _api_register( 'draw()', function ( resetPaging ) {
7300
+ _api_register( 'draw()', function ( paging ) {
7277
7301
  return this.iterator( 'table', function ( settings ) {
7278
- _fnReDraw( settings, resetPaging===false );
7302
+ if ( paging === 'page' ) {
7303
+ _fnDraw( settings );
7304
+ }
7305
+ else {
7306
+ if ( typeof paging === 'string' ) {
7307
+ paging = paging === 'full-hold' ?
7308
+ false :
7309
+ true;
7310
+ }
7311
+
7312
+ _fnReDraw( settings, paging===false );
7313
+ }
7279
7314
  } );
7280
7315
  } );
7281
7316
 
@@ -7349,7 +7384,8 @@
7349
7384
  "end": settings.fnDisplayEnd(),
7350
7385
  "length": len,
7351
7386
  "recordsTotal": settings.fnRecordsTotal(),
7352
- "recordsDisplay": visRecords
7387
+ "recordsDisplay": visRecords,
7388
+ "serverSide": _fnDataSource( settings ) === 'ssp'
7353
7389
  };
7354
7390
  } );
7355
7391
 
@@ -7397,9 +7433,15 @@
7397
7433
  _fnReDraw( settings, holdPosition );
7398
7434
  }
7399
7435
  else {
7400
- // Trigger xhr
7401
7436
  _fnProcessingDisplay( settings, true );
7402
7437
 
7438
+ // Cancel an existing request
7439
+ var xhr = settings.jqXHR;
7440
+ if ( xhr && xhr.readyState !== 4 ) {
7441
+ xhr.abort();
7442
+ }
7443
+
7444
+ // Trigger xhr
7403
7445
  _fnBuildAjax( settings, [], function( json ) {
7404
7446
  _fnClearTable( settings );
7405
7447
 
@@ -7527,7 +7569,7 @@
7527
7569
 
7528
7570
 
7529
7571
 
7530
- var _selector_run = function ( selector, select )
7572
+ var _selector_run = function ( type, selector, selectFn, settings, opts )
7531
7573
  {
7532
7574
  var
7533
7575
  out = [], res,
@@ -7546,15 +7588,23 @@
7546
7588
  [ selector[i] ];
7547
7589
 
7548
7590
  for ( j=0, jen=a.length ; j<jen ; j++ ) {
7549
- res = select( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7591
+ res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7550
7592
 
7551
7593
  if ( res && res.length ) {
7552
- out.push.apply( out, res );
7594
+ out = out.concat( res );
7553
7595
  }
7554
7596
  }
7555
7597
  }
7556
7598
 
7557
- return out;
7599
+ // selector extensions
7600
+ var ext = _ext.selector[ type ];
7601
+ if ( ext.length ) {
7602
+ for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7603
+ out = ext[i]( settings, opts, out );
7604
+ }
7605
+ }
7606
+
7607
+ return _unique( out );
7558
7608
  };
7559
7609
 
7560
7610
 
@@ -7566,15 +7616,15 @@
7566
7616
 
7567
7617
  // Backwards compatibility for 1.9- which used the terminology filter rather
7568
7618
  // than search
7569
- if ( opts.filter && ! opts.search ) {
7619
+ if ( opts.filter && opts.search === undefined ) {
7570
7620
  opts.search = opts.filter;
7571
7621
  }
7572
7622
 
7573
- return {
7574
- search: opts.search || 'none',
7575
- order: opts.order || 'current',
7576
- page: opts.page || 'all'
7577
- };
7623
+ return $.extend( {
7624
+ search: 'none',
7625
+ order: 'current',
7626
+ page: 'all'
7627
+ }, opts );
7578
7628
  };
7579
7629
 
7580
7630
 
@@ -7586,6 +7636,7 @@
7586
7636
  // Assign the first element to the first item in the instance
7587
7637
  // and truncate the instance and context
7588
7638
  inst[0] = inst[i];
7639
+ inst[0].length = 1;
7589
7640
  inst.length = 1;
7590
7641
  inst.context = [ inst.context[i] ];
7591
7642
 
@@ -7672,7 +7723,7 @@
7672
7723
 
7673
7724
  var __row_selector = function ( settings, selector, opts )
7674
7725
  {
7675
- return _selector_run( selector, function ( sel ) {
7726
+ var run = function ( sel ) {
7676
7727
  var selInt = _intVal( sel );
7677
7728
  var i, ien;
7678
7729
 
@@ -7715,6 +7766,26 @@
7715
7766
  }
7716
7767
  }
7717
7768
 
7769
+ // ID selector. Want to always be able to select rows by id, regardless
7770
+ // of if the tr element has been created or not, so can't rely upon
7771
+ // jQuery here - hence a custom implementation. This does not match
7772
+ // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7773
+ // but to select it using a CSS selector engine (like Sizzle or
7774
+ // querySelect) it would need to need to be escaped for some characters.
7775
+ // DataTables simplifies this for row selectors since you can select
7776
+ // only a row. A # indicates an id any anything that follows is the id -
7777
+ // unescaped.
7778
+ if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7779
+ // get row index from id
7780
+ var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7781
+ if ( rowObj !== undefined ) {
7782
+ return [ rowObj.idx ];
7783
+ }
7784
+
7785
+ // need to fall through to jQuery in case there is DOM id that
7786
+ // matches
7787
+ }
7788
+
7718
7789
  // Selector - jQuery selector string, array of nodes or jQuery object/
7719
7790
  // As jQuery's .filter() allows jQuery objects to be passed in filter,
7720
7791
  // it also allows arrays, so this will cope with all three options
@@ -7724,7 +7795,9 @@
7724
7795
  return this._DT_RowIndex;
7725
7796
  } )
7726
7797
  .toArray();
7727
- } );
7798
+ };
7799
+
7800
+ return _selector_run( 'row', selector, run, settings, opts );
7728
7801
  };
7729
7802
 
7730
7803
 
@@ -7782,11 +7855,27 @@
7782
7855
  }, 1 );
7783
7856
  } );
7784
7857
 
7858
+ _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
7859
+ var a = [];
7860
+ var context = this.context;
7861
+
7862
+ // `iterator` will drop undefined values, but in this case we want them
7863
+ for ( var i=0, ien=context.length ; i<ien ; i++ ) {
7864
+ for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
7865
+ var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
7866
+ a.push( (hash === true ? '#' : '' )+ id );
7867
+ }
7868
+ }
7869
+
7870
+ return new _Api( context, a );
7871
+ } );
7872
+
7785
7873
  _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
7786
7874
  var that = this;
7787
7875
 
7788
- return this.iterator( 'row', function ( settings, row, thatIdx ) {
7876
+ this.iterator( 'row', function ( settings, row, thatIdx ) {
7789
7877
  var data = settings.aoData;
7878
+ var rowData = data[ row ];
7790
7879
 
7791
7880
  data.splice( row, 1 );
7792
7881
 
@@ -7797,9 +7886,6 @@
7797
7886
  }
7798
7887
  }
7799
7888
 
7800
- // Remove the target row from the search array
7801
- var displayIndex = $.inArray( row, settings.aiDisplay );
7802
-
7803
7889
  // Delete from the display arrays
7804
7890
  _fnDeleteIndex( settings.aiDisplayMaster, row );
7805
7891
  _fnDeleteIndex( settings.aiDisplay, row );
@@ -7807,7 +7893,21 @@
7807
7893
 
7808
7894
  // Check for an 'overflow' they case for displaying the table
7809
7895
  _fnLengthOverflow( settings );
7896
+
7897
+ // Remove the row's ID reference if there is one
7898
+ var id = settings.rowIdFn( rowData._aData );
7899
+ if ( id !== undefined ) {
7900
+ delete settings.aIds[ id ];
7901
+ }
7810
7902
  } );
7903
+
7904
+ this.iterator( 'table', function ( settings ) {
7905
+ for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7906
+ settings.aoData[i].idx = i;
7907
+ }
7908
+ } );
7909
+
7910
+ return this;
7811
7911
  } );
7812
7912
 
7813
7913
 
@@ -7833,7 +7933,7 @@
7833
7933
  // Return an Api.rows() extended instance, so rows().nodes() etc can be used
7834
7934
  var modRows = this.rows( -1 );
7835
7935
  modRows.pop();
7836
- modRows.push.apply( modRows, newRows.toArray() );
7936
+ $.merge( modRows, newRows );
7837
7937
 
7838
7938
  return modRows;
7839
7939
  } );
@@ -7951,7 +8051,7 @@
7951
8051
  if ( ctx.length ) {
7952
8052
  var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
7953
8053
 
7954
- if ( row._details ) {
8054
+ if ( row && row._details ) {
7955
8055
  row._details.remove();
7956
8056
 
7957
8057
  row._detailsShow = undefined;
@@ -8154,7 +8254,7 @@
8154
8254
  names = _pluck( columns, 'sName' ),
8155
8255
  nodes = _pluck( columns, 'nTh' );
8156
8256
 
8157
- return _selector_run( selector, function ( s ) {
8257
+ var run = function ( s ) {
8158
8258
  var selInt = _intVal( s );
8159
8259
 
8160
8260
  // Selector - all
@@ -8220,7 +8320,9 @@
8220
8320
  } )
8221
8321
  .toArray();
8222
8322
  }
8223
- } );
8323
+ };
8324
+
8325
+ return _selector_run( 'column', selector, run, settings, opts );
8224
8326
  };
8225
8327
 
8226
8328
 
@@ -8395,7 +8497,7 @@
8395
8497
  var columns = settings.aoColumns.length;
8396
8498
  var a, i, ien, j, o, host;
8397
8499
 
8398
- return _selector_run( selector, function ( s ) {
8500
+ var run = function ( s ) {
8399
8501
  var fnSelector = typeof s === 'function';
8400
8502
 
8401
8503
  if ( s === null || s === undefined || fnSelector ) {
@@ -8413,9 +8515,9 @@
8413
8515
 
8414
8516
  if ( fnSelector ) {
8415
8517
  // Selector - function
8416
- host = settings.aoData[ row ];
8518
+ host = data[ row ];
8417
8519
 
8418
- if ( s( o, _fnGetCellData(settings, row, j), host.anCells[j] ) ) {
8520
+ if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8419
8521
  a.push( o );
8420
8522
  }
8421
8523
  }
@@ -8438,7 +8540,19 @@
8438
8540
  return allCells
8439
8541
  .filter( s )
8440
8542
  .map( function (i, el) {
8441
- row = el.parentNode._DT_RowIndex;
8543
+ if ( el.parentNode ) {
8544
+ row = el.parentNode._DT_RowIndex;
8545
+ }
8546
+ else {
8547
+ // If no parent node, then the cell is hidden and we'll need
8548
+ // to traverse the array to find it
8549
+ for ( i=0, ien=data.length ; i<ien ; i++ ) {
8550
+ if ( $.inArray( el, data[i].anCells ) !== -1 ) {
8551
+ row = i;
8552
+ break;
8553
+ }
8554
+ }
8555
+ }
8442
8556
 
8443
8557
  return {
8444
8558
  row: row,
@@ -8446,7 +8560,9 @@
8446
8560
  };
8447
8561
  } )
8448
8562
  .toArray();
8449
- } );
8563
+ };
8564
+
8565
+ return _selector_run( 'cell', selector, run, settings, opts );
8450
8566
  };
8451
8567
 
8452
8568
 
@@ -8856,11 +8972,22 @@
8856
8972
  */
8857
8973
  DataTable.tables = DataTable.fnTables = function ( visible )
8858
8974
  {
8859
- return $.map( DataTable.settings, function (o) {
8975
+ var api = false;
8976
+
8977
+ if ( $.isPlainObject( visible ) ) {
8978
+ api = visible.api;
8979
+ visible = visible.visible;
8980
+ }
8981
+
8982
+ var a = $.map( DataTable.settings, function (o) {
8860
8983
  if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
8861
8984
  return o.nTable;
8862
8985
  }
8863
8986
  } );
8987
+
8988
+ return api ?
8989
+ new _Api( a ) :
8990
+ a;
8864
8991
  };
8865
8992
 
8866
8993
 
@@ -9015,10 +9142,6 @@
9015
9142
  jqTable.append( tfoot );
9016
9143
  }
9017
9144
 
9018
- // Remove the DataTables generated nodes, events and classes
9019
- jqTable.detach();
9020
- jqWrapper.detach();
9021
-
9022
9145
  settings.aaSorting = [];
9023
9146
  settings.aaSortingFixed = [];
9024
9147
  _fnSortingClasses( settings );
@@ -9038,30 +9161,36 @@
9038
9161
  } );
9039
9162
  }
9040
9163
 
9041
- if ( ! remove && orig ) {
9042
- // insertBefore acts like appendChild if !arg[1]
9043
- orig.insertBefore( table, settings.nTableReinsertBefore );
9044
- }
9045
-
9046
9164
  // Add the TR elements back into the table in their original order
9047
9165
  jqTbody.children().detach();
9048
9166
  jqTbody.append( rows );
9049
9167
 
9050
- // Restore the width of the original table - was read from the style property,
9051
- // so we can restore directly to that
9052
- jqTable
9053
- .css( 'width', settings.sDestroyWidth )
9054
- .removeClass( classes.sTable );
9168
+ // Remove the DataTables generated nodes, events and classes
9169
+ var removedMethod = remove ? 'remove' : 'detach';
9170
+ jqTable[ removedMethod ]();
9171
+ jqWrapper[ removedMethod ]();
9055
9172
 
9056
- // If the were originally stripe classes - then we add them back here.
9057
- // Note this is not fool proof (for example if not all rows had stripe
9058
- // classes - but it's a good effort without getting carried away
9059
- ien = settings.asDestroyStripes.length;
9173
+ // If we need to reattach the table to the document
9174
+ if ( ! remove && orig ) {
9175
+ // insertBefore acts like appendChild if !arg[1]
9176
+ orig.insertBefore( table, settings.nTableReinsertBefore );
9060
9177
 
9061
- if ( ien ) {
9062
- jqTbody.children().each( function (i) {
9063
- $(this).addClass( settings.asDestroyStripes[i % ien] );
9064
- } );
9178
+ // Restore the width of the original table - was read from the style property,
9179
+ // so we can restore directly to that
9180
+ jqTable
9181
+ .css( 'width', settings.sDestroyWidth )
9182
+ .removeClass( classes.sTable );
9183
+
9184
+ // If the were originally stripe classes - then we add them back here.
9185
+ // Note this is not fool proof (for example if not all rows had stripe
9186
+ // classes - but it's a good effort without getting carried away
9187
+ ien = settings.asDestroyStripes.length;
9188
+
9189
+ if ( ien ) {
9190
+ jqTbody.children().each( function (i) {
9191
+ $(this).addClass( settings.asDestroyStripes[i % ien] );
9192
+ } );
9193
+ }
9065
9194
  }
9066
9195
 
9067
9196
  /* Remove the settings object from the settings array */
@@ -9076,13 +9205,44 @@
9076
9205
  // Add the `every()` method for rows, columns and cells in a compact form
9077
9206
  $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9078
9207
  _api_register( type+'s().every()', function ( fn ) {
9079
- return this.iterator( type, function ( settings, idx, idx2 ) {
9080
- // idx2 is undefined for rows and columns.
9081
- fn.call( new _Api( settings )[ type ]( idx, idx2 ) );
9208
+ return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9209
+ // Rows and columns:
9210
+ // arg1 - index
9211
+ // arg2 - table counter
9212
+ // arg3 - loop counter
9213
+ // arg4 - undefined
9214
+ // Cells:
9215
+ // arg1 - row index
9216
+ // arg2 - column index
9217
+ // arg3 - table counter
9218
+ // arg4 - loop counter
9219
+ fn.call(
9220
+ new _Api( settings )[ type ]( arg1, type==='cell' ? arg2 : undefined ),
9221
+ arg1, arg2, arg3, arg4
9222
+ );
9082
9223
  } );
9083
9224
  } );
9084
9225
  } );
9085
9226
 
9227
+
9228
+ // i18n method for extensions to be able to use the language object from the
9229
+ // DataTable
9230
+ _api_register( 'i18n()', function ( token, def, plural ) {
9231
+ var ctx = this.context[0];
9232
+ var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9233
+
9234
+ if ( resolved === undefined ) {
9235
+ resolved = def;
9236
+ }
9237
+
9238
+ if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9239
+ resolved = resolved[ plural ] !== undefined ?
9240
+ resolved[ plural ] :
9241
+ resolved._;
9242
+ }
9243
+
9244
+ return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9245
+ } );
9086
9246
 
9087
9247
  /**
9088
9248
  * Version string for plug-ins to check compatibility. Allowed format is
@@ -9092,7 +9252,7 @@
9092
9252
  * @type string
9093
9253
  * @default Version number
9094
9254
  */
9095
- DataTable.version = "1.10.6";
9255
+ DataTable.version = "1.10.9";
9096
9256
 
9097
9257
  /**
9098
9258
  * Private data store, containing all of the settings objects that are
@@ -9244,7 +9404,16 @@
9244
9404
  * @default null
9245
9405
  * @private
9246
9406
  */
9247
- "src": null
9407
+ "src": null,
9408
+
9409
+ /**
9410
+ * Index in the aoData array. This saves an indexOf lookup when we have the
9411
+ * object, but want to know the index
9412
+ * @type integer
9413
+ * @default -1
9414
+ * @private
9415
+ */
9416
+ "idx": -1
9248
9417
  };
9249
9418
 
9250
9419
 
@@ -11685,7 +11854,18 @@
11685
11854
  * @name DataTable.defaults.renderer
11686
11855
  *
11687
11856
  */
11688
- "renderer": null
11857
+ "renderer": null,
11858
+
11859
+
11860
+ /**
11861
+ * Set the data property name that DataTables should use to get a row's id
11862
+ * to set as the `id` property in the node.
11863
+ * @type string
11864
+ * @default DT_RowId
11865
+ *
11866
+ * @name DataTable.defaults.rowId
11867
+ */
11868
+ "rowId": "DT_RowId"
11689
11869
  };
11690
11870
 
11691
11871
  _fnHungarianMap( DataTable.defaults );
@@ -12784,7 +12964,21 @@
12784
12964
  * @type boolean
12785
12965
  * @default false
12786
12966
  */
12787
- "bScrollbarLeft": false
12967
+ "bScrollbarLeft": false,
12968
+
12969
+ /**
12970
+ * Flag for if `getBoundingClientRect` is fully supported or not
12971
+ * @type boolean
12972
+ * @default false
12973
+ */
12974
+ "bBounding": false,
12975
+
12976
+ /**
12977
+ * Browser scrollbar width
12978
+ * @type integer
12979
+ * @default 0
12980
+ */
12981
+ "barWidth": 0
12788
12982
  },
12789
12983
 
12790
12984
 
@@ -12829,6 +13023,13 @@
12829
13023
  */
12830
13024
  "aiDisplayMaster": [],
12831
13025
 
13026
+ /**
13027
+ * Map of row ids to data indexes
13028
+ * @type object
13029
+ * @default {}
13030
+ */
13031
+ "aIds": {},
13032
+
12832
13033
  /**
12833
13034
  * Store information about each column that is in use
12834
13035
  * @type array
@@ -13437,7 +13638,21 @@
13437
13638
  * @type object
13438
13639
  * @default {}
13439
13640
  */
13440
- "oPlugins": {}
13641
+ "oPlugins": {},
13642
+
13643
+ /**
13644
+ * Function used to get a row's id from the row's data
13645
+ * @type function
13646
+ * @default null
13647
+ */
13648
+ "rowIdFn": null,
13649
+
13650
+ /**
13651
+ * Data location where to store a row's id
13652
+ * @type string
13653
+ * @default null
13654
+ */
13655
+ "rowId": null
13441
13656
  };
13442
13657
 
13443
13658
  /**
@@ -13599,6 +13814,37 @@
13599
13814
  search: [],
13600
13815
 
13601
13816
 
13817
+ /**
13818
+ * Selector extensions
13819
+ *
13820
+ * The `selector` option can be used to extend the options available for the
13821
+ * selector modifier options (`selector-modifier` object data type) that
13822
+ * each of the three built in selector types offer (row, column and cell +
13823
+ * their plural counterparts). For example the Select extension uses this
13824
+ * mechanism to provide an option to select only rows, columns and cells
13825
+ * that have been marked as selected by the end user (`{selected: true}`),
13826
+ * which can be used in conjunction with the existing built in selector
13827
+ * options.
13828
+ *
13829
+ * Each property is an array to which functions can be pushed. The functions
13830
+ * take three attributes:
13831
+ *
13832
+ * * Settings object for the host table
13833
+ * * Options object (`selector-modifier` object type)
13834
+ * * Array of selected item indexes
13835
+ *
13836
+ * The return is an array of the resulting item indexes after the custom
13837
+ * selector has been applied.
13838
+ *
13839
+ * @type object
13840
+ */
13841
+ selector: {
13842
+ cell: [],
13843
+ column: [],
13844
+ row: []
13845
+ },
13846
+
13847
+
13602
13848
  /**
13603
13849
  * Internal functions, exposed for used in plug-ins.
13604
13850
  *
@@ -14113,6 +14359,10 @@
14113
14359
  return [ 'first', 'previous', 'next', 'last' ];
14114
14360
  },
14115
14361
 
14362
+ numbers: function ( page, pages ) {
14363
+ return [ _numbers(page, pages) ];
14364
+ },
14365
+
14116
14366
  simple_numbers: function ( page, pages ) {
14117
14367
  return [ 'previous', _numbers(page, pages), 'next' ];
14118
14368
  },
@@ -14151,7 +14401,7 @@
14151
14401
  attach( inner, button );
14152
14402
  }
14153
14403
  else {
14154
- btnDisplay = '';
14404
+ btnDisplay = null;
14155
14405
  btnClass = '';
14156
14406
 
14157
14407
  switch ( button ) {
@@ -14190,7 +14440,7 @@
14190
14440
  break;
14191
14441
  }
14192
14442
 
14193
- if ( btnDisplay ) {
14443
+ if ( btnDisplay !== null ) {
14194
14444
  node = $('<a>', {
14195
14445
  'class': classes.sPageButton+' '+btnClass,
14196
14446
  'aria-controls': settings.sTableId,
@@ -14223,7 +14473,7 @@
14223
14473
  // elements, focus is lost on the select button which is bad for
14224
14474
  // accessibility. So we want to restore focus once the draw has
14225
14475
  // completed
14226
- activeEl = $(document.activeElement).data('dt-idx');
14476
+ activeEl = $(host).find(document.activeElement).data('dt-idx');
14227
14477
  }
14228
14478
  catch (e) {}
14229
14479
 
@@ -14521,11 +14771,12 @@
14521
14771
  *
14522
14772
  * * `number` - Will format numeric data (defined by `columns.data`) for
14523
14773
  * display, retaining the original unformatted data for sorting and filtering.
14524
- * It takes 4 parameters:
14774
+ * It takes 5 parameters:
14525
14775
  * * `string` - Thousands grouping separator
14526
14776
  * * `string` - Decimal point indicator
14527
14777
  * * `integer` - Number of decimal points to show
14528
14778
  * * `string` (optional) - Prefix.
14779
+ * * `string` (optional) - Postfix (/suffix).
14529
14780
  *
14530
14781
  * @example
14531
14782
  * // Column definition using the number renderer
@@ -14537,7 +14788,7 @@
14537
14788
  * @namespace
14538
14789
  */
14539
14790
  DataTable.render = {
14540
- number: function ( thousands, decimal, precision, prefix ) {
14791
+ number: function ( thousands, decimal, precision, prefix, postfix ) {
14541
14792
  return {
14542
14793
  display: function ( d ) {
14543
14794
  if ( typeof d !== 'number' && typeof d !== 'string' ) {
@@ -14556,7 +14807,8 @@
14556
14807
  intPart.toString().replace(
14557
14808
  /\B(?=(\d{3})+(?!\d))/g, thousands
14558
14809
  ) +
14559
- floatPart;
14810
+ floatPart +
14811
+ (postfix||'');
14560
14812
  }
14561
14813
  };
14562
14814
  }
@@ -14660,11 +14912,9 @@
14660
14912
  _fnCalculateColumnWidths: _fnCalculateColumnWidths,
14661
14913
  _fnThrottle: _fnThrottle,
14662
14914
  _fnConvertToWidth: _fnConvertToWidth,
14663
- _fnScrollingWidthAdjust: _fnScrollingWidthAdjust,
14664
14915
  _fnGetWidestNode: _fnGetWidestNode,
14665
14916
  _fnGetMaxLenString: _fnGetMaxLenString,
14666
14917
  _fnStringToCss: _fnStringToCss,
14667
- _fnScrollBarWidth: _fnScrollBarWidth,
14668
14918
  _fnSortFlatten: _fnSortFlatten,
14669
14919
  _fnSort: _fnSort,
14670
14920
  _fnSortAria: _fnSortAria,