]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Update DataTables and its plugins
authorMarcin Haba <marcin.haba@bacula.pl>
Sun, 1 Mar 2020 16:00:15 +0000 (17:00 +0100)
committerMarcin Haba <marcin.haba@bacula.pl>
Sun, 1 Mar 2020 17:09:46 +0000 (18:09 +0100)
- update DataTables
- update responsive plugin
- update buttons plugin
- add select plugin

gui/baculum/LICENSE
gui/baculum/protected/Web/JavaScript/dataTables.responsive.js
gui/baculum/protected/Web/JavaScript/dataTables.select.js [new file with mode: 0644]
gui/baculum/protected/Web/JavaScript/datatables.js
gui/baculum/themes/Baculum-v2/css/buttons.dataTables.css
gui/baculum/themes/Baculum-v2/css/datatables.css
gui/baculum/themes/Baculum-v2/css/select.jqueryui.css [new file with mode: 0644]

index 7a510719423e31a7006e4680a6a8a816f198c580..3dc9f01c2104ce2d6564eeaf4c5f51597cc81387 100644 (file)
@@ -841,12 +841,14 @@ Files:
   protected/Web/JavaScript/datatables.js
   protected/Web/JavaScript/dataTables.responsive.js
   protected/Web/JavaScript/dataTables.buttons.js
+  protected/Web/JavaScript/dataTables.select.js
   protected/Web/JavaScript/responsive.jqueryui.js
   protected/Web/JavaScript/buttons.colVis.js
   protected/Web/JavaScript/buttons.html5.js
   themes/Baculum-v2/css/datatables.css
   themes/Baculum-v2/css/responsive.dataTables.css
   themes/Baculum-v2/css/buttons.dataTables.css
+  themes/Baculum-v2/css/select.jqueryui.css
 
 Copyright (C) 2008-2020, SpryMedia Ltd.
 
index 3ffe2b3d2fa6d77cbbc23ee8ab1ac1a88f7e33ec..f0bbdcbd28d0c3cae0cd53ff023ae70873d7d573 100644 (file)
@@ -1,15 +1,15 @@
-/*! Responsive 2.2.1
- * 2014-2017 SpryMedia Ltd - datatables.net/license
+/*! Responsive 2.2.3
+ * 2014-2018 SpryMedia Ltd - datatables.net/license
  */
 
 /**
  * @summary     Responsive
  * @description Responsive tables plug-in for DataTables
- * @version     2.2.1
+ * @version     2.2.3
  * @file        dataTables.responsive.js
  * @author      SpryMedia Ltd (www.sprymedia.co.uk)
  * @contact     www.sprymedia.co.uk/contact
- * @copyright   Copyright 2014-2017 SpryMedia Ltd.
+ * @copyright   Copyright 2014-2018 SpryMedia Ltd.
  *
  * This source file is free software, available under the following license:
  *   MIT license - http://datatables.net/license/mit
@@ -208,12 +208,21 @@ $.extend( Responsive.prototype, {
 
                        // DataTables will trigger this event on every column it shows and
                        // hides individually
-                       dt.on( 'column-visibility.dtr', function (e, ctx, col, vis, recalc) {
-                               if ( recalc ) {
+                       dt.on( 'column-visibility.dtr', function () {
+                               // Use a small debounce to allow multiple columns to be set together
+                               if ( that._timer ) {
+                                       clearTimeout( that._timer );
+                               }
+
+                               that._timer = setTimeout( function () {
+                                       that._timer = null;
+
                                        that._classLogic();
                                        that._resizeAuto();
                                        that._resize();
-                               }
+
+                                       that._redrawChildren();
+                               }, 100 );
                        } );
 
                        // Redraw the details box on each draw which will happen if the data
@@ -316,7 +325,10 @@ $.extend( Responsive.prototype, {
                // Class logic - determine which columns are in this breakpoint based
                // on the classes. If no class control (i.e. `auto`) then `-` is used
                // to indicate this to the rest of the function
-               var display = $.map( columns, function ( col ) {
+               var display = $.map( columns, function ( col, i ) {
+                       if ( dt.column(i).visible() === false ) {
+                               return 'not-visible';
+                       }
                        return col.auto && col.minWidth === null ?
                                false :
                                col.auto === true ?
@@ -384,7 +396,7 @@ $.extend( Responsive.prototype, {
                var showControl = false;
 
                for ( i=0, ien=columns.length ; i<ien ; i++ ) {
-                       if ( ! columns[i].control && ! columns[i].never && ! display[i] ) {
+                       if ( ! columns[i].control && ! columns[i].never && display[i] === false ) {
                                showControl = true;
                                break;
                        }
@@ -394,6 +406,11 @@ $.extend( Responsive.prototype, {
                        if ( columns[i].control ) {
                                display[i] = showControl;
                        }
+
+                       // Replace not visible string with false from the control column detection above
+                       if ( display[i] === 'not-visible' ) {
+                               display[i] = false;
+                       }
                }
 
                // Finally we need to make sure that there is at least one column that
@@ -758,7 +775,7 @@ $.extend( Responsive.prototype, {
                // any columns that are not visible but can be shown
                var collapsedClass = false;
                for ( i=0, ien=columns.length ; i<ien ; i++ ) {
-                       if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control ) {
+                       if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control && ! dt.column(i).visible() === false ) {
                                collapsedClass = true;
                                break;
                        }
@@ -884,6 +901,10 @@ $.extend( Responsive.prototype, {
                // multiple times. For example, cloning and inserting a checked radio
                // clears the chcecked state of the original radio.
                $( clonedTable ).find( '[name]' ).removeAttr( 'name' );
+
+               // A position absolute table would take the table out of the flow of
+               // our container element, bypassing the height and width (Scroller)
+               $( clonedTable ).css( 'position', 'relative' )
                
                var inserted = $('<div/>')
                        .css( {
@@ -953,19 +974,22 @@ $.extend( Responsive.prototype, {
 
                cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
 
-               var selector = typeof target === 'number' ?
-                       ':eq('+target+')' :
-                       target;
-
-               // This is a bit of a hack - we need to limit the selected nodes to just
-               // those of this table
-               if ( selector === 'td:first-child, th:first-child' ) {
-                       selector = '>td:first-child, >th:first-child';
+               if ( typeof target === 'number' ) {
+                       dt.cells( null, target, { page: 'current' } ).nodes().to$()
+                               .attr( 'tabIndex', ctx.iTabIndex )
+                               .data( 'dtr-keyboard', 1 );
                }
+               else {
+                       // This is a bit of a hack - we need to limit the selected nodes to just
+                       // those of this table
+                       if ( target === 'td:first-child, th:first-child' ) {
+                               target = '>td:first-child, >th:first-child';
+                       }
 
-               $( selector, dt.rows( { page: 'current' } ).nodes() )
-                       .attr( 'tabIndex', ctx.iTabIndex )
-                       .data( 'dtr-keyboard', 1 );
+                       $( target, dt.rows( { page: 'current' } ).nodes() )
+                               .attr( 'tabIndex', ctx.iTabIndex )
+                               .data( 'dtr-keyboard', 1 );
+               }
        }
 } );
 
@@ -1338,7 +1362,7 @@ Api.registerPlural( 'columns().responsiveHidden()', 'column().responsiveHidden()
  * @name Responsive.version
  * @static
  */
-Responsive.version = '2.2.1';
+Responsive.version = '2.2.3';
 
 
 $.fn.dataTable.Responsive = Responsive;
