UNPKG

handsontable

Version:

Handsontable is a JavaScript Data Grid available for React, Angular and Vue.

190 lines (180 loc) 6.16 kB
"use strict"; exports.__esModule = true; require("core-js/modules/es.error.cause.js"); require("core-js/modules/es.array.push.js"); var _viewSizeSet = require("./viewSizeSet"); var _viewDiffer = require("./viewDiffer"); function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /** * Executive model for each table renderer. It's responsible for injecting DOM nodes in a * specified order and adjusting the number of elements in the root node. * * Only this class have rights to juggling DOM elements within the root node (see render method). * * @class {OrderView} */ class OrderView { constructor(rootNode, nodesPool) { /** * The root node to manage with. * * @type {HTMLElement} */ _defineProperty(this, "rootNode", void 0); /** * Factory for newly created DOM elements. * * @type {function(number): HTMLElement} */ _defineProperty(this, "nodesPool", void 0); /** * Holder for sizing and positioning of the view. * * @type {ViewSizeSet} */ _defineProperty(this, "sizeSet", new _viewSizeSet.ViewSizeSet()); /** * The list of DOM elements which are rendered for this render cycle. * * @type {HTMLElement[]} */ _defineProperty(this, "collectedNodes", []); /** * The differ which calculates the differences between current and next view. It generates * commands that are processed by the OrderView (see `applyCommand` method). * * @type {ViewDiffer} */ _defineProperty(this, "viewDiffer", new _viewDiffer.ViewDiffer(this.sizeSet)); /** * The list of render commands to execute. The command is an array with the following * structure: [ * [ * 'prepend' | 'append' | 'insert_before' | 'replace' | 'remove', // command name * 10, // processed node index * 9, // previous node index (only for 'insert_before' and 'replace' commands) * 8 // node index to remove (only for 'insert_before' command) * ], * ... * ]. * * @type {Array[]} */ _defineProperty(this, "leads", []); this.rootNode = rootNode; this.nodesPool = nodesPool; } /** * Sets the size for rendered elements. It can be a size for rows, cells or size for row * headers etc. It depends for what table renderer this instance was created. * * @param {number} size The size. * @returns {OrderView} */ setSize(size) { this.sizeSet.setSize(size); return this; } /** * Sets the offset for rendered elements. The offset describes the shift between 0 and * the first rendered element according to the scroll position. * * @param {number} offset The offset. * @returns {OrderView} */ setOffset(offset) { this.sizeSet.setOffset(offset); return this; } /** * Checks if this instance of the view shares the root node with another instance. This happens only once when * a row (TR) as a root node is managed by two OrderView instances. If this happens another DOM injection * algorithm is performed to achieve consistent order. * * @returns {boolean} */ isSharedViewSet() { return this.sizeSet.isShared(); } /** * Returns rendered DOM element based on visual index. * * @param {number} visualIndex The visual index. * @returns {HTMLElement} */ getNode(visualIndex) { return visualIndex < this.collectedNodes.length ? this.collectedNodes[visualIndex] : null; } /** * Returns currently processed DOM element. * * @returns {HTMLElement} */ getCurrentNode() { const length = this.collectedNodes.length; return length > 0 ? this.collectedNodes[length - 1] : null; } /** * Applies the commands generated by the differ into the specific DOM operations. * * @param {Array} command The command to apply. */ applyCommand(command) { const { rootNode } = this; const [name, nodeIndex, nodePrevIndex, nodeIndexToRemove] = command; const node = this.nodesPool(nodeIndex); this.collectedNodes.push(node); switch (name) { case 'prepend': rootNode.insertBefore(node, rootNode.firstChild); break; case 'append': rootNode.appendChild(node); break; case 'insert_before': rootNode.insertBefore(node, this.nodesPool(nodePrevIndex)); // To keep the constant length of child nodes (after inserting a node) remove the last child. rootNode.removeChild(this.nodesPool(nodeIndexToRemove)); break; case 'replace': rootNode.replaceChild(node, this.nodesPool(nodePrevIndex)); break; case 'remove': rootNode.removeChild(node); break; default: break; } } /** * Setups and prepares all necessary properties and start the rendering process. * This method has to be called only once (at the start) for the render cycle. */ start() { this.collectedNodes.length = 0; this.leads = this.viewDiffer.diff(); } /** * Renders the DOM element based on visual index (which is calculated internally). * This method has to be called as many times as the size count is met (to cover all previously rendered DOM elements). */ render() { if (this.leads.length > 0) { this.applyCommand(this.leads.shift()); } } /** * Ends the render process. * This method has to be called only once (at the end) for the render cycle. */ end() { while (this.leads.length > 0) { this.applyCommand(this.leads.shift()); } } } exports.OrderView = OrderView;