![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/cartforge.co/pub/static/frontend/Magento/luma/en_US/Magento_Ui/js/grid/ |
/** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ /** * @api */ define([ 'Magento_Ui/js/lib/view/utils/async', 'ko', 'underscore', 'mageUtils', 'uiRegistry', 'Magento_Ui/js/lib/knockout/extender/bound-nodes', 'uiElement' ], function ($, ko, _, utils, registry, boundedNodes, Element) { 'use strict'; return Element.extend({ defaults: { rootSelector: '${ $.columnsProvider }:.admin__data-grid-wrap', tableSelector: '${ $.rootSelector } -> table.data-grid', mainTableSelector: '[data-role="grid"]', columnSelector: '${ $.tableSelector } thead tr th', fieldSelector: '${ $.tableSelector } tbody tr td', imports: { storageColumnsData: '${ $.storageConfig.path }.storageColumnsData' }, storageColumnsData: {}, columnsElements: {}, tableWidth: 0, sumColumnsWidth: 0, showLines: 4, resizableElementClass: 'shadow-div', resizingColumnClass: '_resizing', fixedLayoutClass: '_layout-fixed', inResizeClass: '_in-resize', visibleClass: '_resize-visible', cellContentElement: 'div.data-grid-cell-content', minColumnWidth: 40, layoutFixedPolyfillIterator: 0, windowResize: false, resizable: false, resizeConfig: { maxRowsHeight: [], curResizeElem: {}, depResizeElem: {}, previousWidth: null } }, /** * Initialize application - * binding functions context, * set handlers for table elements * * @returns {Object} Chainable */ initialize: function () { _.bindAll( this, 'initTable', 'initColumn', 'mousedownHandler', 'mousemoveHandler', 'mouseupHandler', 'refreshLastColumn', 'refreshMaxRowHeight', 'preprocessingWidth', '_eventProxy', 'checkAfterResize' ); this._super(); this.observe(['maxRowsHeight']); this.maxRowsHeight([]); $.async(this.tableSelector, this.initTable); $.async(this.columnSelector, this.initColumn); return this; }, /** * Set table element and adds handler to mousedown on headers * * @returns {Object} Chainable */ initTable: function (table) { if ($(table).is(this.mainTableSelector)) { this.table = table; this.tableWidth = $(table).outerWidth(); $(window).on('resize', this.checkAfterResize); } //TODO - Must be deleted when Firefox fixed problem with table-layout: fixed //ticket to Firefox: https://bugs.webkit.org/show_bug.cgi?id=90068 if (navigator.userAgent.search(/Firefox/) > -1) { this._layoutFixedPolyfill(); } $(table).addClass(this.fixedLayoutClass); return this; }, /** * Window resize handler, * check changes on table width and * set new width to variable * after window resize start preprocessingWidth method */ checkAfterResize: function () { var tableWidth, self = this; setTimeout(function () { tableWidth = $(self.table).outerWidth(); if (self.tableWidth !== tableWidth) { self.tableWidth = tableWidth; } else { self.preprocessingWidth(); } }, 300); }, /** * Check conditions to set minimal width */ checkSumColumnsWidth: function () { var table = $(this.table), elems = table.find('th:not([style*="width: auto"]):visible'), elemsWidthMin = table.find('th[style*="width: ' + (this.minColumnWidth - 1) + 'px"]:visible'), elemsWidthAuto = table.find('th[style*="width: auto"]:visible'), model; this.sumColumnsWidth = 0; _.each(elems, function (elem) { model = ko.dataFor(elem); model.width && model.width !== 'auto' ? this.sumColumnsWidth += model.width : false; }, this); if ( this.sumColumnsWidth + elemsWidthAuto.length * this.minColumnWidth + elemsWidthMin.length * this.minColumnWidth > this.tableWidth ) { return true; } return false; }, /** * Set minimal width to element with "auto" width */ setWidthToColumnsWidthAuto: function () { var elemsWidthAuto = $(this.table).find('th[style*="width: auto"]:visible'); _.each(elemsWidthAuto, function (elem) { $(elem).outerWidth(this.minColumnWidth - 1); }, this); }, /** * Check conditions to set auto width */ hasMinimal: function () { var table = $(this.table), elemsWidthMin = table.find('th[style*="width: ' + (this.minColumnWidth - 1) + 'px"]:visible'), elemsWidthAuto = table.find('th[style*="width: auto"]:visible'); if ( elemsWidthAuto && this.sumColumnsWidth + elemsWidthAuto.length * this.minColumnWidth + elemsWidthMin.length * this.minColumnWidth + 5 < this.tableWidth ) { return true; } return false; }, /** * Set "auto" width to element with minimal width */ setAuto: function () { var elemsWidthAuto = $(this.table).find('th[style*="width: ' + (this.minColumnWidth - 1) + 'px"]:visible'); _.each(elemsWidthAuto, function (elem) { $(elem).outerWidth('auto'); }, this); }, /** * Check columns width and preprocessing */ preprocessingWidth: function () { if (this.checkSumColumnsWidth()) { this.setWidthToColumnsWidthAuto(); } else if (this.hasMinimal()) { this.setAuto(); } }, /** * Init columns elements, * set width to current column element, * add resizable element to columns header, * check and add no-resize class to last column, * stop parents events, * add handler to visibility column * * @param {Object} column - columns header element (th) */ initColumn: function (column) { var model = ko.dataFor(column), ctxIndex = this.getCtxIndex(ko.contextFor(column)); model.width = this.getDefaultWidth(column); if (!this.hasColumn(model, ctxIndex, false)) { this.columnsElements[model.index] = this.columnsElements[model.index] || {}; this.columnsElements[model.index][ctxIndex] = column; this.initResizableElement(column); this.setStopPropagationHandler(column); $(column).outerWidth(model.width); } this.refreshLastColumn(column); this.preprocessingWidth(); model.on('visible', this.refreshLastColumn.bind(this, column)); model.on('visible', this.preprocessingWidth.bind(this)); }, /** * Hack for mozilla firefox */ _layoutFixedPolyfill: function () { var self = this; setTimeout(function () { if (self.layoutFixedPolyfillIterator < 20) { $(window).trigger('resize'); self.layoutFixedPolyfillIterator++; self._layoutFixedPolyfill(); } else { return false; } }, 500); }, /** * Check element is resizable or not * and append resizable element to DOM * * @param {Object} column - columns header element (th) * @returns {Boolean} */ initResizableElement: function (column) { var model = ko.dataFor(column), templateDragElement = '<div class="' + this.resizableElementClass + '"></div>'; if (_.isUndefined(model.resizeEnabled) || model.resizeEnabled) { $(column).append(templateDragElement); return true; } return false; }, /** * Check event target and if need stop parents event, * * @param {Object} column - columns header element (th) * @returns {Boolean} */ setStopPropagationHandler: function (column) { var events, click, mousedown; $(column).on('click', this._eventProxy); $(column).on('mousedown', this._eventProxy); events = $._data(column, 'events'); click = events.click; mousedown = events.mousedown; click.unshift(click.pop()); mousedown.unshift(mousedown.pop()); return this; }, /** * Check event target and stop event if need * * @param {Object} event */ _eventProxy: function (event) { if ($(event.target).is('.' + this.resizableElementClass)) { if (event.type === 'click') { event.stopImmediatePropagation(); } else if (event.type === 'mousedown') { this.mousedownHandler(event); } } }, /** * Check visible columns and set disable class to resizable elements, * * @param {Object} column - columns header element (th) */ refreshLastColumn: function (column) { var i = 0, columns = $(column).parent().children().not(':hidden'), length = columns.length; $('.' + this.visibleClass).removeClass(this.visibleClass); $(column).parent().children().not(':hidden').last().addClass(this.visibleClass); for (i; i < length; i++) { if (!columns.eq(i).find('.' + this.resizableElementClass).length && i) { columns.eq(i - 1).addClass(this.visibleClass); } } }, /** * Refresh max height to row elements, * * @param {Object} elem - (td) */ refreshMaxRowHeight: function (elem) { var rowsH = this.maxRowsHeight(), curEL = $(elem).find('div'), height, obj = this.hasRow($(elem).parent()[0], true); curEL.css('white-space', 'nowrap'); height = curEL.height() * this.showLines; curEL.css('white-space', 'normal'); if (obj) { if (obj.maxHeight < height) { rowsH[_.indexOf(rowsH, obj)].maxHeight = height; } else { return false; } } else { rowsH.push({ elem: $(elem).parent()[0], maxHeight: height }); } $(elem).parent().children().find(this.cellContentElement).css('max-height', height + 'px'); this.maxRowsHeight(rowsH); }, /** * Set resize class to elements when resizable */ _setResizeClass: function () { var rowElements = $(this.table).find('tr'); rowElements .find('td:eq(' + this.resizeConfig.curResizeElem.ctx.$index() + ')') .addClass(this.resizingColumnClass); rowElements .find('td:eq(' + this.resizeConfig.depResizeElem.ctx.$index() + ')') .addClass(this.resizingColumnClass); }, /** * Remove resize class to elements when resizable */ _removeResizeClass: function () { var rowElements = $(this.table).find('tr'); rowElements .find('td:eq(' + this.resizeConfig.curResizeElem.ctx.$index() + ')') .removeClass(this.resizingColumnClass); rowElements .find('td:eq(' + this.resizeConfig.depResizeElem.ctx.$index() + ')') .removeClass(this.resizingColumnClass); }, /** * Check conditions to resize * * @returns {Boolean} */ _canResize: function (column) { if ( $(column).hasClass(this.visibleClass) || !$(this.resizeConfig.depResizeElem.elems[0]).find('.' + this.resizableElementClass).length ) { return false; } return true; }, /** * Mouse down event handler, * find current and dep column to resize * * @param {Object} event */ mousedownHandler: function (event) { var target = event.target, column = $(target).parent()[0], cfg = this.resizeConfig, body = $('body'); event.stopImmediatePropagation(); cfg.curResizeElem.model = ko.dataFor(column); cfg.curResizeElem.ctx = ko.contextFor(column); cfg.curResizeElem.elems = this.hasColumn(cfg.curResizeElem.model, false, true); cfg.curResizeElem.position = event.pageX; cfg.depResizeElem.elems = this.getNextElements(cfg.curResizeElem.elems[0]); cfg.depResizeElem.model = ko.dataFor(cfg.depResizeElem.elems[0]); cfg.depResizeElem.ctx = ko.contextFor(cfg.depResizeElem.elems[0]); this._setResizeClass(); if (!this._canResize(column)) { return false; } event.stopPropagation(); this.resizable = true; cfg.curResizeElem.model.width = $(cfg.curResizeElem.elems[0]).outerWidth(); cfg.depResizeElem.model.width = $(cfg.depResizeElem.elems[0]).outerWidth(); body.addClass(this.inResizeClass); body.on('mousemove', this.mousemoveHandler); $(window).on('mouseup', this.mouseupHandler); }, /** * Mouse move event handler, * change columns width * * @param {Object} event */ mousemoveHandler: function (event) { var cfg = this.resizeConfig, width = event.pageX - cfg.curResizeElem.position, self = this; event.stopPropagation(); event.preventDefault(); if ( this.resizable && this.minColumnWidth < cfg.curResizeElem.model.width + width && this.minColumnWidth < cfg.depResizeElem.model.width - width && cfg.previousWidth !== width ) { cfg.curResizeElem.model.width += width; cfg.depResizeElem.model.width -= width; cfg.curResizeElem.elems.forEach(function (el) { $(el).outerWidth(cfg.curResizeElem.model.width); }); cfg.depResizeElem.elems.forEach(function (el) { $(el).outerWidth(cfg.depResizeElem.model.width); }); cfg.previousWidth = width; cfg.curResizeElem.position = event.pageX; } else if (width <= -(cfg.curResizeElem.model.width - this.minColumnWidth)) { cfg.curResizeElem.elems.forEach(function (el) { $(el).outerWidth(self.minColumnWidth); }); cfg.depResizeElem.elems.forEach(function (el) { $(el).outerWidth( cfg.depResizeElem.model.width + cfg.curResizeElem.model.width - self.minColumnWidth); }); } else if (width >= cfg.depResizeElem.model.width - this.minColumnWidth) { cfg.depResizeElem.elems.forEach(function (el) { $(el).outerWidth(self.minColumnWidth); }); cfg.curResizeElem.elems.forEach(function (el) { $(el).outerWidth( cfg.curResizeElem.model.width + cfg.depResizeElem.model.width - self.minColumnWidth ); }); } }, /** * Mouse up event handler, * change columns width * * @param {Object} event */ mouseupHandler: function (event) { var cfg = this.resizeConfig, body = $('body'); event.stopPropagation(); event.preventDefault(); this._removeResizeClass(); this.storageColumnsData[cfg.curResizeElem.model.index] = cfg.curResizeElem.model.width; this.storageColumnsData[cfg.depResizeElem.model.index] = cfg.depResizeElem.model.width; this.resizable = false; this.store('storageColumnsData'); body.removeClass(this.inResizeClass); body.off('mousemove', this.mousemoveHandler); $(window).off('mouseup', this.mouseupHandler); }, /** * Find dependency element * * @param {Object} element - current element * @returns {Object} next element data */ getNextElements: function (element) { var nextElem = $(element).next()[0], nextElemModel = ko.dataFor(nextElem), nextElemData = this.hasColumn(nextElemModel, false, true); if (nextElemData) { if (nextElemModel.visible) { return nextElemData; } return this.getNextElements(nextElem); } }, /** * Get default width * * @param {Object} column - (th) element * @return {String} width for current column */ getDefaultWidth: function (column) { var model = ko.dataFor(column); if (this.storageColumnsData[model.index]) { return this.storageColumnsData[model.index]; } if (model.resizeDefaultWidth) { return parseInt(model.resizeDefaultWidth, 10); } return 'auto'; }, /** * Check column is render or not * * @param {Object} model - cur column model * @param {String|Boolean} ctxIndex - index of context, or false, if want to get cols from all ctx * @param {Boolean} returned - need return column object or not * @return {Boolean} if returned param is false, returned boolean value, else return current object data */ hasColumn: function (model, ctxIndex, returned) { var colElem = this.columnsElements[model.index] || {}, getFromAllCtx = ctxIndex === false; if (colElem && (getFromAllCtx || colElem.hasOwnProperty(ctxIndex))) { if (returned) { return getFromAllCtx ? _.values(colElem) : colElem[ctxIndex]; } return true; } return false; }, /** * Check row is render or not * * @param {Object} elem - cur column element * @param {Boolean} returned - need return column object or not * @return {Boolean|Object} if returned param is false, returned boolean value, else return current object data */ hasRow: function (elem, returned) { var i = 0, el = this.maxRowsHeight(), length = el.length; for (i; i < length; i++) { if (this.maxRowsHeight()[i].elem === elem) { if (returned) {//eslint-disable-line max-depth return this.maxRowsHeight()[i]; } return true; } } return false; }, /** * Generate index that will identify context * * @param {Object} ctx * @return {String} */ getCtxIndex: function (ctx) { return ctx ? ctx.$parents.reduce(function (pv, cv) { return (pv.index || pv) + (cv || {}).index; }) : ctx; } }); });