diff --git a/gui/baculum/protected/Web/JavaScript/dataTables.select.js b/gui/baculum/protected/Web/JavaScript/dataTables.select.js
new file mode 100644 (file)
index 0000000..50f4bc0
--- /dev/null
@@ -0,0 +1,1206 @@
+/*! Select for DataTables 1.3.1
+ * 2015-2019 SpryMedia Ltd - datatables.net/license/mit
+ */
+
+/**
+ * @summary     Select for DataTables
+ * @description A collection of API methods, events and buttons for DataTables
+ *   that provides selection options of the items in a DataTable
+ * @version     1.3.1
+ * @file        dataTables.select.js
+ * @author      SpryMedia Ltd (www.sprymedia.co.uk)
+ * @contact     datatables.net/forums
+ * @copyright   Copyright 2015-2019 SpryMedia Ltd.
+ *
+ * This source file is free software, available under the following license:
+ *   MIT license - http://datatables.net/license/mit
+ *
+ * This source file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
+ *
+ * For details please refer to: http://www.datatables.net/extensions/select
+ */
+(function( factory ){
+       if ( typeof define === 'function' && define.amd ) {
+               // AMD
+               define( ['jquery', 'datatables.net'], function ( $ ) {
+                       return factory( $, window, document );
+               } );
+       }
+       else if ( typeof exports === 'object' ) {
+               // CommonJS
+               module.exports = function (root, $) {
+                       if ( ! root ) {
+                               root = window;
+                       }
+
+                       if ( ! $ || ! $.fn.dataTable ) {
+                               $ = require('datatables.net')(root, $).$;
+                       }
+
+                       return factory( $, root, root.document );
+               };
+       }
+       else {
+               // Browser
+               factory( jQuery, window, document );
+       }
+}(function( $, window, document, undefined ) {
+'use strict';
+var DataTable = $.fn.dataTable;
+
+
+// Version information for debugger
+DataTable.select = {};
+
+DataTable.select.version = '1.3.1';
+
+DataTable.select.init = function ( dt ) {
+       var ctx = dt.settings()[0];
+       var init = ctx.oInit.select;
+       var defaults = DataTable.defaults.select;
+       var opts = init === undefined ?
+               defaults :
+               init;
+
+       // Set defaults
+       var items = 'row';
+       var style = 'api';
+       var blurable = false;
+       var toggleable = true;
+       var info = true;
+       var selector = 'td, th';
+       var className = 'selected';
+       var setStyle = false;
+
+       ctx._select = {};
+
+       // Initialisation customisations
+       if ( opts === true ) {
+               style = 'os';
+               setStyle = true;
+       }
+       else if ( typeof opts === 'string' ) {
+               style = opts;
+               setStyle = true;
+       }
+       else if ( $.isPlainObject( opts ) ) {
+               if ( opts.blurable !== undefined ) {
+                       blurable = opts.blurable;
+               }
+               
+               if ( opts.toggleable !== undefined ) {
+                       toggleable = opts.toggleable;
+               }
+
+               if ( opts.info !== undefined ) {
+                       info = opts.info;
+               }
+
+               if ( opts.items !== undefined ) {
+                       items = opts.items;
+               }
+
+               if ( opts.style !== undefined ) {
+                       style = opts.style;
+                       setStyle = true;
+               }
+               else {
+                       style = 'os';
+                       setStyle = true;
+               }
+
+               if ( opts.selector !== undefined ) {
+                       selector = opts.selector;
+               }
+
+               if ( opts.className !== undefined ) {
+                       className = opts.className;
+               }
+       }
+
+       dt.select.selector( selector );
+       dt.select.items( items );
+       dt.select.style( style );
+       dt.select.blurable( blurable );
+       dt.select.toggleable( toggleable );
+       dt.select.info( info );
+       ctx._select.className = className;
+
+
+       // Sort table based on selected rows. Requires Select Datatables extension
+       $.fn.dataTable.ext.order['select-checkbox'] = function ( settings, col ) {
+               return this.api().column( col, {order: 'index'} ).nodes().map( function ( td ) {
+                       if ( settings._select.items === 'row' ) {
+                               return $( td ).parent().hasClass( settings._select.className );
+                       } else if ( settings._select.items === 'cell' ) {
+                               return $( td ).hasClass( settings._select.className );
+                       }
+                       return false;
+               });
+       };
+
+       // If the init options haven't enabled select, but there is a selectable
+       // class name, then enable
+       if ( ! setStyle && $( dt.table().node() ).hasClass( 'selectable' ) ) {
+               dt.select.style( 'os' );
+       }
+};
+
+/*
+
+Select is a collection of API methods, event handlers, event emitters and
+buttons (for the `Buttons` extension) for DataTables. It provides the following
+features, with an overview of how they are implemented:
+
+## Selection of rows, columns and cells. Whether an item is selected or not is
+   stored in:
+
+* rows: a `_select_selected` property which contains a boolean value of the
+  DataTables' `aoData` object for each row
+* columns: a `_select_selected` property which contains a boolean value of the
+  DataTables' `aoColumns` object for each column
+* cells: a `_selected_cells` property which contains an array of boolean values
+  of the `aoData` object for each row. The array is the same length as the
+  columns array, with each element of it representing a cell.
+
+This method of using boolean flags allows Select to operate when nodes have not
+been created for rows / cells (DataTables' defer rendering feature).
+
+## API methods
+
+A range of API methods are available for triggering selection and de-selection
+of rows. Methods are also available to configure the selection events that can
+be triggered by an end user (such as which items are to be selected). To a large
+extent, these of API methods *is* Select. It is basically a collection of helper
+functions that can be used to select items in a DataTable.
+
+Configuration of select is held in the object `_select` which is attached to the
+DataTables settings object on initialisation. Select being available on a table
+is not optional when Select is loaded, but its default is for selection only to
+be available via the API - so the end user wouldn't be able to select rows
+without additional configuration.
+
+The `_select` object contains the following properties:
+
+```
+{
+       items:string       - Can be `rows`, `columns` or `cells`. Defines what item 
+                            will be selected if the user is allowed to activate row
+                            selection using the mouse.
+       style:string       - Can be `none`, `single`, `multi` or `os`. Defines the
+                            interaction style when selecting items
+       blurable:boolean   - If row selection can be cleared by clicking outside of
+                            the table
+       toggleable:boolean - If row selection can be cancelled by repeated clicking
+                            on the row
+       info:boolean       - If the selection summary should be shown in the table
+                            information elements
+}
+```
+
+In addition to the API methods, Select also extends the DataTables selector
+options for rows, columns and cells adding a `selected` option to the selector
+options object, allowing the developer to select only selected items or
+unselected items.
+
+## Mouse selection of items
+
+Clicking on items can be used to select items. This is done by a simple event
+handler that will select the items using the API methods.
+
+ */
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Local functions
+ */
+
+/**
+ * Add one or more cells to the selection when shift clicking in OS selection
+ * style cell selection.
+ *
+ * Cell range is more complicated than row and column as we want to select
+ * in the visible grid rather than by index in sequence. For example, if you
+ * click first in cell 1-1 and then shift click in 2-2 - cells 1-2 and 2-1
+ * should also be selected (and not 1-3, 1-4. etc)
+ * 
+ * @param  {DataTable.Api} dt   DataTable
+ * @param  {object}        idx  Cell index to select to
+ * @param  {object}        last Cell index to select from
+ * @private
+ */
+function cellRange( dt, idx, last )
+{
+       var indexes;
+       var columnIndexes;
+       var rowIndexes;
+       var selectColumns = function ( start, end ) {
+               if ( start > end ) {
+                       var tmp = end;
+                       end = start;
+                       start = tmp;
+               }
+               
+               var record = false;
+               return dt.columns( ':visible' ).indexes().filter( function (i) {
+                       if ( i === start ) {
+                               record = true;
+                       }
+                       
+                       if ( i === end ) { // not else if, as start might === end
+                               record = false;
+                               return true;
+                       }
+
+                       return record;
+               } );
+       };
+
+       var selectRows = function ( start, end ) {
+               var indexes = dt.rows( { search: 'applied' } ).indexes();
+
+               // Which comes first - might need to swap
+               if ( indexes.indexOf( start ) > indexes.indexOf( end ) ) {
+                       var tmp = end;
+                       end = start;
+                       start = tmp;
+               }
+
+               var record = false;
+               return indexes.filter( function (i) {
+                       if ( i === start ) {
+                               record = true;
+                       }
+                       
+                       if ( i === end ) {
+                               record = false;
+                               return true;
+                       }
+
+                       return record;
+               } );
+       };
+
+       if ( ! dt.cells( { selected: true } ).any() && ! last ) {
+               // select from the top left cell to this one
+               columnIndexes = selectColumns( 0, idx.column );
+               rowIndexes = selectRows( 0 , idx.row );
+       }
+       else {
+               // Get column indexes between old and new
+               columnIndexes = selectColumns( last.column, idx.column );
+               rowIndexes = selectRows( last.row , idx.row );
+       }
+
+       indexes = dt.cells( rowIndexes, columnIndexes ).flatten();
+
+       if ( ! dt.cells( idx, { selected: true } ).any() ) {
+               // Select range
+               dt.cells( indexes ).select();
+       }
+       else {
+               // Deselect range
+               dt.cells( indexes ).deselect();
+       }
+}
+
+/**
+ * Disable mouse selection by removing the selectors
+ *
+ * @param {DataTable.Api} dt DataTable to remove events from
+ * @private
+ */
+function disableMouseSelection( dt )
+{
+       var ctx = dt.settings()[0];
+       var selector = ctx._select.selector;
+
+       $( dt.table().container() )
+               .off( 'mousedown.dtSelect', selector )
+               .off( 'mouseup.dtSelect', selector )
+               .off( 'click.dtSelect', selector );
+
+       $('body').off( 'click.dtSelect' + _safeId(dt.table().node()) );
+}
+
+/**
+ * Attach mouse listeners to the table to allow mouse selection of items
+ *
+ * @param {DataTable.Api} dt DataTable to remove events from
+ * @private
+ */
+function enableMouseSelection ( dt )
+{
+       var container = $( dt.table().container() );
+       var ctx = dt.settings()[0];
+       var selector = ctx._select.selector;
+       var matchSelection;
+
+       container
+               .on( 'mousedown.dtSelect', selector, function(e) {
+                       // Disallow text selection for shift clicking on the table so multi
+                       // element selection doesn't look terrible!
+                       if ( e.shiftKey || e.metaKey || e.ctrlKey ) {
+                               container
+                                       .css( '-moz-user-select', 'none' )
+                                       .one('selectstart.dtSelect', selector, function () {
+                                               return false;
+                                       } );
+                       }
+
+                       if ( window.getSelection ) {
+                               matchSelection = window.getSelection();
+                       }
+               } )
+               .on( 'mouseup.dtSelect', selector, function() {
+                       // Allow text selection to occur again, Mozilla style (tested in FF
+                       // 35.0.1 - still required)
+                       container.css( '-moz-user-select', '' );
+               } )
+               .on( 'click.dtSelect', selector, function ( e ) {
+                       var items = dt.select.items();
+                       var idx;
+
+                       // If text was selected (click and drag), then we shouldn't change
+                       // the row's selected state
+                       if ( matchSelection ) {
+                               var selection = window.getSelection();
+
+                               // If the element that contains the selection is not in the table, we can ignore it
+                               // This can happen if the developer selects text from the click event
+                               if ( ! selection.anchorNode || $(selection.anchorNode).closest('table')[0] === dt.table().node() ) {
+                                       if ( selection !== matchSelection ) {
+                                               return;
+                                       }
+                               }
+                       }
+
+                       var ctx = dt.settings()[0];
+                       var wrapperClass = $.trim(dt.settings()[0].oClasses.sWrapper).replace(/ +/g, '.');
+
+                       // Ignore clicks inside a sub-table
+                       if ( $(e.target).closest('div.'+wrapperClass)[0] != dt.table().container() ) {
+                               return;
+                       }
+
+                       var cell = dt.cell( $(e.target).closest('td, th') );
+
+                       // Check the cell actually belongs to the host DataTable (so child
+                       // rows, etc, are ignored)
+                       if ( ! cell.any() ) {
+                               return;
+                       }
+
+                       var event = $.Event('user-select.dt');
+                       eventTrigger( dt, event, [ items, cell, e ] );
+
+                       if ( event.isDefaultPrevented() ) {
+                               return;
+                       }
+
+                       var cellIndex = cell.index();
+                       if ( items === 'row' ) {
+                               idx = cellIndex.row;
+                               typeSelect( e, dt, ctx, 'row', idx );
+                       }
+                       else if ( items === 'column' ) {
+                               idx = cell.index().column;
+                               typeSelect( e, dt, ctx, 'column', idx );
+                       }
+                       else if ( items === 'cell' ) {
+                               idx = cell.index();
+                               typeSelect( e, dt, ctx, 'cell', idx );
+                       }
+
+                       ctx._select_lastCell = cellIndex;
+               } );
+
+       // Blurable
+       $('body').on( 'click.dtSelect' + _safeId(dt.table().node()), function ( e ) {
+               if ( ctx._select.blurable ) {
+                       // If the click was inside the DataTables container, don't blur
+                       if ( $(e.target).parents().filter( dt.table().container() ).length ) {
+                               return;
+                       }
+
+                       // Ignore elements which have been removed from the DOM (i.e. paging
+                       // buttons)
+                       if ( $(e.target).parents('html').length === 0 ) {
+                               return;
+                       }
+
+                       // Don't blur in Editor form
+                       if ( $(e.target).parents('div.DTE').length ) {
+                               return;
+                       }
+
+                       clear( ctx, true );
+               }
+       } );
+}
+
+/**
+ * Trigger an event on a DataTable
+ *
+ * @param {DataTable.Api} api      DataTable to trigger events on
+ * @param  {boolean}      selected true if selected, false if deselected
+ * @param  {string}       type     Item type acting on
+ * @param  {boolean}      any      Require that there are values before
+ *     triggering
+ * @private
+ */
+function eventTrigger ( api, type, args, any )
+{
+       if ( any && ! api.flatten().length ) {
+               return;
+       }
+
+       if ( typeof type === 'string' ) {
+               type = type +'.dt';
+       }
+
+       args.unshift( api );
+
+       $(api.table().node()).trigger( type, args );
+}
+
+/**
+ * Update the information element of the DataTable showing information about the
+ * items selected. This is done by adding tags to the existing text
+ * 
+ * @param {DataTable.Api} api DataTable to update
+ * @private
+ */
+function info ( api )
+{
+       var ctx = api.settings()[0];
+
+       if ( ! ctx._select.info || ! ctx.aanFeatures.i ) {
+               return;
+       }
+
+       if ( api.select.style() === 'api' ) {
+               return;
+       }
+
+       var rows    = api.rows( { selected: true } ).flatten().length;
+       var columns = api.columns( { selected: true } ).flatten().length;
+       var cells   = api.cells( { selected: true } ).flatten().length;
+
+       var add = function ( el, name, num ) {
+               el.append( $('<span class="select-item"/>').append( api.i18n(
+                       'select.'+name+'s',
+                       { _: '%d '+name+'s selected', 0: '', 1: '1 '+name+' selected' },
+                       num
+               ) ) );
+       };
+
+       // Internal knowledge of DataTables to loop over all information elements
+       $.each( ctx.aanFeatures.i, function ( i, el ) {
+               el = $(el);
+
+               var output  = $('<span class="select-info"/>');
+               add( output, 'row', rows );
+               add( output, 'column', columns );
+               add( output, 'cell', cells  );
+
+               var exisiting = el.children('span.select-info');
+               if ( exisiting.length ) {
+                       exisiting.remove();
+               }
+
+               if ( output.text() !== '' ) {
+                       el.append( output );
+               }
+       } );
+}
+
+/**
+ * Initialisation of a new table. Attach event handlers and callbacks to allow
+ * Select to operate correctly.
+ *
+ * This will occur _after_ the initial DataTables initialisation, although
+ * before Ajax data is rendered, if there is ajax data
+ *
+ * @param  {DataTable.settings} ctx Settings object to operate on
+ * @private
+ */
+function init ( ctx ) {
+       var api = new DataTable.Api( ctx );
+
+       // Row callback so that classes can be added to rows and cells if the item
+       // was selected before the element was created. This will happen with the
+       // `deferRender` option enabled.
+       // 
+       // This method of attaching to `aoRowCreatedCallback` is a hack until
+       // DataTables has proper events for row manipulation If you are reviewing
+       // this code to create your own plug-ins, please do not do this!
+       ctx.aoRowCreatedCallback.push( {
+               fn: function ( row, data, index ) {
+                       var i, ien;
+                       var d = ctx.aoData[ index ];
+
+                       // Row
+                       if ( d._select_selected ) {
+                               $( row ).addClass( ctx._select.className );
+                       }
+
+                       // Cells and columns - if separated out, we would need to do two
+                       // loops, so it makes sense to combine them into a single one
+                       for ( i=0, ien=ctx.aoColumns.length ; i<ien ; i++ ) {
+                               if ( ctx.aoColumns[i]._select_selected || (d._selected_cells && d._selected_cells[i]) ) {
+                                       $(d.anCells[i]).addClass( ctx._select.className );
+                               }
+                       }
+               },
+               sName: 'select-deferRender'
+       } );
+
+       // On Ajax reload we want to reselect all rows which are currently selected,
+       // if there is an rowId (i.e. a unique value to identify each row with)
+       api.on( 'preXhr.dt.dtSelect', function () {
+               // note that column selection doesn't need to be cached and then
+               // reselected, as they are already selected
+               var rows = api.rows( { selected: true } ).ids( true ).filter( function ( d ) {
+                       return d !== undefined;
+               } );
+
+               var cells = api.cells( { selected: true } ).eq(0).map( function ( cellIdx ) {
+                       var id = api.row( cellIdx.row ).id( true );
+                       return id ?
+                               { row: id, column: cellIdx.column } :
+                               undefined;
+               } ).filter( function ( d ) {
+                       return d !== undefined;
+               } );
+
+               // On the next draw, reselect the currently selected items
+               api.one( 'draw.dt.dtSelect', function () {
+                       api.rows( rows ).select();
+
+                       // `cells` is not a cell index selector, so it needs a loop
+                       if ( cells.any() ) {
+                               cells.each( function ( id ) {
+                                       api.cells( id.row, id.column ).select();
+                               } );
+                       }
+               } );
+       } );
+
+       // Update the table information element with selected item summary
+       api.on( 'draw.dtSelect.dt select.dtSelect.dt deselect.dtSelect.dt info.dt', function () {
+               info( api );
+       } );
+
+       // Clean up and release
+       api.on( 'destroy.dtSelect', function () {
+               disableMouseSelection( api );
+               api.off( '.dtSelect' );
+       } );
+}
+
+/**
+ * Add one or more items (rows or columns) to the selection when shift clicking
+ * in OS selection style
+ *
+ * @param  {DataTable.Api} dt   DataTable
+ * @param  {string}        type Row or column range selector
+ * @param  {object}        idx  Item index to select to
+ * @param  {object}        last Item index to select from
+ * @private
+ */
+function rowColumnRange( dt, type, idx, last )
+{
+       // Add a range of rows from the last selected row to this one
+       var indexes = dt[type+'s']( { search: 'applied' } ).indexes();
+       var idx1 = $.inArray( last, indexes );
+       var idx2 = $.inArray( idx, indexes );
+
+       if ( ! dt[type+'s']( { selected: true } ).any() && idx1 === -1 ) {
+               // select from top to here - slightly odd, but both Windows and Mac OS
+               // do this
+               indexes.splice( $.inArray( idx, indexes )+1, indexes.length );
+       }
+       else {
+               // reverse so we can shift click 'up' as well as down
+               if ( idx1 > idx2 ) {
+                       var tmp = idx2;
+                       idx2 = idx1;
+                       idx1 = tmp;
+               }
+
+               indexes.splice( idx2+1, indexes.length );
+               indexes.splice( 0, idx1 );
+       }
+
+       if ( ! dt[type]( idx, { selected: true } ).any() ) {
+               // Select range
+               dt[type+'s']( indexes ).select();
+       }
+       else {
+               // Deselect range - need to keep the clicked on row selected
+               indexes.splice( $.inArray( idx, indexes ), 1 );
+               dt[type+'s']( indexes ).deselect();
+       }
+}
+
+/**
+ * Clear all selected items
+ *
+ * @param  {DataTable.settings} ctx Settings object of the host DataTable
+ * @param  {boolean} [force=false] Force the de-selection to happen, regardless
+ *     of selection style
+ * @private
+ */
+function clear( ctx, force )
+{
+       if ( force || ctx._select.style === 'single' ) {
+               var api = new DataTable.Api( ctx );
+               
+               api.rows( { selected: true } ).deselect();
+               api.columns( { selected: true } ).deselect();
+               api.cells( { selected: true } ).deselect();
+       }
+}
+
+/**
+ * Select items based on the current configuration for style and items.
+ *
+ * @param  {object}             e    Mouse event object
+ * @param  {DataTables.Api}     dt   DataTable
+ * @param  {DataTable.settings} ctx  Settings object of the host DataTable
+ * @param  {string}             type Items to select
+ * @param  {int|object}         idx  Index of the item to select
+ * @private
+ */
+function typeSelect ( e, dt, ctx, type, idx )
+{
+       var style = dt.select.style();
+       var toggleable = dt.select.toggleable();
+       var isSelected = dt[type]( idx, { selected: true } ).any();
+       
+       if ( isSelected && ! toggleable ) {
+               return;
+       }
+
+       if ( style === 'os' ) {
+               if ( e.ctrlKey || e.metaKey ) {
+                       // Add or remove from the selection
+                       dt[type]( idx ).select( ! isSelected );
+               }
+               else if ( e.shiftKey ) {
+                       if ( type === 'cell' ) {
+                               cellRange( dt, idx, ctx._select_lastCell || null );
+                       }
+                       else {
+                               rowColumnRange( dt, type, idx, ctx._select_lastCell ?
+                                       ctx._select_lastCell[type] :
+                                       null
+                               );
+                       }
+               }
+               else {
+                       // No cmd or shift click - deselect if selected, or select
+                       // this row only
+                       var selected = dt[type+'s']( { selected: true } );
+
+                       if ( isSelected && selected.flatten().length === 1 ) {
+                               dt[type]( idx ).deselect();
+                       }
+                       else {
+                               selected.deselect();
+                               dt[type]( idx ).select();
+                       }
+               }
+       } else if ( style == 'multi+shift' ) {
+               if ( e.shiftKey ) {
+                       if ( type === 'cell' ) {
+                               cellRange( dt, idx, ctx._select_lastCell || null );
+                       }
+                       else {
+                               rowColumnRange( dt, type, idx, ctx._select_lastCell ?
+                                       ctx._select_lastCell[type] :
+                                       null
+                               );
+                       }
+               }
+               else {
+                       dt[ type ]( idx ).select( ! isSelected );
+               }
+       }
+       else {
+               dt[ type ]( idx ).select( ! isSelected );
+       }
+}
+
+function _safeId( node ) {
+       return node.id.replace(/[^a-zA-Z0-9\-\_]/g, '-');
+}
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables selectors
+ */
+
+// row and column are basically identical just assigned to different properties
+// and checking a different array, so we can dynamically create the functions to
+// reduce the code size
+$.each( [
+       { type: 'row', prop: 'aoData' },
+       { type: 'column', prop: 'aoColumns' }
+], function ( i, o ) {
+       DataTable.ext.selector[ o.type ].push( function ( settings, opts, indexes ) {
+               var selected = opts.selected;
+               var data;
+               var out = [];
+
+               if ( selected !== true && selected !== false ) {
+                       return indexes;
+               }
+
+               for ( var i=0, ien=indexes.length ; i<ien ; i++ ) {
+                       data = settings[ o.prop ][ indexes[i] ];
+
+                       if ( (selected === true && data._select_selected === true) ||
+                            (selected === false && ! data._select_selected )
+                       ) {
+                               out.push( indexes[i] );
+                       }
+               }
+
+               return out;
+       } );
+} );
+
+DataTable.ext.selector.cell.push( function ( settings, opts, cells ) {
+       var selected = opts.selected;
+       var rowData;
+       var out = [];
+
+       if ( selected === undefined ) {
+               return cells;
+       }
+
+       for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
+               rowData = settings.aoData[ cells[i].row ];
+
+               if ( (selected === true && rowData._selected_cells && rowData._selected_cells[ cells[i].column ] === true) ||
+                    (selected === false && ( ! rowData._selected_cells || ! rowData._selected_cells[ cells[i].column ] ) )
+               ) {
+                       out.push( cells[i] );
+               }
+       }
+
+       return out;
+} );
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables API
+ *
+ * For complete documentation, please refer to the docs/api directory or the
+ * DataTables site
+ */
+
+// Local variables to improve compression
+var apiRegister = DataTable.Api.register;
+var apiRegisterPlural = DataTable.Api.registerPlural;
+
+apiRegister( 'select()', function () {
+       return this.iterator( 'table', function ( ctx ) {
+               DataTable.select.init( new DataTable.Api( ctx ) );
+       } );
+} );
+
+apiRegister( 'select.blurable()', function ( flag ) {
+       if ( flag === undefined ) {
+               return this.context[0]._select.blurable;
+       }
+
+       return this.iterator( 'table', function ( ctx ) {
+               ctx._select.blurable = flag;
+       } );
+} );
+
+apiRegister( 'select.toggleable()', function ( flag ) {
+       if ( flag === undefined ) {
+               return this.context[0]._select.toggleable;
+       }
+
+       return this.iterator( 'table', function ( ctx ) {
+               ctx._select.toggleable = flag;
+       } );
+} );
+
+apiRegister( 'select.info()', function ( flag ) {
+       if ( info === undefined ) {
+               return this.context[0]._select.info;
+       }
+
+       return this.iterator( 'table', function ( ctx ) {
+               ctx._select.info = flag;
+       } );
+} );
+
+apiRegister( 'select.items()', function ( items ) {
+       if ( items === undefined ) {
+               return this.context[0]._select.items;
+       }
+
+       return this.iterator( 'table', function ( ctx ) {
+               ctx._select.items = items;
+
+               eventTrigger( new DataTable.Api( ctx ), 'selectItems', [ items ] );
+       } );
+} );
+
+// Takes effect from the _next_ selection. None disables future selection, but
+// does not clear the current selection. Use the `deselect` methods for that
+apiRegister( 'select.style()', function ( style ) {
+       if ( style === undefined ) {
+               return this.context[0]._select.style;
+       }
+
+       return this.iterator( 'table', function ( ctx ) {
+               ctx._select.style = style;
+
+               if ( ! ctx._select_init ) {
+                       init( ctx );
+               }
+
+               // Add / remove mouse event handlers. They aren't required when only
+               // API selection is available
+               var dt = new DataTable.Api( ctx );
+               disableMouseSelection( dt );
+               
+               if ( style !== 'api' ) {
+                       enableMouseSelection( dt );
+               }
+
+               eventTrigger( new DataTable.Api( ctx ), 'selectStyle', [ style ] );
+       } );
+} );
+
+apiRegister( 'select.selector()', function ( selector ) {
+       if ( selector === undefined ) {
+               return this.context[0]._select.selector;
+       }
+
+       return this.iterator( 'table', function ( ctx ) {
+               disableMouseSelection( new DataTable.Api( ctx ) );
+
+               ctx._select.selector = selector;
+
+               if ( ctx._select.style !== 'api' ) {
+                       enableMouseSelection( new DataTable.Api( ctx ) );
+               }
+       } );
+} );
+
+
+
+apiRegisterPlural( 'rows().select()', 'row().select()', function ( select ) {
+       var api = this;
+
+       if ( select === false ) {
+               return this.deselect();
+       }
+
+       this.iterator( 'row', function ( ctx, idx ) {
+               clear( ctx );
+
+               ctx.aoData[ idx ]._select_selected = true;
+               $( ctx.aoData[ idx ].nTr ).addClass( ctx._select.className );
+       } );
+
+       this.iterator( 'table', function ( ctx, i ) {
+               eventTrigger( api, 'select', [ 'row', api[i] ], true );
+       } );
+
+       return this;
+} );
+
+apiRegisterPlural( 'columns().select()', 'column().select()', function ( select ) {
+       var api = this;
+
+       if ( select === false ) {
+               return this.deselect();
+       }
+
+       this.iterator( 'column', function ( ctx, idx ) {
+               clear( ctx );
+
+               ctx.aoColumns[ idx ]._select_selected = true;
+
+               var column = new DataTable.Api( ctx ).column( idx );
+
+               $( column.header() ).addClass( ctx._select.className );
+               $( column.footer() ).addClass( ctx._select.className );
+
+               column.nodes().to$().addClass( ctx._select.className );
+       } );
+
+       this.iterator( 'table', function ( ctx, i ) {
+               eventTrigger( api, 'select', [ 'column', api[i] ], true );
+       } );
+
+       return this;
+} );
+
+apiRegisterPlural( 'cells().select()', 'cell().select()', function ( select ) {
+       var api = this;
+
+       if ( select === false ) {
+               return this.deselect();
+       }
+
+       this.iterator( 'cell', function ( ctx, rowIdx, colIdx ) {
+               clear( ctx );
+
+               var data = ctx.aoData[ rowIdx ];
+
+               if ( data._selected_cells === undefined ) {
+                       data._selected_cells = [];
+               }
+
+               data._selected_cells[ colIdx ] = true;
+
+               if ( data.anCells ) {
+                       $( data.anCells[ colIdx ] ).addClass( ctx._select.className );
+               }
+       } );
+
+       this.iterator( 'table', function ( ctx, i ) {
+               eventTrigger( api, 'select', [ 'cell', api[i] ], true );
+       } );
+
+       return this;
+} );
+
+
+apiRegisterPlural( 'rows().deselect()', 'row().deselect()', function () {
+       var api = this;
+
+       this.iterator( 'row', function ( ctx, idx ) {
+               ctx.aoData[ idx ]._select_selected = false;
+               $( ctx.aoData[ idx ].nTr ).removeClass( ctx._select.className );
+       } );
+
+       this.iterator( 'table', function ( ctx, i ) {
+               eventTrigger( api, 'deselect', [ 'row', api[i] ], true );
+       } );
+
+       return this;
+} );
+
+apiRegisterPlural( 'columns().deselect()', 'column().deselect()', function () {
+       var api = this;
+
+       this.iterator( 'column', function ( ctx, idx ) {
+               ctx.aoColumns[ idx ]._select_selected = false;
+
+               var api = new DataTable.Api( ctx );
+               var column = api.column( idx );
+
+               $( column.header() ).removeClass( ctx._select.className );
+               $( column.footer() ).removeClass( ctx._select.className );
+
+               // Need to loop over each cell, rather than just using
+               // `column().nodes()` as cells which are individually selected should
+               // not have the `selected` class removed from them
+               api.cells( null, idx ).indexes().each( function (cellIdx) {
+                       var data = ctx.aoData[ cellIdx.row ];
+                       var cellSelected = data._selected_cells;
+
+                       if ( data.anCells && (! cellSelected || ! cellSelected[ cellIdx.column ]) ) {
+                               $( data.anCells[ cellIdx.column  ] ).removeClass( ctx._select.className );
+                       }
+               } );
+       } );
+
+       this.iterator( 'table', function ( ctx, i ) {
+               eventTrigger( api, 'deselect', [ 'column', api[i] ], true );
+       } );
+
+       return this;
+} );
+
+apiRegisterPlural( 'cells().deselect()', 'cell().deselect()', function () {
+       var api = this;
+
+       this.iterator( 'cell', function ( ctx, rowIdx, colIdx ) {
+               var data = ctx.aoData[ rowIdx ];
+
+               data._selected_cells[ colIdx ] = false;
+
+               // Remove class only if the cells exist, and the cell is not column
+               // selected, in which case the class should remain (since it is selected
+               // in the column)
+               if ( data.anCells && ! ctx.aoColumns[ colIdx ]._select_selected ) {
+                       $( data.anCells[ colIdx ] ).removeClass( ctx._select.className );
+               }
+       } );
+
+       this.iterator( 'table', function ( ctx, i ) {
+               eventTrigger( api, 'deselect', [ 'cell', api[i] ], true );
+       } );
+
+       return this;
+} );
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Buttons
+ */
+function i18n( label, def ) {
+       return function (dt) {
+               return dt.i18n( 'buttons.'+label, def );
+       };
+}
+
+// Common events with suitable namespaces
+function namespacedEvents ( config ) {
+       var unique = config._eventNamespace;
+
+       return 'draw.dt.DT'+unique+' select.dt.DT'+unique+' deselect.dt.DT'+unique;
+}
+
+function enabled ( dt, config ) {
+       if ( $.inArray( 'rows', config.limitTo ) !== -1 && dt.rows( { selected: true } ).any() ) {
+               return true;
+       }
+
+       if ( $.inArray( 'columns', config.limitTo ) !== -1 && dt.columns( { selected: true } ).any() ) {
+               return true;
+       }
+
+       if ( $.inArray( 'cells', config.limitTo ) !== -1 && dt.cells( { selected: true } ).any() ) {
+               return true;
+       }
+
+       return false;
+}
+
+var _buttonNamespace = 0;
+
+$.extend( DataTable.ext.buttons, {
+       selected: {
+               text: i18n( 'selected', 'Selected' ),
+               className: 'buttons-selected',
+               limitTo: [ 'rows', 'columns', 'cells' ],
+               init: function ( dt, node, config ) {
+                       var that = this;
+                       config._eventNamespace = '.select'+(_buttonNamespace++);
+
+                       // .DT namespace listeners are removed by DataTables automatically
+                       // on table destroy
+                       dt.on( namespacedEvents(config), function () {
+                               that.enable( enabled(dt, config) );
+                       } );
+
+                       this.disable();
+               },
+               destroy: function ( dt, node, config ) {
+                       dt.off( config._eventNamespace );
+               }
+       },
+       selectedSingle: {
+               text: i18n( 'selectedSingle', 'Selected single' ),
+               className: 'buttons-selected-single',
+               init: function ( dt, node, config ) {
+                       var that = this;
+                       config._eventNamespace = '.select'+(_buttonNamespace++);
+
+                       dt.on( namespacedEvents(config), function () {
+                               var count = dt.rows( { selected: true } ).flatten().length +
+                                           dt.columns( { selected: true } ).flatten().length +
+                                           dt.cells( { selected: true } ).flatten().length;
+
+                               that.enable( count === 1 );
+                       } );
+
+                       this.disable();
+               },
+               destroy: function ( dt, node, config ) {
+                       dt.off( config._eventNamespace );
+               }
+       },
+       selectAll: {
+               text: i18n( 'selectAll', 'Select all' ),
+               className: 'buttons-select-all',
+               action: function () {
+                       var items = this.select.items();
+                       this[ items+'s' ]().select();
+               }
+       },
+       selectNone: {
+               text: i18n( 'selectNone', 'Deselect all' ),
+               className: 'buttons-select-none',
+               action: function () {
+                       clear( this.settings()[0], true );
+               },
+               init: function ( dt, node, config ) {
+                       var that = this;
+                       config._eventNamespace = '.select'+(_buttonNamespace++);
+
+                       dt.on( namespacedEvents(config), function () {
+                               var count = dt.rows( { selected: true } ).flatten().length +
+                                           dt.columns( { selected: true } ).flatten().length +
+                                           dt.cells( { selected: true } ).flatten().length;
+
+                               that.enable( count > 0 );
+                       } );
+
+                       this.disable();
+               },
+               destroy: function ( dt, node, config ) {
+                       dt.off( config._eventNamespace );
+               }
+       }
+} );
+
+$.each( [ 'Row', 'Column', 'Cell' ], function ( i, item ) {
+       var lc = item.toLowerCase();
+
+       DataTable.ext.buttons[ 'select'+item+'s' ] = {
+               text: i18n( 'select'+item+'s', 'Select '+lc+'s' ),
+               className: 'buttons-select-'+lc+'s',
+               action: function () {
+                       this.select.items( lc );
+               },
+               init: function ( dt ) {
+                       var that = this;
+
+                       dt.on( 'selectItems.dt.DT', function ( e, ctx, items ) {
+                               that.active( items === lc );
+                       } );
+               }
+       };
+} );
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Initialisation
+ */
+
+// DataTables creation - check if select has been defined in the options. Note
+// this required that the table be in the document! If it isn't then something
+// needs to trigger this method unfortunately. The next major release of
+// DataTables will rework the events and address this.
+$(document).on( 'preInit.dt.dtSelect', function (e, ctx) {
+       if ( e.namespace !== 'dt' ) {
+               return;
+       }
+
+       DataTable.select.init( new DataTable.Api( ctx ) );
+} );
+
+
+return DataTable.select;
+}));
index 53bba7df4eb2cee1d8545c32abb12179555eeb85..7f2cb5f122aba8423161e99e4f7a0b469477756e 100644 (file)
@@ -1,27 +1,15 @@
-/*
- * This combined file was created by the DataTables downloader builder:
- *   https://datatables.net/download
- *
- * To rebuild or modify this file with the latest versions of the included
- * software please visit:
- *   https://datatables.net/download/#dt/dt-1.10.16
- *
- * Included libraries:
- *   DataTables 1.10.16
- */
-
-/*! DataTables 1.10.16
- * Â©2008-2017 SpryMedia Ltd - datatables.net/license
+/*! DataTables 1.10.20
+ * Â©2008-2019 SpryMedia Ltd - datatables.net/license
  */
 
 /**
  * @summary     DataTables
  * @description Paginate, search and order HTML tables
- * @version     1.10.16
+ * @version     1.10.20
  * @file        jquery.dataTables.js
  * @author      SpryMedia Ltd
  * @contact     www.datatables.net
- * @copyright   Copyright 2008-2017 SpryMedia Ltd.
+ * @copyright   Copyright 2008-2019 SpryMedia Ltd.
  *
  * This source file is free software, available under the following license:
  *   MIT license - http://datatables.net/license
                        _fnCamelToHungarian( defaults.column, defaults.column, true );
                        
                        /* Setting up the initialisation object */
