UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

956 lines (954 loc) • 83.5 kB
/** * DevExtreme (cjs/ui/grid_core/ui.grid_core.virtual_scrolling.js) * Version: 22.1.9 * Build date: Tue Apr 18 2023 * * Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; exports.virtualScrollingModule = void 0; var _size = require("../../core/utils/size"); var _renderer = _interopRequireDefault(require("../../core/renderer")); var _window = require("../../core/utils/window"); var _uiGrid_core = require("./ui.grid_core.virtual_scrolling_core"); var _uiGrid_core2 = _interopRequireDefault(require("./ui.grid_core.utils")); var _iterator = require("../../core/utils/iterator"); var _deferred = require("../../core/utils/deferred"); var _load_indicator = _interopRequireDefault(require("../load_indicator")); var _browser = _interopRequireDefault(require("../../core/utils/browser")); var _position = require("../../core/utils/position"); var _type = require("../../core/utils/type"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } var BOTTOM_LOAD_PANEL_CLASS = "bottom-load-panel"; var TABLE_CONTENT_CLASS = "table-content"; var GROUP_SPACE_CLASS = "group-space"; var CONTENT_CLASS = "content"; var FREESPACE_CLASS = "dx-freespace-row"; var COLUMN_LINES_CLASS = "dx-column-lines"; var VIRTUAL_ROW_CLASS = "dx-virtual-row"; var ROW_INSERTED = "dx-row-inserted"; var SCROLLING_MODE_INFINITE = "infinite"; var SCROLLING_MODE_VIRTUAL = "virtual"; var LOAD_TIMEOUT = 300; var LEGACY_SCROLLING_MODE = "scrolling.legacyMode"; var VISIBLE_PAGE_INDEX = "paging.pageIndex"; var isVirtualMode = function(that) { return that.option("scrolling.mode") === SCROLLING_MODE_VIRTUAL }; var isAppendMode = function(that) { return that.option("scrolling.mode") === SCROLLING_MODE_INFINITE }; var isVirtualPaging = function(that) { return isVirtualMode(that) || isAppendMode(that) }; var _correctCount = function(items, count, fromEnd, isItemCountableFunc) { for (var i = 0; i < count + 1; i++) { var item = items[fromEnd ? items.length - 1 - i : i]; if (item && !isItemCountableFunc(item, i === count, fromEnd)) { count++ } } return count }; var isItemCountableByDataSource = function(item, dataSource) { return "data" === item.rowType && !item.isNewRow || "group" === item.rowType && dataSource.isGroupItemCountable(item.data) }; var updateItemIndices = function(items) { items.forEach((function(item, index) { item.rowIndex = index })); return items }; var VirtualScrollingDataSourceAdapterExtender = function() { var _updateLoading = function(that) { var beginPageIndex = that._virtualScrollController.beginPageIndex(-1); if (isVirtualMode(that)) { if (beginPageIndex < 0 || that.viewportSize() >= 0 && that.getViewportItemIndex() >= 0 && (beginPageIndex * that.pageSize() > that.getViewportItemIndex() || beginPageIndex * that.pageSize() + that.itemsCount() < that.getViewportItemIndex() + that.viewportSize()) && that._dataSource.isLoading()) { if (!that._isLoading) { that._isLoading = true; that.loadingChanged.fire(true) } } else if (that._isLoading) { that._isLoading = false; that.loadingChanged.fire(false) } } }; var result = { init: function() { this.callBase.apply(this, arguments); this._items = []; this._totalCount = -1; this._isLoaded = true; this._loadPageCount = 1; this._virtualScrollController = new _uiGrid_core.VirtualScrollController(this.component, this._getVirtualScrollDataOptions()) }, _getVirtualScrollDataOptions: function() { var that = this; return { pageSize: function() { return that.pageSize() }, totalItemsCount: function() { return that.totalItemsCount() }, hasKnownLastPage: function() { return that.hasKnownLastPage() }, pageIndex: function(index) { return that._dataSource.pageIndex(index) }, isLoading: function() { return that._dataSource.isLoading() && !that.isCustomLoading() }, pageCount: function() { return that.pageCount() }, load: function() { return that._dataSource.load() }, updateLoading: function() { _updateLoading(that) }, itemsCount: function() { return that.itemsCount(true) }, items: function() { return that._dataSource.items() }, viewportItems: function(items) { if (items) { that._items = items } return that._items }, onChanged: function(e) { that.changed.fire(e) }, changingDuration: function(e) { if (that.isLoading()) { return LOAD_TIMEOUT } return that._renderTime || 0 } } }, _handleLoadingChanged: function(isLoading) { if (false === this.option(LEGACY_SCROLLING_MODE)) { this.callBase.apply(this, arguments); return } if (!isVirtualMode(this) || this._isLoadingAll) { this._isLoading = isLoading; this.callBase.apply(this, arguments) } if (isLoading) { this._startLoadTime = new Date } else { this._startLoadTime = void 0 } }, _handleLoadError: function() { if (false !== this.option(LEGACY_SCROLLING_MODE)) { this._isLoading = false; this.loadingChanged.fire(false) } this.callBase.apply(this, arguments) }, _handleDataChanged: function(e) { if (false === this.option(LEGACY_SCROLLING_MODE)) { this._items = this._dataSource.items().slice(); this._totalCount = this._dataSourceTotalCount(true); this.callBase.apply(this, arguments); return } var callBase = this.callBase.bind(this); this._virtualScrollController.handleDataChanged(callBase, e) }, _customizeRemoteOperations: function(options, operationTypes) { var newMode = false === this.option(LEGACY_SCROLLING_MODE); var renderAsync = this.option("scrolling.renderAsync"); if (!(0, _type.isDefined)(renderAsync)) { renderAsync = this._renderTime >= this.option("scrolling.renderingThreshold") } if ((isVirtualMode(this) || isAppendMode(this) && newMode) && !operationTypes.reload && (operationTypes.skip || newMode) && !renderAsync) { options.delay = void 0 } this.callBase.apply(this, arguments) }, items: function() { return this._items }, _dataSourceTotalCount: function(isBase) { return false === this.option(LEGACY_SCROLLING_MODE) && isVirtualMode(this) && !isBase ? this._totalCount : this.callBase() }, itemsCount: function(isBase) { if (isBase || false === this.option(LEGACY_SCROLLING_MODE)) { return this.callBase() } return this._virtualScrollController.itemsCount() }, load: function(loadOptions) { if (false === this.option(LEGACY_SCROLLING_MODE) || loadOptions) { return this.callBase(loadOptions) } return this._virtualScrollController.load() }, isLoading: function() { return false === this.option(LEGACY_SCROLLING_MODE) ? this._dataSource.isLoading() : this._isLoading }, isLoaded: function() { return this._dataSource.isLoaded() && this._isLoaded }, resetPagesCache: function(isLiveUpdate) { if (!isLiveUpdate) { this._virtualScrollController.reset(true) } this.callBase.apply(this, arguments) }, _changeRowExpandCore: function() { var result = this.callBase.apply(this, arguments); if (false === this.option(LEGACY_SCROLLING_MODE)) { return result } this.resetPagesCache(); _updateLoading(this); return result }, reload: function() { this._dataSource.pageIndex(this.pageIndex()); var virtualScrollController = this._virtualScrollController; if (false !== this.option(LEGACY_SCROLLING_MODE) && virtualScrollController) { var d = new _deferred.Deferred; this.callBase.apply(this, arguments).done((function(r) { var delayDeferred = virtualScrollController.getDelayDeferred(); if (delayDeferred) { delayDeferred.done(d.resolve).fail(d.reject) } else { d.resolve(r) } })).fail(d.reject); return d } else { return this.callBase.apply(this, arguments) } }, refresh: function(options, operationTypes) { if (false !== this.option(LEGACY_SCROLLING_MODE)) { var storeLoadOptions = options.storeLoadOptions; var dataSource = this._dataSource; if (operationTypes.reload) { this._virtualScrollController.reset(); dataSource.items().length = 0; this._isLoaded = false; _updateLoading(this); this._isLoaded = true; if (isAppendMode(this)) { this.pageIndex(0); dataSource.pageIndex(0); storeLoadOptions.pageIndex = 0; options.pageIndex = 0; storeLoadOptions.skip = 0 } else { dataSource.pageIndex(this.pageIndex()); if (dataSource.paginate()) { options.pageIndex = this.pageIndex(); storeLoadOptions.skip = this.pageIndex() * this.pageSize() } } } else if (isAppendMode(this) && storeLoadOptions.skip && this._totalCountCorrection < 0) { storeLoadOptions.skip += this._totalCountCorrection } } return this.callBase.apply(this, arguments) }, dispose: function() { this._virtualScrollController.dispose(); this.callBase.apply(this, arguments) }, loadPageCount: function(count) { if (!(0, _type.isDefined)(count)) { return this._loadPageCount } this._loadPageCount = count }, _handleDataLoading: function(options) { var loadPageCount = this.loadPageCount(); var pageSize = this.pageSize(); var newMode = false === this.option(LEGACY_SCROLLING_MODE); var storeLoadOptions = options.storeLoadOptions; var takeIsDefined = (0, _type.isDefined)(storeLoadOptions.take); options.loadPageCount = loadPageCount; if (!options.isCustomLoading && newMode && takeIsDefined && loadPageCount > 1 && pageSize > 0) { storeLoadOptions.take = loadPageCount * pageSize } this.callBase.apply(this, arguments) }, _loadPageSize: function() { return this.callBase.apply(this, arguments) * this.loadPageCount() } }; ["beginPageIndex", "endPageIndex", "pageIndex"].forEach((function(name) { result[name] = function() { if (false === this.option(LEGACY_SCROLLING_MODE)) { var dataSource = this._dataSource; return dataSource.pageIndex.apply(dataSource, arguments) } var virtualScrollController = this._virtualScrollController; return virtualScrollController[name].apply(virtualScrollController, arguments) } })); ["virtualItemsCount", "getContentOffset", "getVirtualContentSize", "setContentItemSizes", "setViewportPosition", "getViewportItemIndex", "setViewportItemIndex", "getItemIndexByPosition", "viewportSize", "viewportItemSize", "getItemSize", "getItemSizes", "loadIfNeed"].forEach((function(name) { result[name] = function() { var virtualScrollController = this._virtualScrollController; return virtualScrollController[name].apply(virtualScrollController, arguments) } })); return result }(); var VirtualScrollingRowsViewExtender = function() { var removeEmptyRows = function($emptyRows, className) { var tBodies = $emptyRows.toArray().map((function(row) { return (0, _renderer.default)(row).parent("." + className).get(0) })).filter((function(row) { return row })); if (tBodies.length) { $emptyRows = (0, _renderer.default)(tBodies) } var rowCount = className === FREESPACE_CLASS ? $emptyRows.length - 1 : $emptyRows.length; for (var i = 0; i < rowCount; i++) { $emptyRows.eq(i).remove() } }; return { init: function() { var _dataController$state, _this = this; var dataController = this.getController("data"); this.callBase(); dataController.pageChanged.add((function(pageIndex) { var scrollTop = _this._scrollTop; _this.scrollToPage(null !== pageIndex && void 0 !== pageIndex ? pageIndex : dataController.pageIndex()); if (false === _this.option(LEGACY_SCROLLING_MODE) && _this._scrollTop === scrollTop) { dataController.updateViewport() } })); dataController.dataSourceChanged.add((function() { !_this._scrollTop && _this._scrollToCurrentPageOnResize() })); null === (_dataController$state = dataController.stateLoaded) || void 0 === _dataController$state ? void 0 : _dataController$state.add((function() { _this._scrollToCurrentPageOnResize() })); this._scrollToCurrentPageOnResize() }, _scrollToCurrentPageOnResize: function() { var _this2 = this; var dataController = this.getController("data"); if (dataController.pageIndex() > 0) { this.resizeCompleted.add((function resizeHandler() { _this2.resizeCompleted.remove(resizeHandler); _this2.scrollToPage(dataController.pageIndex()) })) } }, scrollToPage: function(pageIndex) { var dataController = this._dataController; var pageSize = dataController ? dataController.pageSize() : 0; var scrollPosition; if (isVirtualMode(this) || isAppendMode(this)) { var itemSize = dataController.getItemSize(); var itemSizes = dataController.getItemSizes(); var itemIndex = pageIndex * pageSize; scrollPosition = itemIndex * itemSize; for (var index in itemSizes) { if (index < itemIndex) { scrollPosition += itemSizes[index] - itemSize } } } else { scrollPosition = 0 } this.scrollTo({ y: scrollPosition, x: this._scrollLeft }) }, renderDelayedTemplates: function(e) { var _this3 = this; this.waitAsyncTemplates().done((function() { _this3._updateContentPosition(true) })); this.callBase.apply(this, arguments) }, _renderCore: function(e) { var startRenderTime = new Date; var deferred = this.callBase.apply(this, arguments); var dataSource = this._dataController._dataSource; if (dataSource && e) { var itemCount = e.items ? e.items.length : 20; var viewportSize = this._dataController.viewportSize() || 20; if (_uiGrid_core2.default.isVirtualRowRendering(this) && itemCount > 0 && false !== this.option(LEGACY_SCROLLING_MODE)) { dataSource._renderTime = (new Date - startRenderTime) * viewportSize / itemCount } else { dataSource._renderTime = new Date - startRenderTime } } return deferred }, _getRowElements: function(tableElement) { var $rows = this.callBase(tableElement); return $rows && $rows.not("." + VIRTUAL_ROW_CLASS) }, _removeRowsElements: function(contentTable, removeCount, changeType) { var rowElements = this._getRowElements(contentTable).toArray(); if ("append" === changeType) { rowElements = rowElements.slice(0, removeCount) } else { rowElements = rowElements.slice(-removeCount) } var errorHandlingController = this.getController("errorHandling"); rowElements.map((function(rowElement) { var $rowElement = (0, _renderer.default)(rowElement); errorHandlingController && errorHandlingController.removeErrorRow($rowElement.next()); $rowElement.remove() })) }, _updateContent: function(tableElement, change) { var _this4 = this; var $freeSpaceRowElements; var contentElement = this._findContentElement(); var changeType = change && change.changeType; var d = (0, _deferred.Deferred)(); var contentTable = contentElement.children().first(); if ("append" === changeType || "prepend" === changeType) { this.waitAsyncTemplates().done((function() { var $tBodies = _this4._getBodies(tableElement); if (1 === $tBodies.length) { _this4._getBodies(contentTable)["append" === changeType ? "append" : "prepend"]($tBodies.children()) } else { $tBodies["append" === changeType ? "appendTo" : "prependTo"](contentTable) } tableElement.remove(); $freeSpaceRowElements = _this4._getFreeSpaceRowElements(contentTable); removeEmptyRows($freeSpaceRowElements, FREESPACE_CLASS); if (change.removeCount) { _this4._removeRowsElements(contentTable, change.removeCount, changeType) } _this4._restoreErrorRow(contentTable); d.resolve() })).fail(d.reject) } else { this.callBase.apply(this, arguments).done((function() { if ("update" === changeType) { _this4._restoreErrorRow(contentTable) } d.resolve() })).fail(d.reject) } return d.promise().done((function() { _this4._updateBottomLoading() })) }, _addVirtualRow: function($table, isFixed, location, position) { if (!position) { return } var $virtualRow = this._createEmptyRow(VIRTUAL_ROW_CLASS, isFixed, position); $virtualRow = this._wrapRowIfNeed($table, $virtualRow); this._appendEmptyRow($table, $virtualRow, location) }, _updateContentItemSizes: function() { var rowHeights = this._getRowHeights(); var correctedRowHeights = this._correctRowHeights(rowHeights); this._dataController.setContentItemSizes(correctedRowHeights) }, _updateViewportSize: function(viewportHeight, scrollTop) { if (!(0, _type.isDefined)(viewportHeight)) { viewportHeight = this._hasHeight ? (0, _size.getOuterHeight)(this.element()) : (0, _size.getOuterHeight)((0, _window.getWindow)()) } this._dataController.viewportHeight(viewportHeight, scrollTop) }, _getRowHeights: function() { var _this$getController, _this$getController$i; var isPopupEditMode = null === (_this$getController = this.getController("editing")) || void 0 === _this$getController ? void 0 : null === (_this$getController$i = _this$getController.isPopupEditMode) || void 0 === _this$getController$i ? void 0 : _this$getController$i.call(_this$getController); var rowElements = this._getRowElements(this._tableElement).toArray(); if (isPopupEditMode) { rowElements = rowElements.filter((function(row) { return !(0, _renderer.default)(row).hasClass(ROW_INSERTED) })) } return rowElements.map((function(row) { return (0, _position.getBoundingRect)(row).height })) }, _correctRowHeights: function(rowHeights) { var dataController = this._dataController; var dataSource = dataController._dataSource; var correctedRowHeights = []; var visibleRows = dataController.getVisibleRows(); var itemSize = 0; var firstCountableItem = true; var lastLoadIndex = -1; for (var i = 0; i < rowHeights.length; i++) { var currentItem = visibleRows[i]; if (!(0, _type.isDefined)(currentItem)) { continue } if (false === this.option(LEGACY_SCROLLING_MODE)) { if (lastLoadIndex >= 0 && lastLoadIndex !== currentItem.loadIndex) { correctedRowHeights.push(itemSize); itemSize = 0 } lastLoadIndex = currentItem.loadIndex } else if (isItemCountableByDataSource(currentItem, dataSource)) { if (firstCountableItem) { firstCountableItem = false } else { correctedRowHeights.push(itemSize); itemSize = 0 } } itemSize += rowHeights[i] } itemSize > 0 && correctedRowHeights.push(itemSize); return correctedRowHeights }, _updateContentPosition: function(isRender) { var _this5 = this; var dataController = this._dataController; var rowHeight = this._rowHeight || 20; dataController.viewportItemSize(rowHeight); if (isVirtualMode(this) || _uiGrid_core2.default.isVirtualRowRendering(this)) { if (!isRender) { this._updateContentItemSizes() } var top = dataController.getContentOffset("begin"); var bottom = dataController.getContentOffset("end"); var $tables = this.getTableElements(); var $virtualRows = $tables.children("tbody").children("." + VIRTUAL_ROW_CLASS); removeEmptyRows($virtualRows, VIRTUAL_ROW_CLASS); $tables.each((function(index, element) { var isFixed = index > 0; var prevFixed = _this5._isFixedTableRendering; _this5._isFixedTableRendering = isFixed; _this5._addVirtualRow((0, _renderer.default)(element), isFixed, "top", top); _this5._addVirtualRow((0, _renderer.default)(element), isFixed, "bottom", bottom); _this5._isFixedTableRendering = prevFixed })) } }, _isTableLinesDisplaysCorrect: function(table) { var hasColumnLines = table.find("." + COLUMN_LINES_CLASS).length > 0; return hasColumnLines === this.option("showColumnLines") }, _isColumnElementsEqual: function($columns, $virtualColumns) { var result = $columns.length === $virtualColumns.length; if (result) { (0, _iterator.each)($columns, (function(index, element) { if (element.style.width !== $virtualColumns[index].style.width) { result = false; return result } })) } return result }, _getCellClasses: function(column) { var classes = []; var cssClass = column.cssClass; var isExpandColumn = "expand" === column.command; cssClass && classes.push(cssClass); isExpandColumn && classes.push(this.addWidgetPrefix(GROUP_SPACE_CLASS)); return classes }, _findBottomLoadPanel: function($contentElement) { var $element = $contentElement || this.element(); var $bottomLoadPanel = $element && $element.find("." + this.addWidgetPrefix(BOTTOM_LOAD_PANEL_CLASS)); if ($bottomLoadPanel && $bottomLoadPanel.length) { return $bottomLoadPanel } }, _updateBottomLoading: function() { var virtualMode = isVirtualMode(this); var appendMode = isAppendMode(this); var showBottomLoading = !this._dataController.hasKnownLastPage() && this._dataController.isLoaded() && (virtualMode || appendMode); var $contentElement = this._findContentElement(); var bottomLoadPanelElement = this._findBottomLoadPanel($contentElement); if (showBottomLoading) { if (!bottomLoadPanelElement) { (0, _renderer.default)("<div>").addClass(this.addWidgetPrefix(BOTTOM_LOAD_PANEL_CLASS)).append(this._createComponent((0, _renderer.default)("<div>"), _load_indicator.default).$element()).appendTo($contentElement) } } else if (bottomLoadPanelElement) { bottomLoadPanelElement.remove() } }, _handleScroll: function(e) { var legacyScrollingMode = true === this.option(LEGACY_SCROLLING_MODE); var zeroTopPosition = 0 === e.scrollOffset.top; var isScrollTopChanged = this._scrollTop !== e.scrollOffset.top; var hasScrolled = isScrollTopChanged || e.forceUpdateScrollPosition; var isValidScrollTarget = this._hasHeight || !legacyScrollingMode && zeroTopPosition; if (hasScrolled && isValidScrollTarget && this._rowHeight) { this._scrollTop = e.scrollOffset.top; var isVirtualRowRendering = isVirtualMode(this) || "standard" !== this.option("scrolling.rowRenderingMode"); if (isVirtualRowRendering && false === this.option(LEGACY_SCROLLING_MODE)) { this._updateContentItemSizes(); this._updateViewportSize(null, this._scrollTop) } this._dataController.setViewportPosition(e.scrollOffset.top) } this.callBase.apply(this, arguments) }, _needUpdateRowHeight: function(itemsCount) { return this.callBase.apply(this, arguments) || itemsCount > 0 && isAppendMode(this) && !_uiGrid_core2.default.isVirtualRowRendering(this) }, _updateRowHeight: function() { this.callBase.apply(this, arguments); if (this._rowHeight) { this._updateContentPosition(); var viewportHeight = this._hasHeight ? (0, _size.getOuterHeight)(this.element()) : (0, _size.getOuterHeight)((0, _window.getWindow)()); var dataController = this._dataController; if (false === this.option(LEGACY_SCROLLING_MODE)) { this._updateViewportSize(viewportHeight); dataController.updateViewport() } else { dataController.viewportSize(Math.ceil(viewportHeight / this._rowHeight)) } } }, updateFreeSpaceRowHeight: function() { var result = this.callBase.apply(this, arguments); if (result) { this._updateContentPosition() } return result }, setLoading: function(isLoading, messageText) { var dataController = this._dataController; var hasBottomLoadPanel = dataController.pageIndex() > 0 && dataController.isLoaded() && !!this._findBottomLoadPanel(); if (false === this.option(LEGACY_SCROLLING_MODE) && isLoading && dataController.isViewportChanging()) { return } if (hasBottomLoadPanel) { isLoading = false } this.callBase.call(this, isLoading, messageText) }, _resizeCore: function() { var that = this; var $element = that.element(); that.callBase(); if (that.component.$element() && !that._windowScroll && $element.closest((0, _window.getWindow)().document).length) { that._windowScroll = (0, _uiGrid_core.subscribeToExternalScrollers)($element, (function(scrollPos) { if (!that._hasHeight && that._rowHeight) { that._dataController.setViewportPosition(scrollPos) } }), that.component.$element()); that.on("disposing", (function() { that._windowScroll.dispose() })) } if (false !== this.option(LEGACY_SCROLLING_MODE)) { that.loadIfNeed() } }, loadIfNeed: function() { var _dataController$loadI; var dataController = this._dataController; null === dataController || void 0 === dataController ? void 0 : null === (_dataController$loadI = dataController.loadIfNeed) || void 0 === _dataController$loadI ? void 0 : _dataController$loadI.call(dataController) }, setColumnWidths: function(widths) { var scrollable = this.getScrollable(); var $content; this.callBase.apply(this, arguments); if ("virtual" === this.option("scrolling.mode")) { $content = scrollable ? (0, _renderer.default)(scrollable.content()) : this.element(); this.callBase(widths, $content.children("." + this.addWidgetPrefix(CONTENT_CLASS)).children(":not(." + this.addWidgetPrefix(TABLE_CONTENT_CLASS) + ")")) } }, _restoreErrorRow: function() { if (false === this.option(LEGACY_SCROLLING_MODE)) { var errorHandling = this.getController("errorHandling"); null === errorHandling || void 0 === errorHandling ? void 0 : errorHandling.removeErrorRow() } this.callBase.apply(this, arguments) }, dispose: function() { clearTimeout(this._scrollTimeoutID); this.callBase() } } }(); var virtualScrollingModule = { defaultOptions: function() { return { scrolling: { timeout: 300, updateTimeout: 300, minTimeout: 0, renderingThreshold: 100, removeInvisiblePages: true, rowPageSize: 5, prerenderedRowChunkSize: 1, mode: "standard", preloadEnabled: false, rowRenderingMode: "standard", loadTwoPagesOnStart: false, legacyMode: false, prerenderedRowCount: 1 } } }, extenders: { dataSourceAdapter: VirtualScrollingDataSourceAdapterExtender, controllers: { data: function() { var members = { _refreshDataSource: function() { var baseResult = this.callBase.apply(this, arguments) || (new _deferred.Deferred).resolve().promise(); baseResult.done(this.initVirtualRows.bind(this)); return baseResult }, _loadDataSource: function() { if (this._rowsScrollController && isVirtualPaging(this)) { var _this$_dataSource; var _ref = (0, _type.isDefined)(this._loadViewportParams) ? this.getLoadPageParams() : {}, loadPageCount = _ref.loadPageCount; loadPageCount >= 1 && (null === (_this$_dataSource = this._dataSource) || void 0 === _this$_dataSource ? void 0 : _this$_dataSource.loadPageCount(loadPageCount)) } return this.callBase.apply(this, arguments) }, getRowPageSize: function() { var rowPageSize = this.option("scrolling.rowPageSize"); var pageSize = this.pageSize(); return pageSize && pageSize < rowPageSize ? pageSize : rowPageSize }, reload: function() { var _this6 = this; var rowsScrollController = this._rowsScrollController || this._dataSource; var itemIndex = rowsScrollController && rowsScrollController.getItemIndexByPosition(); var result = this.callBase.apply(this, arguments); return result && result.done((function() { if (isVirtualMode(_this6) || _uiGrid_core2.default.isVirtualRowRendering(_this6)) { var rowIndexOffset = _this6.getRowIndexOffset(); var rowIndex = Math.floor(itemIndex) - rowIndexOffset; var component = _this6.component; var scrollable = component.getScrollable && component.getScrollable(); var isSortingOperation = _this6.dataSource().operationTypes().sorting; if (scrollable && !isSortingOperation && rowIndex >= 0) { var rowElement = component.getRowElement(rowIndex); var $rowElement = rowElement && rowElement[0] && (0, _renderer.default)(rowElement[0]); var top = $rowElement && $rowElement.position().top; var isChromeLatest = _browser.default.chrome && _browser.default.version >= 91; var allowedTopOffset = _browser.default.mozilla || isChromeLatest ? 1 : 0; if (top > allowedTopOffset) { top = Math.round(top + (0, _size.getOuterHeight)($rowElement) * (itemIndex % 1)); scrollable.scrollTo({ y: top }) } } } })) }, initVirtualRows: function() { var _this7 = this; var virtualRowsRendering = _uiGrid_core2.default.isVirtualRowRendering(this); this._allItems = null; this._loadViewportParams = null; if ("virtual" !== this.option("scrolling.mode") && true !== virtualRowsRendering || false === virtualRowsRendering || false !== this.option(LEGACY_SCROLLING_MODE) && !this.option("scrolling.rowPageSize")) { this._visibleItems = null; this._rowsScrollController = null; return } var pageIndex = !isVirtualMode(this) && this.pageIndex() >= this.pageCount() ? this.pageCount() - 1 : this.pageIndex(); this._rowPageIndex = Math.ceil(pageIndex * this.pageSize() / this.getRowPageSize()); this._visibleItems = false === this.option(LEGACY_SCROLLING_MODE) ? null : []; this._viewportChanging = false; this._needUpdateViewportAfterLoading = false; if (!this._rowsScrollController) { this._rowsScrollController = new _uiGrid_core.VirtualScrollController(this.component, this._getRowsScrollDataOptions(), true); this._rowsScrollController.positionChanged.add((function() { var _this7$_dataSource; if (false === _this7.option(LEGACY_SCROLLING_MODE)) { _this7._viewportChanging = true; _this7.loadViewport(); _this7._viewportChanging = false; return } null === (_this7$_dataSource = _this7._dataSource) || void 0 === _this7$_dataSource ? void 0 : _this7$_dataSource.setViewportItemIndex(_this7._rowsScrollController.getViewportItemIndex()) })) } if (false === this.option(LEGACY_SCROLLING_MODE)) { this._updateLoadViewportParams() } if (this.isLoaded() && false !== this.option(LEGACY_SCROLLING_MODE)) { this._rowsScrollController.load() } }, isViewportChanging: function() { return this._viewportChanging }, _getRowsScrollDataOptions: function() { var that = this; var isItemCountable = function(item) { return isItemCountableByDataSource(item, that._dataSource) }; return { pageSize: function() { return that.getRowPageSize() }, loadedOffset: function() { var _that$_dataSource; return isVirtualMode(that) && (null === (_that$_dataSource = that._dataSource) || void 0 === _that$_dataSource ? void 0 : _that$_dataSource.lastLoadOptions().skip) || 0 }, loadedItemCount: function() { return that._itemCount }, totalItemsCount: function() { if (isVirtualPaging(that)) { return that.totalItemsCount() } return false === that.option(LEGACY_SCROLLING_MODE) ? that._itemCount : that._items.filter(isItemCountable).length }, hasKnownLastPage: function() { return false === that.option(LEGACY_SCROLLING_MODE) ? that.hasKnownLastPage() : true }, pageIndex: function(index) { if (void 0 !== index) { that._rowPageIndex = index } return that._rowPageIndex }, isLoading: function() { return that.isLoading() }, pageCount: function() { var pageCount = Math.ceil(this.totalItemsCount() / this.pageSize()); return pageCount ? pageCount : 1 }, load: function() { if (that._rowsScrollController.pageIndex() >= this.pageCount()) { that._rowPageIndex = this.pageCount() - 1; that._rowsScrollController.pageIndex(that._rowPageIndex) } if (!this.items().length && this.totalItemsCount()) { return } that._rowsScrollController.handleDataChanged((function(change) { change = change || {}; change.changeType = change.changeType || "refresh"; change.items = change.items || that._visibleItems; that._visibleItems.forEach((function(item, index) { item.rowIndex = index })); that._fireChanged(change) })) }, updateLoading: function() {}, itemsCount: function() { return this.items(true).length }, correctCount: function(items, count, fromEnd) { return _correctCount(items, count, fromEnd, (function(item, isNextAfterLast, fromEnd) { if (item.isNewRow) { return isNextAfterLast && !fromEnd } if (isNextAfterLast && fromEnd) { return !item.isNewRow } return isItemCountable(item) })) }, items: function(countableOnly) { var result = that._items; if (that.option(LEGACY_SCROLLING_MODE)) { var dataSource = that.dataSource(); var virtualItemsCount = null === dataSource || void 0 === dataSource ? void 0 : dataSource.virtualItemsCount(); var begin = virtualItemsCount ? virtualItemsCount.begin : 0; var rowPageSize = that.getRowPageSize(); var skip = that._rowPageIndex * rowPageSize - begin; var take = rowPageSize; if (skip < 0) { return [] } if (skip) { skip = this.correctCount(result, skip); result = result.slice(skip) } if (take) { take = this.correctCount(result, take); result = result.slice(0, take) } } return countableOnly ? result.filter(isItemCountable) : result }, viewportItems: function(items) { if (items && false !== that.option(LEGACY_SCROLLING_MODE)) { that._visibleItems = items } return that._visibleItems }, onChanged: function() {}, changingDuration: function(e) { var dataSource = that.dataSource(); if (null !== dataSource && void 0 !== dataSource && dataSource.isLoading() && false !== that.option(LEGACY_SCROLLING_MODE)) { return LOAD_TIMEOUT } return (null === dataSource || void 0 === dataSource ? void 0 : dataSource._renderTime) || 0 } } }, _updateItemsCore: function(change) { var _this8 = this; var delta = this.getRowIndexDelta(); this.callBase.apply(this, arguments); if (false === this.option(LEGACY_SCROLLING_MODE) && _uiGrid_core2.default.isVirtualRowRendering(this)) { if ("update" === change.changeType && 0 === change.rowIndices.length && change.cancelEmptyChanges) { change.cancel = true } return } var rowsScrollController = this._rowsScrollController; if (rowsScrollController) { var visibleItems = this._visibleItems; var isRefresh = "refresh" === change.changeType || change.isLiveUpdate; if ("append" === change.changeType && change.items && !change.items.length) { return } if (isRefresh || "append" === change.changeType || "prepend" === change.changeType) { change.cancel = true; isRefresh && rowsScrollController.reset(true); rowsScrollController.load() } else { if ("update" === change.changeType) { change.rowIndices.forEach((function(rowIndex, index) { var changeType = change.changeTypes[index]; var newItem = change.items[index]; if ("update" === changeType) { visibleItems[rowIndex] = newItem } else if ("insert" === changeType) { visibleItems.splice(rowIndex, 0, newItem) } else if ("remove" === changeType) { visibleItems.splice(rowIndex, 1) } })) } else { visibleItems.forEach((function(item, index) { visibleItems[index] = _this8._items[index + delta] || visibleItems[index] })); change.items = visibleItems } updateItemIndices(visibleItems) } } }, _updateLoadViewportParams: function() { var viewportParams = this._rowsScrollController.getViewportParams(); var pageSize = this.pageSize(); if (viewportParams && !isVirtualPaging(this) && pageSize > 0) {