handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
100 lines (95 loc) • 3.55 kB
JavaScript
;
exports.__esModule = true;
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); }
/**
* Differ based renderer adapter that uses ViewDiffer for efficient DOM manipulation.
* This is the default implementation for most browsers.
*
* @class {DifferBasedRendererAdapter}
*/
class DifferBasedRendererAdapter {
/**
* @param {OrderView} orderView The OrderView instance.
*/
constructor(orderView) {
/**
* 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.orderView = orderView;
}
/**
* Applies the commands generated by the differ into the specific DOM operations.
*
* @param {Array} command The command to apply.
*/
applyCommand(command) {
const {
rootNode
} = this.orderView;
const [name, nodeIndex, nodePrevIndex, nodeIndexToRemove] = command;
const node = this.orderView.nodesPool(nodeIndex);
this.orderView.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.orderView.nodesPool(nodePrevIndex));
// To keep the constant length of child nodes (after inserting a node) remove the last child.
rootNode.removeChild(this.orderView.nodesPool(nodeIndexToRemove));
break;
case 'replace':
rootNode.replaceChild(node, this.orderView.nodesPool(nodePrevIndex));
break;
case 'remove':
rootNode.removeChild(node);
break;
default:
break;
}
}
/**
* Sets up and prepares all necessary properties and starts the rendering process.
* This method has to be called only once (at the start) for the render cycle.
*/
start() {
this.orderView.collectedNodes.length = 0;
this.leads = this.orderView.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.DifferBasedRendererAdapter = DifferBasedRendererAdapter;