-                       _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
+                       _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true );
                        
                        
                        
                                var s = allSettings[i];
                        
                                /* Base check on table node */
-                               if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
-                               {
+                               if (
+                                       s.nTable == this ||
+                                       (s.nTHead && s.nTHead.parentNode == this) ||
+                                       (s.nTFoot && s.nTFoot.parentNode == this)
+                               ) {
                                        var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
                                        var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
                        
                        
                        // Backwards compatibility, before we apply all the defaults
                        _fnCompatOpts( oInit );
-                       
-                       if ( oInit.oLanguage )
-                       {
-                               _fnLanguageCompat( oInit.oLanguage );
-                       }
+                       _fnLanguageCompat( oInit.oLanguage );
                        
                        // If the length menu is given, but the init display length is not, use the length menu
                        if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
        var _api_registerPlural; // DataTable.Api.registerPlural
        
        var _re_dic = {};
-       var _re_new_lines = /[\r\n]/g;
+       var _re_new_lines = /[\r\n\u2028]/g;
        var _re_html = /<.*?>/g;
        
        // This is not strict ISO8601 - Date.parse() is quite lax, although
        // - fr - Swiss Franc
        // - kr - Swedish krona, Norwegian krone and Danish krone
        // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
+       // - Éƒ - Bitcoin
+       // - Îž - Ethereum
        //   standards as thousands separators.
-       var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
+       var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
        
        
        var _empty = function ( d ) {
         */
        function _fnLanguageCompat( lang )
        {
+               // Note the use of the Hungarian notation for the parameters in this method as
+               // this is called after the mapping of camelCase to Hungarian
                var defaults = DataTable.defaults.oLanguage;
-               var zeroRecords = lang.sZeroRecords;
        
-               /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
-                * sZeroRecords - assuming that is given.
-                */
-               if ( ! lang.sEmptyTable && zeroRecords &&
-                       defaults.sEmptyTable === "No data available in table" )
-               {
-                       _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
+               // Default mapping
+               var defaultDecimal = defaults.sDecimal;
+               if ( defaultDecimal ) {
+                       _addNumericSort( defaultDecimal );
                }
        
-               /* Likewise with loading records */
-               if ( ! lang.sLoadingRecords && zeroRecords &&
-                       defaults.sLoadingRecords === "Loading..." )
-               {
-                       _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
-               }
+               if ( lang ) {
+                       var zeroRecords = lang.sZeroRecords;
        
-               // Old parameter name of the thousands separator mapped onto the new
-               if ( lang.sInfoThousands ) {
-                       lang.sThousands = lang.sInfoThousands;
-               }
+                       // Backwards compatibility - if there is no sEmptyTable given, then use the same as
+                       // sZeroRecords - assuming that is given.
+                       if ( ! lang.sEmptyTable && zeroRecords &&
+                               defaults.sEmptyTable === "No data available in table" )
+                       {
+                               _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
+                       }
+       
+                       // Likewise with loading records
+                       if ( ! lang.sLoadingRecords && zeroRecords &&
+                               defaults.sLoadingRecords === "Loading..." )
+                       {
+                               _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
+                       }
        
-               var decimal = lang.sDecimal;
-               if ( decimal ) {
-                       _addNumericSort( decimal );
+                       // Old parameter name of the thousands separator mapped onto the new
+                       if ( lang.sInfoThousands ) {
+                               lang.sThousands = lang.sInfoThousands;
+                       }
+       
+                       var decimal = lang.sDecimal;
+                       if ( decimal && defaultDecimal !== decimal ) {
+                               _addNumericSort( decimal );
+                       }
                }
        }
        
                        _fnCompatCols( oOptions );
        
                        // Map camel case parameters to their Hungarian counterparts
-                       _fnCamelToHungarian( DataTable.defaults.column, oOptions );
+                       _fnCamelToHungarian( DataTable.defaults.column, oOptions, true );
        
                        /* Backwards compatibility for mDataProp */
                        if ( oOptions.mDataProp !== undefined && !oOptions.mData )
                        rowData = row._aData,
                        cells = [],
                        nTr, nTd, oCol,
-                       i, iLen;
+                       i, iLen, create;
        
                if ( row.nTr === null )
                {
                        for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
                        {
                                oCol = oSettings.aoColumns[i];
+                               create = nTrIn ? false : true;
        
-                               nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
+                               nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
                                nTd._DT_CellIndex = {
                                        row: iRow,
                                        column: i
                                cells.push( nTd );
        
                                // Need to create the HTML if new, or if a rendering function is defined
-                               if ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&
+                               if ( create || ((!nTrIn || oCol.mRender || oCol.mData !== i) &&
                                         (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
-                               ) {
+                               )) {
                                        nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
                                }
        
                                }
                        }
        
-                       _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
+                       _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] );
                }
        
                // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
                                // iRowCount and j are not currently documented. Are they at all
                                // useful?
                                _fnCallbackFire( oSettings, 'aoRowCallback', null,
-                                       [nRow, aoData._aData, iRowCount, j] );
+                                       [nRow, aoData._aData, iRowCount, j, iDataIndex] );
        
                                anRows.push( nRow );
                                iRowCount++;
                {
                        ajaxData = ajax.data;
        
-                       var newData = $.isFunction( ajaxData ) ?
+                       var newData = typeof ajaxData === 'function' ?
                                ajaxData( data, oSettings ) :  // fn can manipulate data or return
                                ajaxData;                      // an object object or array to merge
        
                        // If the function returned something, use that alone
-                       data = $.isFunction( ajaxData ) && newData ?
+                       data = typeof ajaxData === 'function' && newData ?
                                newData :
                                $.extend( true, data, newData );
        
                                url: ajax || oSettings.sAjaxSource
                        } ) );
                }
