dark mode and websockets
[kismet-logviewer.git] / logviewer / static / js / dataTables.pageResize.js
1 /*! PageResize for DataTables v1.0.0
2  * 2015 SpryMedia Ltd - datatables.net/license
3  */
4
5 /**
6  * @summary     PageResize
7  * @description Automatically alter the DataTables page length to fit the table
8      into a container
9  * @version     1.0.0
10  * @file        dataTables.pageResize.js
11  * @author      SpryMedia Ltd (www.sprymedia.co.uk)
12  * @contact     www.sprymedia.co.uk/contact
13  * @copyright   Copyright 2015 SpryMedia Ltd.
14  * 
15  * License      MIT - http://datatables.net/license/mit
16  *
17  * This feature plug-in for DataTables will automatically change the DataTables
18  * page length in order to fit inside its container. This can be particularly
19  * useful for control panels and other interfaces which resize dynamically with
20  * the user's browser window instead of scrolling.
21  *
22  * Page resizing in DataTables can be enabled by using any one of the following
23  * options:
24  *
25  * * Adding the class `pageResize` to the HTML table
26  * * Setting the `pageResize` parameter in the DataTables initialisation to
27  *   be true - i.e. `pageResize: true`
28  * * Setting the `pageResize` parameter to be true in the DataTables
29  *   defaults (thus causing all tables to have this feature) - i.e.
30  *   `$.fn.dataTable.defaults.pageResize = true`.
31  * * Creating a new instance: `new $.fn.dataTable.PageResize( table );` where
32  *   `table` is a DataTable's API instance.
33  *
34  * For more detailed information please see:
35  *     http://datatables.net/blog/2015-04-10
36  */
37 (function( factory ){
38         if ( typeof define === 'function' && define.amd ) {
39                 // AMD
40                 define( ['jquery', 'datatables.net'], function ( $ ) {
41                         return factory( $, window, document );
42                 } );
43         }
44         else if ( typeof exports === 'object' ) {
45                 // CommonJS
46                 module.exports = function (root, $) {
47                         if ( ! root ) {
48                                 root = window;
49                         }
50
51                         if ( ! $ || ! $.fn.dataTable ) {
52                                 $ = require('datatables.net')(root, $).$;
53                         }
54
55                         return factory( $, root, root.document );
56                 };
57         }
58         else {
59                 // Browser
60                 factory( jQuery, window, document );
61         }
62 }(function( $, window, document, undefined ) {
63 'use strict';
64
65
66 var PageResize = function ( dt, pageResizeManualDelta )
67 {
68         var table = dt.table();
69
70         this.s = {
71                 dt:        dt,
72                 host:      $(table.container()).parent(),
73                 header:    $(table.header()),
74                 footer:    $(table.footer()),
75                 body:      $(table.body()),
76                 container: $(table.container()),
77                 table:     $(table.node()),
78                 delta:     pageResizeManualDelta
79     };
80
81     this.sizes = {
82         offsetTop: this._getOffsetTop(),
83         tableHeight: this._getTableHeight(),
84         containerHeight: this._getContainerHeight(),
85         headerHeight: this._getHeaderHeight(),
86         footerHeight: this._getFooterHeight()
87     };
88
89         var host = this.s.host;
90         if ( host.css('position') === 'static' ) {
91                 host.css( 'position', 'relative' );
92         }
93
94     var onDestroy = function () {
95         dt.off('.pageResize', onDestroy);
96         this.s.obj && this.s.obj.remove();
97     }.bind(this);
98     dt.on('destroy.pageResize', onDestroy);
99
100         this._attach();
101
102         // Delay the initial sizing until the table is fully initialized
103         // such that the pagination element is also added and can be taken
104         // into account.
105         var initEvent = 'init.pageResize';
106         dt.on(initEvent, function () {
107                 dt.off(initEvent);
108                 this._size();
109         }.bind(this));
110 };
111
112
113 PageResize.prototype = {
114         _size: function ()
115         {
116                 var settings = this.s;
117                 var dt = settings.dt;
118                 var t = dt.table();
119                 var rows = $( 'tr', settings.body );
120                 var rowHeight = rows.eq( rows.length > 1 ? 1 : 0 ).height(); // Attempt to use the second row if poss, for top and bottom border
121                 var availableHeight = settings.host.height();
122                 var scrolling = t.header().parentNode !== t.body().parentNode;
123         var delta = settings.delta;
124
125         var offsetTop = this.sizes.offsetTop = this._getOffsetTop();
126         var tableHeight = this.sizes.tableHeight = this._getTableHeight();
127         var containerHeight = this.sizes.containerHeight = this._getContainerHeight();
128         var headerHeight = this.sizes.headerHeight = this._getHeaderHeight();
129         var footerHeight = this.sizes.footerHeight = this._getFooterHeight();
130
131                 // Subtract the height of the header, footer and the elements
132                 // surrounding the table
133                 if ( ! scrolling ) {
134                         if ( t.header() ) {
135                             availableHeight -= headerHeight;
136                         }
137                         if ( t.footer() ) {
138                             availableHeight -= footerHeight;
139                         }
140                 }
141                 availableHeight -= offsetTop;
142                 availableHeight -= containerHeight - ( offsetTop + tableHeight );
143
144                 if ( !isNaN( parseFloat( delta ) ) && isFinite( delta ) ) {
145                         availableHeight -= delta;
146                 }
147
148                 var drawRows = Math.floor( availableHeight / rowHeight );
149
150                 if ( drawRows !== Infinity && drawRows !== -Infinity && 
151                          ! isNaN( drawRows )   && drawRows > 0 &&
152                          drawRows !== dt.page.len()
153                 ) {
154                         dt.page.len( drawRows ).draw();
155                 }
156         },
157
158         _attach: function () {
159                 // There is no `resize` event for elements, so to trigger this effect,
160                 // create an empty HTML document using an <object> which will issue a
161                 // resize event inside itself when the document resizes. Since it is
162                 // 100% x 100% that will occur whenever the host element is resized.
163                 var that = this;
164                 var obj = $('<object/>')
165                         .css( {
166                                 position: 'absolute',
167                                 top: 0,
168                                 left: 0,
169                                 height: '100%',
170                                 width: '100%',
171                                 zIndex: -1
172                         } )
173                         .attr( 'type', 'text/html' );
174
175                 obj[0].onload = function () {
176                         var body = this.contentDocument.body;
177                         var height = body.offsetHeight;
178
179             this.contentDocument.defaultView.onresize = function () {
180
181                 var newHeight = body.clientHeight || body.offsetHeight;
182                 if (newHeight !== height) {
183                     height = newHeight;
184                     that._size();
185                     return;
186                 }
187
188                 // Width changes might lead to layout changes, which might require
189                 // resizing the table
190                 if (that.sizes.offsetTop !== that._getOffsetTop()
191                     || that.sizes.containerHeight !== that._getContainerHeight()
192                     || that.sizes.tableHeight !== that._getTableHeight()
193                     || that.sizes.headerHeight !== that._getHeaderHeight()
194                     || that.sizes.footerHeight !== that._getFooterHeight()) {
195                     that._size();
196                     return;
197                 }
198
199                         };
200                 };
201
202                 obj
203                         .appendTo( this.s.host )
204                         .attr( 'data', 'about:blank' );
205
206                 this.s.obj = obj;
207         },
208
209     _getOffsetTop: function () { return $(this.s.table).offset().top; },
210     _getTableHeight: function () { return this.s.table.height(); },
211     _getContainerHeight: function () { return this.s.container.height(); },
212     _getHeaderHeight: function () { return this.s.dt.table().header() ? this.s.header.height() : 0; },
213     _getFooterHeight: function () { return this.s.dt.table().footer() ? this.s.footer.height() : 0; }
214
215 };
216
217
218 $.fn.dataTable.PageResize = PageResize;
219 $.fn.DataTable.PageResize = PageResize;
220
221 // Automatic initialisation listener
222 $(document).on( 'preInit.dt', function ( e, settings ) {
223         if ( e.namespace !== 'dt' ) {
224                 return;
225         }
226
227         var api = new $.fn.dataTable.Api( settings );
228
229         if ( $( api.table().node() ).hasClass( 'pageResize' ) ||
230                  settings.oInit.pageResize ||
231                  $.fn.dataTable.defaults.pageResize )
232         {
233                 new PageResize( api, settings.oInit.pageResizeManualDelta );
234         }
235 } );
236
237
238 }));