diff options
Diffstat (limited to 'core/misc/tableheader.es6.js')
-rw-r--r-- | core/misc/tableheader.es6.js | 335 |
1 files changed, 0 insertions, 335 deletions
diff --git a/core/misc/tableheader.es6.js b/core/misc/tableheader.es6.js deleted file mode 100644 index 1d4eca7e69e..00000000000 --- a/core/misc/tableheader.es6.js +++ /dev/null @@ -1,335 +0,0 @@ -/** - * @file - * Sticky table headers. - */ - -(function ($, Drupal, displace) { - /** - * Constructor for the tableHeader object. Provides sticky table headers. - * - * TableHeader will make the current table header stick to the top of the page - * if the table is very long. - * - * @constructor Drupal.TableHeader - * - * @param {HTMLElement} table - * DOM object for the table to add a sticky header to. - * - * @listens event:columnschange - */ - function TableHeader(table) { - const $table = $(table); - - /** - * @name Drupal.TableHeader#$originalTable - * - * @type {HTMLElement} - */ - this.$originalTable = $table; - - /** - * @type {jQuery} - */ - this.$originalHeader = $table.children('thead'); - - /** - * @type {jQuery} - */ - this.$originalHeaderCells = this.$originalHeader.find('> tr > th'); - - /** - * @type {null|bool} - */ - this.displayWeight = null; - this.$originalTable.addClass('sticky-table'); - this.tableHeight = $table[0].clientHeight; - this.tableOffset = this.$originalTable.offset(); - - // React to columns change to avoid making checks in the scroll callback. - this.$originalTable.on( - 'columnschange', - { tableHeader: this }, - (e, display) => { - const tableHeader = e.data.tableHeader; - if ( - tableHeader.displayWeight === null || - tableHeader.displayWeight !== display - ) { - tableHeader.recalculateSticky(); - } - tableHeader.displayWeight = display; - }, - ); - - // Create and display sticky header. - this.createSticky(); - } - - // Helper method to loop through tables and execute a method. - function forTables(method, arg) { - const tables = TableHeader.tables; - const il = tables.length; - for (let i = 0; i < il; i++) { - tables[i][method](arg); - } - } - - // Select and initialize sticky table headers. - function tableHeaderInitHandler(e) { - once('tableheader', $(e.data.context).find('table.sticky-enabled')).forEach( - (table) => { - TableHeader.tables.push(new TableHeader(table)); - }, - ); - forTables('onScroll'); - } - - /** - * Attaches sticky table headers. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the sticky table header behavior. - */ - Drupal.behaviors.tableHeader = { - attach(context) { - $(window).one( - 'scroll.TableHeaderInit', - { context }, - tableHeaderInitHandler, - ); - }, - }; - - function scrollValue(position) { - return document.documentElement[position] || document.body[position]; - } - - function tableHeaderResizeHandler(e) { - forTables('recalculateSticky'); - } - - function tableHeaderOnScrollHandler(e) { - forTables('onScroll'); - } - - function tableHeaderOffsetChangeHandler(e, offsets) { - forTables('stickyPosition', offsets.top); - } - - // Bind event that need to change all tables. - $(window).on({ - /** - * When resizing table width can change, recalculate everything. - * - * @ignore - */ - 'resize.TableHeader': tableHeaderResizeHandler, - - /** - * Bind only one event to take care of calling all scroll callbacks. - * - * @ignore - */ - 'scroll.TableHeader': tableHeaderOnScrollHandler, - }); - // Bind to custom Drupal events. - $(document).on({ - /** - * Recalculate columns width when window is resized, when show/hide weight - * is triggered, or when toolbar tray is toggled. - * - * @ignore - */ - 'columnschange.TableHeader drupalToolbarTrayChange': - tableHeaderResizeHandler, - - /** - * Recalculate TableHeader.topOffset when viewport is resized. - * - * @ignore - */ - 'drupalViewportOffsetChange.TableHeader': tableHeaderOffsetChangeHandler, - }); - - /** - * Store the state of TableHeader. - */ - $.extend( - TableHeader, - /** @lends Drupal.TableHeader */ { - /** - * This will store the state of all processed tables. - * - * @type {Array.<Drupal.TableHeader>} - */ - tables: [], - }, - ); - - /** - * Extend TableHeader prototype. - */ - $.extend( - TableHeader.prototype, - /** @lends Drupal.TableHeader# */ { - /** - * Minimum height in pixels for the table to have a sticky header. - * - * @type {number} - */ - minHeight: 100, - - /** - * Absolute position of the table on the page. - * - * @type {?Drupal~displaceOffset} - */ - tableOffset: null, - - /** - * Absolute position of the table on the page. - * - * @type {?number} - */ - tableHeight: null, - - /** - * Boolean storing the sticky header visibility state. - * - * @type {bool} - */ - stickyVisible: false, - - /** - * Create the duplicate header. - */ - createSticky() { - // For caching purposes. - this.$html = $('html'); - // Clone the table header so it inherits original jQuery properties. - const $stickyHeader = this.$originalHeader.clone(true); - // Hide the table to avoid a flash of the header clone upon page load. - this.$stickyTable = $('<table class="sticky-header"></table>') - .css({ - visibility: 'hidden', - position: 'fixed', - top: '0px', - }) - .append($stickyHeader) - .insertBefore(this.$originalTable); - - this.$stickyHeaderCells = $stickyHeader.find('> tr > th'); - - // Initialize all computations. - this.recalculateSticky(); - }, - - /** - * Set absolute position of sticky. - * - * @param {number} offsetTop - * The top offset for the sticky header. - * @param {number} offsetLeft - * The left offset for the sticky header. - * - * @return {jQuery} - * The sticky table as a jQuery collection. - */ - stickyPosition(offsetTop, offsetLeft) { - const css = {}; - if (typeof offsetTop === 'number') { - css.top = `${offsetTop}px`; - } - if (typeof offsetLeft === 'number') { - css.left = `${this.tableOffset.left - offsetLeft}px`; - } - this.$html.css( - 'scroll-padding-top', - displace.offsets.top + - (this.stickyVisible ? this.$stickyTable.height() : 0), - ); - return this.$stickyTable.css(css); - }, - - /** - * Returns true if sticky is currently visible. - * - * @return {bool} - * The visibility status. - */ - checkStickyVisible() { - const scrollTop = scrollValue('scrollTop'); - const tableTop = this.tableOffset.top - displace.offsets.top; - const tableBottom = tableTop + this.tableHeight; - let visible = false; - - if (tableTop < scrollTop && scrollTop < tableBottom - this.minHeight) { - visible = true; - } - - this.stickyVisible = visible; - return visible; - }, - - /** - * Check if sticky header should be displayed. - * - * This function is throttled to once every 250ms to avoid unnecessary - * calls. - * - * @param {jQuery.Event} e - * The scroll event. - */ - onScroll(e) { - this.checkStickyVisible(); - // Track horizontal positioning relative to the viewport. - this.stickyPosition(null, scrollValue('scrollLeft')); - this.$stickyTable.css( - 'visibility', - this.stickyVisible ? 'visible' : 'hidden', - ); - }, - - /** - * Event handler: recalculates position of the sticky table header. - * - * @param {jQuery.Event} event - * Event being triggered. - */ - recalculateSticky(event) { - // Update table size. - this.tableHeight = this.$originalTable[0].clientHeight; - - // Update offset top. - displace.offsets.top = displace.calculateOffset('top'); - this.tableOffset = this.$originalTable.offset(); - this.stickyPosition(displace.offsets.top, scrollValue('scrollLeft')); - - // Update columns width. - let $that = null; - let $stickyCell = null; - let display = null; - // Resize header and its cell widths. - // Only apply width to visible table cells. This prevents the header from - // displaying incorrectly when the sticky header is no longer visible. - const il = this.$originalHeaderCells.length; - for (let i = 0; i < il; i++) { - $that = $(this.$originalHeaderCells[i]); - $stickyCell = this.$stickyHeaderCells.eq($that.index()); - display = $that.css('display'); - if (display !== 'none') { - $stickyCell.css({ width: $that.css('width'), display }); - } else { - $stickyCell.css('display', 'none'); - } - } - this.$stickyTable.css('width', this.$originalTable.outerWidth()); - }, - }, - ); - - // Expose constructor in the public space. - Drupal.TableHeader = TableHeader; -})(jQuery, Drupal, window.Drupal.displace); |