-               else if ( $.isFunction( ajax ) )
+               else if ( typeof ajax === 'function' )
                {
                        // Is a function - let the caller define what needs to be done
                        oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
                        // New search - start from the master array
                        if ( invalidated ||
                                 force ||
+                                regex ||
                                 prevSearch.length > input.length ||
                                 input.indexOf(prevSearch) !== 0 ||
                                 settings.bSorted // On resort, the display master needs to be
                                        }
        
                                        if ( cellData.replace ) {
-                                               cellData = cellData.replace(/[\r\n]/g, '');
+                                               cellData = cellData.replace(/[\r\n\u2028]/g, '');
                                        }
        
                                        filterData.push( cellData );
                // both match, but we want to hide it completely. We want to also fix their
                // width to what they currently are
                _fnApplyToChildren( function(nSizer, i) {
-                       nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
+                       nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>';
+                       nSizer.childNodes[0].style.height = "0";
+                       nSizer.childNodes[0].style.overflow = "hidden";
                        nSizer.style.width = headerWidths[i];
                }, headerSrcEls );
        
                if ( footer )
                {
                        _fnApplyToChildren( function(nSizer, i) {
-                               nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+footerContent[i]+'</div>';
+                               nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
+                               nSizer.childNodes[0].style.height = "0";
+                               nSizer.childNodes[0].style.overflow = "hidden";
                                nSizer.style.width = footerWidths[i];
                        }, footerSrcEls );
                }
                table.children('colgroup').insertBefore( table.children('thead') );
        
                /* Adjust the position of the header in case we loose the y-scrollbar */
-               divBody.scroll();
+               divBody.trigger('scroll');
        
                // If sorting or filtering has occurred, jump the scrolling back to the top
                // only if we aren't holding the position
        
                        _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );
                        callback();
