diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..82f3afa --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ +Are you happy for it to be included and distributed under the MIT license? ✔️/❌ diff --git a/dataRender/datetime.js b/dataRender/datetime.js index c866f97..0d97d8c 100644 --- a/dataRender/datetime.js +++ b/dataRender/datetime.js @@ -97,13 +97,9 @@ $.fn.dataTable.render.moment = function ( from, to, locale ) { // Argument shifting if ( arguments.length === 1 ) { - locale = 'en'; to = from; from = 'YYYY-MM-DD'; } - else if ( arguments.length === 2 ) { - locale = 'en'; - } return function ( d, type, row ) { if (! d) { diff --git a/dataRender/ellipsis.js b/dataRender/ellipsis.js index 186e9e5..a89cf77 100644 --- a/dataRender/ellipsis.js +++ b/dataRender/ellipsis.js @@ -49,7 +49,7 @@ jQuery.fn.dataTable.render.ellipsis = function ( cutoff, wordbreak, escapeHtml ) { var esc = function ( t ) { - return t + return ('' + t) .replace( /&/g, '&' ) .replace( //g, '>' ) @@ -63,12 +63,18 @@ jQuery.fn.dataTable.render.ellipsis = function ( cutoff, wordbreak, escapeHtml ) } if ( typeof d !== 'number' && typeof d !== 'string' ) { + if ( escapeHtml ) { + return esc( d ); + } return d; } d = d.toString(); // cast numbers if ( d.length <= cutoff ) { + if ( escapeHtml ) { + return esc( d ); + } return d; } diff --git a/features/pageResize/dataTables.pageResize.js b/features/pageResize/dataTables.pageResize.js index 9ee8fe3..161ce06 100644 --- a/features/pageResize/dataTables.pageResize.js +++ b/features/pageResize/dataTables.pageResize.js @@ -76,15 +76,37 @@ var PageResize = function ( dt, pageResizeManualDelta ) container: $(table.container()), table: $(table.node()), delta: pageResizeManualDelta - }; + }; + + this.sizes = { + offsetTop: this._getOffsetTop(), + tableHeight: this._getTableHeight(), + containerHeight: this._getContainerHeight(), + headerHeight: this._getHeaderHeight(), + footerHeight: this._getFooterHeight() + }; var host = this.s.host; if ( host.css('position') === 'static' ) { host.css( 'position', 'relative' ); } + var onDestroy = function () { + dt.off('.pageResize', onDestroy); + this.s.obj && this.s.obj.remove(); + }.bind(this); + dt.on('destroy.pageResize', onDestroy); + this._attach(); - this._size(); + + // Delay the initial sizing until the table is fully initialized + // such that the pagination element is also added and can be taken + // into account. + var initEvent = 'init.pageResize'; + dt.on(initEvent, function () { + dt.off(initEvent); + this._size(); + }.bind(this)); }; @@ -94,25 +116,30 @@ PageResize.prototype = { var settings = this.s; var dt = settings.dt; var t = dt.table(); - var offsetTop = $( settings.table ).offset().top; var rows = $( 'tr', settings.body ); var rowHeight = rows.eq( rows.length > 1 ? 1 : 0 ).height(); // Attempt to use the second row if poss, for top and bottom border var availableHeight = settings.host.height(); var scrolling = t.header().parentNode !== t.body().parentNode; - var delta = settings.delta; + var delta = settings.delta; + + var offsetTop = this.sizes.offsetTop = this._getOffsetTop(); + var tableHeight = this.sizes.tableHeight = this._getTableHeight(); + var containerHeight = this.sizes.containerHeight = this._getContainerHeight(); + var headerHeight = this.sizes.headerHeight = this._getHeaderHeight(); + var footerHeight = this.sizes.footerHeight = this._getFooterHeight(); // Subtract the height of the header, footer and the elements // surrounding the table if ( ! scrolling ) { if ( t.header() ) { - availableHeight -= settings.header.height(); + availableHeight -= headerHeight; } if ( t.footer() ) { - availableHeight -= settings.footer.height(); + availableHeight -= footerHeight; } } availableHeight -= offsetTop; - availableHeight -= settings.container.height() - ( offsetTop + settings.table.height() ); + availableHeight -= containerHeight - ( offsetTop + tableHeight ); if ( !isNaN( parseFloat( delta ) ) && isFinite( delta ) ) { availableHeight -= delta; @@ -149,21 +176,42 @@ PageResize.prototype = { var body = this.contentDocument.body; var height = body.offsetHeight; - this.contentDocument.defaultView.onresize = function () { - var newHeight = body.clientHeight || body.offsetHeight; - - if ( newHeight !== height ) { - height = newHeight; + this.contentDocument.defaultView.onresize = function () { + + var newHeight = body.clientHeight || body.offsetHeight; + if (newHeight !== height) { + height = newHeight; + that._size(); + return; + } + + // Width changes might lead to layout changes, which might require + // resizing the table + if (that.sizes.offsetTop !== that._getOffsetTop() + || that.sizes.containerHeight !== that._getContainerHeight() + || that.sizes.tableHeight !== that._getTableHeight() + || that.sizes.headerHeight !== that._getHeaderHeight() + || that.sizes.footerHeight !== that._getFooterHeight()) { + that._size(); + return; + } - that._size(); - } }; }; obj .appendTo( this.s.host ) .attr( 'data', 'about:blank' ); - } + + this.s.obj = obj; + }, + + _getOffsetTop: function () { return $(this.s.table).offset().top; }, + _getTableHeight: function () { return this.s.table.height(); }, + _getContainerHeight: function () { return this.s.container.height(); }, + _getHeaderHeight: function () { return this.s.dt.table().header() ? this.s.header.height() : 0; }, + _getFooterHeight: function () { return this.s.dt.table().footer() ? this.s.footer.height() : 0; } + }; diff --git a/features/scrollResize/dataTables.scrollResize.js b/features/scrollResize/dataTables.scrollResize.js index 2017dea..6c6a1f4 100644 --- a/features/scrollResize/dataTables.scrollResize.js +++ b/features/scrollResize/dataTables.scrollResize.js @@ -79,12 +79,28 @@ var ScrollResize = function ( dt ) host.css( 'position', 'relative' ); } - dt.on( 'draw', function () { + dt.on( 'draw.scrollResize', function () { that._size(); } ); + dt.on('destroy.scrollResize', function () { + dt.off('.scrollResize'); + this.s.obj && this.s.obj.remove(); + }.bind(this)); + this._attach(); this._size(); + + // Redraw the header if the scrollbar was visible before feature + // initialization, but no longer after initialization. Otherwise, + // the header width would differ from the body width, because the + // scrollbar is no longer present. + var settings = dt.settings()[0]; + var divBodyEl = settings.nScrollBody; + var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight; + if (settings.scrollBarVis && !scrollBarVis) { + dt.columns.adjust(); + } }; @@ -154,7 +170,9 @@ ScrollResize.prototype = { obj .appendTo( this.s.host ) .attr( 'data', 'about:blank' ); - } + + this.s.obj = obj; + } }; diff --git a/package.json b/package.json index feeb7ea..678fab6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datatables.net-plugins", - "version": "1.11.4", + "version": "1.11.5", "description": "Various small plug-ins for DataTables including feature, ordering, search and internationalisation plug-ins.", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/sorting/datetime-luxon.js b/sorting/datetime-luxon.js index f743816..2cfee7c 100644 --- a/sorting/datetime-luxon.js +++ b/sorting/datetime-luxon.js @@ -29,13 +29,11 @@ }(function ($, luxon) { function strip (d) { - if ( typeof d === 'string' ) { - // Strip HTML tags and newline characters if possible - d = d.replace(/(<.*?>)|(\r?\n|\r)/g, ''); + // Strip HTML tags and newline characters if possible + d = d.replace(/(<.*?>)|(\r?\n|\r)/g, ''); - // Strip out surrounding white space - d = d.trim(); - } + // Strip out surrounding white space + d = d.trim(); return d; } @@ -45,25 +43,37 @@ $.fn.dataTable.luxon = function ( format, locale, reverseEmpties ) { // Add type detection types.detect.unshift( function ( d ) { - d = strip(d); - - // Null and empty values are acceptable - if ( d === '' || d === null ) { + // Null values are acceptable + if ( d === null ) { return 'luxon-'+format; - } + } + if ( typeof d === 'string' ) { + d = strip(d); - return luxon.DateTime.fromFormat( d, format).isValid ? - 'luxon-'+format : - null; + // Empty values are acceptable + if ( d === '' ) { + return 'luxon-'+format; + } + + return luxon.DateTime.fromFormat( d, format).isValid ? + 'luxon-'+format : + null; + } else { + return null; + } } ); // Add sorting method - use an integer for the sorting types.order[ 'luxon-'+format+'-pre' ] = function ( d ) { - d = strip(d); - - return !luxon.DateTime.fromFormat(d, format).isValid ? - (reverseEmpties ? -Infinity : Infinity) : - parseInt( luxon.DateTime.fromFormat( d, format).ts, 10 ); + if ( typeof d === 'string' ) { + d = strip(d); + + return !luxon.DateTime.fromFormat(d, format).isValid ? + (reverseEmpties ? -Infinity : Infinity) : + parseInt( luxon.DateTime.fromFormat( d, format).ts, 10 ); + } else { + return null; + } }; };