-               }
+               };
        
                if ( ! settings.oFeatures.bStateSave ) {
                        callback();
        {
                $(n)
                        .on( 'click.DT', oData, function (e) {
-                                       n.blur(); // Remove focus outline for mouse users
+                                       $(n).blur(); // Remove focus outline for mouse users
                                        fn(e);
                                } )
                        .on( 'keypress.DT', oData, function (e){
                var ctxSettings = function ( o ) {
                        var a = _toSettings( o );
                        if ( a ) {
-                               settings = settings.concat( a );
+                               settings.push.apply( settings, a );
                        }
                };
        
        
                var
                        i, ien,
-                       j, jen,
-                       struct, inner,
+                       struct,
                        methodScoping = function ( scope, fn, struc ) {
                                return function () {
                                        var ret = fn.apply( scope, arguments );
                        struct = ext[i];
        
                        // Value
-                       obj[ struct.name ] = typeof struct.val === 'function' ?
+                       obj[ struct.name ] = struct.type === 'function' ?
                                methodScoping( scope, struct.val, struct ) :
-                               $.isPlainObject( struct.val ) ?
+                               struct.type === 'object' ?
                                        {} :
                                        struct.val;
        
                                        name:      key,
                                        val:       {},
                                        methodExt: [],
-                                       propExt:   []
+                                       propExt:   [],
+                                       type:      'object'
                                };
                                struct.push( src );
                        }
        
                        if ( i === ien-1 ) {
                                src.val = val;
+                               src.type = typeof val === 'function' ?
+                                       'function' :
+                                       $.isPlainObject( val ) ?
+                                               'object' :
+                                               'other';
                        }
                        else {
                                struct = method ?
                }
        };
        
-       
        _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
                _Api.register( pluralName, val );
        
                        }
                }
                else if ( order == 'current' || order == 'applied' ) {
-                       a = search == 'none' ?
-                               displayMaster.slice() :                      // no search
-                               search == 'applied' ?
-                                       displayFiltered.slice() :                // applied search
-                                       $.map( displayMaster, function (el, i) { // removed search
-                                               return $.inArray( el, displayFiltered ) === -1 ? el : null;
-                                       } );
+                       if ( search == 'none') {
+                               a = displayMaster.slice();
+                       }
+                       else if ( search == 'applied' ) {
+                               a = displayFiltered.slice();
+                       }
+                       else if ( search == 'removed' ) {
+                               // O(n+m) solution by creating a hash map
+                               var displayFilteredMap = {};
+       
+                               for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
+                                       displayFilteredMap[displayFiltered[i]] = null;
+                               }
+       
+                               a = $.map( displayMaster, function (el) {
+                                       return ! displayFilteredMap.hasOwnProperty(el) ?
+                                               el :
+                                               null;
+                               } );
+                       }
                }
                else if ( order == 'index' || order == 'original' ) {
                        for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
         * {array}     - jQuery array of nodes, or simply an array of TR nodes
         *
         */
-       
-       
        var __row_selector = function ( settings, selector, opts )
        {
                var rows;
                var run = function ( sel ) {
                        var selInt = _intVal( sel );
                        var i, ien;
+                       var aoData = settings.aoData;
        
                        // Short cut - selector is a number and no options provided (default is
                        // all records, so no need to check if the index is in there, since it
                        // Selector - function
                        if ( typeof sel === 'function' ) {
                                return $.map( rows, function (idx) {
-                                       var row = settings.aoData[ idx ];
+                                       var row = aoData[ idx ];
                                        return sel( idx, row._aData, row.nTr ) ? idx : null;
                                } );
                        }
        
-                       // Get nodes in the order from the `rows` array with null values removed
-                       var nodes = _removeEmpty(
-                               _pluck_order( settings.aoData, rows, 'nTr' )
-                       );
-       
                        // Selector - node
                        if ( sel.nodeName ) {
-                               if ( sel._DT_RowIndex !== undefined ) {
-                                       return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup
+                               var rowIdx = sel._DT_RowIndex;  // Property added by DT for fast lookup
+                               var cellIdx = sel._DT_CellIndex;
+       
+                               if ( rowIdx !== undefined ) {
+                                       // Make sure that the row is actually still present in the table
+                                       return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?
+                                               [ rowIdx ] :
+                                               [];
                                }
-                               else if ( sel._DT_CellIndex ) {
-                                       return [ sel._DT_CellIndex.row ];
+                               else if ( cellIdx ) {
+                                       return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ?
+                                               [ cellIdx.row ] :
+                                               [];
                                }
                                else {
                                        var host = $(sel).closest('*[data-dt-row]');
                                // need to fall through to jQuery in case there is DOM id that
                                // matches
                        }
+                       
+                       // Get nodes in the order from the `rows` array with null values removed
+                       var nodes = _removeEmpty(
+                               _pluck_order( settings.aoData, rows, 'nTr' )
+                       );
        
                        // Selector - jQuery selector string, array of nodes or jQuery object/
                        // As jQuery's .filter() allows jQuery objects to be passed in filter,
                }
        
                // Set
-               ctx[0].aoData[ this[0] ]._aData = data;
+               var row = ctx[0].aoData[ this[0] ];
+               row._aData = data;
+       
+               // If the DOM has an id, and the data source is an array
+               if ( $.isArray( data ) && row.nTr.id ) {
+                       _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id );
+               }
        
                // Automatically invalidate
                _fnInvalidate( ctx[0], this[0], 'data' );
        
                // Common actions
                col.bVisible = vis;
-               _fnDrawHead( settings, settings.aoHeader );
-               _fnDrawHead( settings, settings.aoFooter );
-       
-               _fnSaveState( settings );
        };
        
        
        } );
        
        _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
+               var that = this;
                var ret = this.iterator( 'column', function ( settings, column ) {
                        if ( vis === undefined ) {
                                return settings.aoColumns[ column ].bVisible;
        
                // Group the column visibility changes
                if ( vis !== undefined ) {
-                       // Second loop once the first is done for events
-                       this.iterator( 'column', function ( settings, column ) {
-                               _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
-                       } );
+                       this.iterator( 'table', function ( settings ) {
+                               // Redraw the header after changes
+                               _fnDrawHead( settings, settings.aoHeader );
+                               _fnDrawHead( settings, settings.aoFooter );
+               
+                               // Update colspan for no records display. Child rows and extensions will use their own
+                               // listeners to do this - only need to update the empty table item here
+                               if ( ! settings.aiDisplay.length ) {
+                                       $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
+                               }
+               
+                               _fnSaveState( settings );
        
-                       if ( calc === undefined || calc ) {
-                               this.columns.adjust();
-                       }
+                               // Second loop once the first is done for events
+                               that.iterator( 'column', function ( settings, column ) {
+                                       _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
+                               } );
+       
+                               if ( calc === undefined || calc ) {
+                                       that.columns.adjust();
+                               }
+                       });
                }
        
                return ret;
                        
                        // Selector - index
                        if ( $.isPlainObject( s ) ) {
-                               return [s];
+                               // Valid cell index and its in the array of selectable rows
+                               return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ?
+                                       [s] :
+                                       [];
                        }
        
                        // Selector - jQuery filtered cells
                        } );
                }
        
+               // The default built in options need to apply to row and columns
+               var internalOpts = opts ? {
+                       page: opts.page,
+                       order: opts.order,
+                       search: opts.search
+               } : {};
+       
                // Row + column selector
-               var columns = this.columns( columnSelector, opts );
-               var rows = this.rows( rowSelector, opts );
-               var a, i, ien, j, jen;
+               var columns = this.columns( columnSelector, internalOpts );
+               var rows = this.rows( rowSelector, internalOpts );
+               var i, ien, j, jen;
        
-               var cells = this.iterator( 'table', function ( settings, idx ) {
-                       a = [];
+               var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) {
+                       var a = [];
        
                        for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
                                for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
                        return a;
                }, 1 );
        
+               // There is currently only one extension which uses a cell selector extension
+               // It is a _major_ performance drag to run this if it isn't needed, so this is
+               // an extension specific check at the moment
+               var cells = opts && opts.selected ?
+                       this.cells( cellsNoOpts, opts ) :
+                       cellsNoOpts;
+       
                $.extend( cells.selector, {
                        cols: columnSelector,
                        rows: rowSelector,
        
                return resolved.replace( '%d', plural ); // nb: plural might be undefined,
        } );
-
        /**
         * Version string for plug-ins to check compatibility. Allowed format is
         * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
         *  @type string
         *  @default Version number
         */
-       DataTable.version = "1.10.16";
+       DataTable.version = "1.10.20";
 
        /**
         * Private data store, containing all of the settings objects that are
                 *          { "data": "engine" },
                 *          { "data": "browser" },
                 *          { "data": "platform.inner" },
-                *          { "data": "platform.details.0" },
-                *          { "data": "platform.details.1" }
+                *          { "data": "details.0" },
+                *          { "data": "details.1" }
                 *        ]
                 *      } );
                 *    } );
                 *
                 *  @type string
                 */
-               build:"dt/dt-1.10.16",
+               builder: "-source-",
        
        
                /**
                         *    $.fn.dataTable.ext.type.detect.push(
                         *      function ( data, settings ) {
                         *        // Check the numeric part
-                        *        if ( ! $.isNumeric( data.substring(1) ) ) {
+                        *        if ( ! data.substring(1).match(/[0-9]/) ) {
                         *          return null;
                         *        }
                         *
                                var btnDisplay, btnClass, counter=0;
        
                                var attach = function( container, buttons ) {
-                                       var i, ien, node, button;
+                                       var i, ien, node, button, tabIndex;
+                                       var disabledClass = classes.sPageButtonDisabled;
                                        var clickHandler = function ( e ) {
                                                _fnPageChange( settings, e.data.action, true );
                                        };
                                                }
                                                else {
                                                        btnDisplay = null;
-                                                       btnClass = '';
+                                                       btnClass = button;
+                                                       tabIndex = settings.iTabIndex;
        
                                                        switch ( button ) {
                                                                case 'ellipsis':
        
                                                                case 'first':
                                                                        btnDisplay = lang.sFirst;
-                                                                       btnClass = button + (page > 0 ?
-                                                                               '' : ' '+classes.sPageButtonDisabled);
+       
+                                                                       if ( page === 0 ) {
+                                                                               tabIndex = -1;
+                                                                               btnClass += ' ' + disabledClass;
+                                                                       }
                                                                        break;
        
                                                                case 'previous':
                                                                        btnDisplay = lang.sPrevious;
-                                                                       btnClass = button + (page > 0 ?
-                                                                               '' : ' '+classes.sPageButtonDisabled);
+       
+                                                                       if ( page === 0 ) {
+                                                                               tabIndex = -1;
+                                                                               btnClass += ' ' + disabledClass;
+                                                                       }
                                                                        break;
        
                                                                case 'next':
                                                                        btnDisplay = lang.sNext;
-                                                                       btnClass = button + (page < pages-1 ?
-                                                                               '' : ' '+classes.sPageButtonDisabled);
+       
+                                                                       if ( page === pages-1 ) {
+                                                                               tabIndex = -1;
+                                                                               btnClass += ' ' + disabledClass;
+                                                                       }
                                                                        break;
        
                                                                case 'last':
                                                                        btnDisplay = lang.sLast;
-                                                                       btnClass = button + (page < pages-1 ?
-                                                                               '' : ' '+classes.sPageButtonDisabled);
+       
+                                                                       if ( page === pages-1 ) {
+                                                                               tabIndex = -1;
+                                                                               btnClass += ' ' + disabledClass;
+                                                                       }
                                                                        break;
        
                                                                default:
                                                                                'aria-controls': settings.sTableId,
                                                                                'aria-label': aria[ button ],
                                                                                'data-dt-idx': counter,
-                                                                               'tabindex': settings.iTabIndex,
+                                                                               'tabindex': tabIndex,
                                                                                'id': idx === 0 && typeof button === 'string' ?
                                                                                        settings.sTableId +'_'+ button :
                                                                                        null
        $.extend( _ext.type.order, {
                // Dates
                "date-pre": function ( d ) {
-                       return Date.parse( d ) || -Infinity;
+                       var ts = Date.parse( d );
+                       return isNaN(ts) ? -Infinity : ts;
                },
        
                // html
        
                text: function () {
                        return {
-                               display: __htmlEscapeEntities
+                               display: __htmlEscapeEntities,
+                               filter: __htmlEscapeEntities
                        };
                }
        };
                _fnRenderer: _fnRenderer,
                _fnDataSource: _fnDataSource,
                _fnRowAttributes: _fnRowAttributes,
+               _fnExtend: _fnExtend,
                _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
                                                // in 1.10, so this dead-end function is
                                                // added to prevent errors
 
        /**
         * Processing event, fired when DataTables is doing some kind of processing
-        * (be it, order, searcg or anything else). It can be used to indicate to
+        * (be it, order, search or anything else). It can be used to indicate to
         * the end user that there is something happening, or that something has
         * finished.
         *  @name DataTable#processing.dt
 
        return $.fn.dataTable;
 }));
-
-
index f7bbb37c2e715b48ce3831f8cc84017bc42093ff..d8e63ed77bca3d9cb063697fb0c5227cf318e876 100644 (file)
@@ -62,23 +62,152 @@ div.dt-button-collection-title:empty {
   display: none;
 }
 
-div.dt-buttons {
+button.dt-button,
+div.dt-button,
+a.dt-button {
   position: relative;
-  float: left;
-}
-div.dt-buttons .dt-button {
-  margin-right: 0;
-}
-div.dt-buttons .dt-button span.ui-icon {
   display: inline-block;
-  vertical-align: middle;
-  margin-top: -2px;
+  box-sizing: border-box;
+  margin-right: 0.333em;
+  margin-bottom: 0.333em;
+  padding: 0.5em 1em;
+  border: 1px solid #999;
+  border-radius: 2px;
+  cursor: pointer;
+  font-size: 0.88em;
+  line-height: 1.6em;
+  color: black;
+  white-space: nowrap;
+  overflow: hidden;
+  background-color: #e9e9e9;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, white 0%, #e9e9e9 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, white 0%, #e9e9e9 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, white 0%, #e9e9e9 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, white 0%, #e9e9e9 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, white 0%, #e9e9e9 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='white', EndColorStr='#e9e9e9');
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-decoration: none;
+  outline: none;
+  text-overflow: ellipsis;
+}
+button.dt-button.disabled,
+div.dt-button.disabled,
+a.dt-button.disabled {
+  color: #999;
+  border: 1px solid #d0d0d0;
+  cursor: default;
+  background-color: #f9f9f9;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, #ffffff 0%, #f9f9f9 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ffffff', EndColorStr='#f9f9f9');
+}
+button.dt-button:active:not(.disabled), button.dt-button.active:not(.disabled),
+div.dt-button:active:not(.disabled),
+div.dt-button.active:not(.disabled),
+a.dt-button:active:not(.disabled),
+a.dt-button.active:not(.disabled) {
+  background-color: #e2e2e2;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, #f3f3f3 0%, #e2e2e2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f3f3f3', EndColorStr='#e2e2e2');
+  box-shadow: inset 1px 1px 3px #999999;
+}
+button.dt-button:active:not(.disabled):hover:not(.disabled), button.dt-button.active:not(.disabled):hover:not(.disabled),
+div.dt-button:active:not(.disabled):hover:not(.disabled),
+div.dt-button.active:not(.disabled):hover:not(.disabled),
+a.dt-button:active:not(.disabled):hover:not(.disabled),
+a.dt-button.active:not(.disabled):hover:not(.disabled) {
+  box-shadow: inset 1px 1px 3px #999999;
+  background-color: #cccccc;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, #eaeaea 0%, #cccccc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#eaeaea', EndColorStr='#cccccc');
+}
+button.dt-button:hover,
+div.dt-button:hover,
+a.dt-button:hover {
+  text-decoration: none;
+}
+button.dt-button:hover:not(.disabled),
+div.dt-button:hover:not(.disabled),
+a.dt-button:hover:not(.disabled) {
+  border: 1px solid #666;
+  background-color: #e0e0e0;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, #f9f9f9 0%, #e0e0e0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f9f9f9', EndColorStr='#e0e0e0');
+}
+button.dt-button:focus:not(.disabled),
+div.dt-button:focus:not(.disabled),
+a.dt-button:focus:not(.disabled) {
+  border: 1px solid #426c9e;
+  text-shadow: 0 1px 0 #c4def1;
+  outline: none;
+  background-color: #79ace9;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, #bddef4 0%, #79ace9 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, #bddef4 0%, #79ace9 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, #bddef4 0%, #79ace9 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, #bddef4 0%, #79ace9 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, #bddef4 0%, #79ace9 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#bddef4', EndColorStr='#79ace9');
 }
-div.dt-buttons .dt-button:active {
+
+.dt-button embed {
   outline: none;
 }
-div.dt-buttons .dt-button:hover > span {
-  background-color: rgba(0, 0, 0, 0.05);
+
+div.dt-buttons {
+  position: relative;
+  float: left;
+}
+div.dt-buttons.buttons-right {
+  float: right;
 }
 
 div.dt-button-collection {
@@ -90,32 +219,43 @@ div.dt-button-collection {
   padding: 8px 8px 4px 8px;
   border: 1px solid #ccc;
   border: 1px solid rgba(0, 0, 0, 0.4);
-  background-color: #f3f3f3;
-  background-color: rgba(255, 255, 255, 0.3);
+  background-color: white;
   overflow: hidden;
   z-index: 2002;
   border-radius: 5px;
   box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
-  z-index: 2002;
-  -webkit-column-gap: 0;
-  -moz-column-gap: 0;
-  -ms-column-gap: 0;
-  -o-column-gap: 0;
-  column-gap: 0;
+  box-sizing: border-box;
 }
-div.dt-button-collection .dt-button {
+div.dt-button-collection button.dt-button,
+div.dt-button-collection div.dt-button,
+div.dt-button-collection a.dt-button {
   position: relative;
   left: 0;
   right: 0;
   width: 100%;
-  box-sizing: border-box;
   display: block;
   float: none;
-  margin-right: 0;
   margin-bottom: 4px;
+  margin-right: 0;
 }
-div.dt-button-collection .dt-button:hover > span {
-  background-color: rgba(0, 0, 0, 0.05);
+div.dt-button-collection button.dt-button:active:not(.disabled), div.dt-button-collection button.dt-button.active:not(.disabled),
+div.dt-button-collection div.dt-button:active:not(.disabled),
+div.dt-button-collection div.dt-button.active:not(.disabled),
+div.dt-button-collection a.dt-button:active:not(.disabled),
+div.dt-button-collection a.dt-button.active:not(.disabled) {
+  background-color: #dadada;
+  /* Fallback */
+  background-image: -webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
+  /* Chrome 10+, Saf5.1+, iOS 5+ */
+  background-image: -moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
+  /* FF3.6 */
+  background-image: -ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
+  /* IE10 */
+  background-image: -o-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
+  /* Opera 11.10+ */
+  background-image: linear-gradient(to bottom, #f0f0f0 0%, #dadada 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f0f0f0', EndColorStr='#dadada');
+  box-shadow: inset 1px 1px 3px #666;
 }
 div.dt-button-collection.fixed {
   position: fixed;
index 7f3d64610e99fff6902255ae8bee323f9a461202..44e04911d9f72c01a8ab9b5b9b18ba6a5b4ea374 100644 (file)
@@ -1,15 +1,3 @@
-/*
- * This combined file was created by the DataTables downloader builder:
- *   https://datatables.net/download
- *
- * To rebuild or modify this file with the latest versions of the included
- * software please visit:
- *   https://datatables.net/download/#dt/dt-1.10.16
- *
- * Included libraries:
- *   DataTables 1.10.16
- */
-
 /*
  * Table styles
  */
@@ -458,5 +446,3 @@ table.dataTable td {
     margin-top: 0.5em;
   }
 }
-
-
diff --git a/gui/baculum/themes/Baculum-v2/css/select.jqueryui.css b/gui/baculum/themes/Baculum-v2/css/select.jqueryui.css
new file mode 100644 (file)
index 0000000..60ab3d7
--- /dev/null
@@ -0,0 +1,105 @@
+table.dataTable tbody > tr.selected,
+table.dataTable tbody > tr > .selected {
+  background-color: #B0BED9;
+}
+table.dataTable.stripe tbody > tr.odd.selected,
+table.dataTable.stripe tbody > tr.odd > .selected, table.dataTable.display tbody > tr.odd.selected,
+table.dataTable.display tbody > tr.odd > .selected {
+  background-color: #acbad4;
+}
+table.dataTable.hover tbody > tr.selected:hover,
+table.dataTable.hover tbody > tr > .selected:hover, table.dataTable.display tbody > tr.selected:hover,
+table.dataTable.display tbody > tr > .selected:hover {
+  background-color: #aab7d1;
+}
+table.dataTable.order-column tbody > tr.selected > .sorting_1,
+table.dataTable.order-column tbody > tr.selected > .sorting_2,
+table.dataTable.order-column tbody > tr.selected > .sorting_3,
+table.dataTable.order-column tbody > tr > .selected, table.dataTable.display tbody > tr.selected > .sorting_1,
+table.dataTable.display tbody > tr.selected > .sorting_2,
+table.dataTable.display tbody > tr.selected > .sorting_3,
+table.dataTable.display tbody > tr > .selected {
+  background-color: #acbad5;
+}
+table.dataTable.display tbody > tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody > tr.odd.selected > .sorting_1 {
+  background-color: #a6b4cd;
+}
+table.dataTable.display tbody > tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody > tr.odd.selected > .sorting_2 {
+  background-color: #a8b5cf;
+}
+table.dataTable.display tbody > tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody > tr.odd.selected > .sorting_3 {
+  background-color: #a9b7d1;
+}
+table.dataTable.display tbody > tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody > tr.even.selected > .sorting_1 {
+  background-color: #acbad5;
+}
+table.dataTable.display tbody > tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody > tr.even.selected > .sorting_2 {
+  background-color: #aebcd6;
+}
+table.dataTable.display tbody > tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody > tr.even.selected > .sorting_3 {
+  background-color: #afbdd8;
+}
+table.dataTable.display tbody > tr.odd > .selected, table.dataTable.order-column.stripe tbody > tr.odd > .selected {
+  background-color: #a6b4cd;
+}
+table.dataTable.display tbody > tr.even > .selected, table.dataTable.order-column.stripe tbody > tr.even > .selected {
+  background-color: #acbad5;
+}
+table.dataTable.display tbody > tr.selected:hover > .sorting_1, table.dataTable.order-column.hover tbody > tr.selected:hover > .sorting_1 {
+  background-color: #a2aec7;
+}
+table.dataTable.display tbody > tr.selected:hover > .sorting_2, table.dataTable.order-column.hover tbody > tr.selected:hover > .sorting_2 {
+  background-color: #a3b0c9;
+}
+table.dataTable.display tbody > tr.selected:hover > .sorting_3, table.dataTable.order-column.hover tbody > tr.selected:hover > .sorting_3 {
+  background-color: #a5b2cb;
+}
+table.dataTable.display tbody > tr:hover > .selected,
+table.dataTable.display tbody > tr > .selected:hover, table.dataTable.order-column.hover tbody > tr:hover > .selected,
+table.dataTable.order-column.hover tbody > tr > .selected:hover {
+  background-color: #a2aec7;
+}
+table.dataTable tbody td.select-checkbox,
+table.dataTable tbody th.select-checkbox {
+  position: relative;
+}
+table.dataTable tbody td.select-checkbox:before, table.dataTable tbody td.select-checkbox:after,
+table.dataTable tbody th.select-checkbox:before,
+table.dataTable tbody th.select-checkbox:after {
+  display: block;
+  position: absolute;
+  top: 1.2em;
+  left: 50%;
+  width: 12px;
+  height: 12px;
+  box-sizing: border-box;
+}
+table.dataTable tbody td.select-checkbox:before,
+table.dataTable tbody th.select-checkbox:before {
+  content: ' ';
+  margin-top: -6px;
+  margin-left: -6px;
+  border: 1px solid black;
+  border-radius: 3px;
+}
+table.dataTable tr.selected td.select-checkbox:after,
+table.dataTable tr.selected th.select-checkbox:after {
+  content: '\2714';
+  margin-top: -11px;
+  margin-left: -4px;
+  text-align: center;
+  text-shadow: 1px 1px #B0BED9, -1px -1px #B0BED9, 1px -1px #B0BED9, -1px 1px #B0BED9;
+}
+
+div.dataTables_wrapper span.select-info,
+div.dataTables_wrapper span.select-item {
+  margin-left: 0.5em;
+}
+
+@media screen and (max-width: 640px) {
+  div.dataTables_wrapper span.select-info,
+  div.dataTables_wrapper span.select-item {
+    margin-left: 0;
+    display: block;
+  }
+}