handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
170 lines (161 loc) • 6.02 kB
JavaScript
;
exports.__esModule = true;
exports.align = align;
exports.checkSelectionConsistency = checkSelectionConsistency;
exports.getAlignmentClasses = getAlignmentClasses;
exports.getAlignmentComparatorByClass = getAlignmentComparatorByClass;
exports.getDocumentOffsetByElement = getDocumentOffsetByElement;
exports.markLabelAsSelected = markLabelAsSelected;
exports.prepareHorizontalAlignClass = prepareHorizontalAlignClass;
exports.prepareVerticalAlignClass = prepareVerticalAlignClass;
var _array = require("../../helpers/array");
/**
* @param {string} className The full element class name to process.
* @param {string} alignment The alignment class name to compare with.
* @returns {string}
*/
function prepareVerticalAlignClass(className, alignment) {
if (className.indexOf(alignment) !== -1) {
return className;
}
const replacedClassName = className.replace('htTop', '').replace('htMiddle', '').replace('htBottom', '').replace(' ', '');
return `${replacedClassName} ${alignment}`;
}
/**
* @param {string} className The full element class name to process.
* @param {string} alignment The alignment class name to compare with.
* @returns {string}
*/
function prepareHorizontalAlignClass(className, alignment) {
if (className.indexOf(alignment) !== -1) {
return className;
}
const replacedClassName = className.replace('htLeft', '').replace('htCenter', '').replace('htRight', '').replace('htJustify', '').replace(' ', '');
return `${replacedClassName} ${alignment}`;
}
/**
* @param {CellRange[]} ranges An array of the cell ranges.
* @param {Function} callback The callback function.
* @returns {object}
*/
function getAlignmentClasses(ranges, callback) {
const classes = {};
(0, _array.arrayEach)(ranges, range => {
range.forAll((row, col) => {
// Alignment classes should only collected within cell ranges. We skip header coordinates.
if (row >= 0 && col >= 0) {
if (!classes[row]) {
classes[row] = [];
}
classes[row][col] = callback(row, col);
}
});
});
return classes;
}
/**
* @param {CellRange[]} ranges An array of the cell ranges.
* @param {string} type The type of the alignment axis ('horizontal' or 'vertical').
* @param {string} alignment CSS class name to add.
* @param {Function} cellDescriptor The function which fetches the cell meta object based in passed coordinates.
* @param {Function} propertySetter The function which contains logic for added/removed alignment.
*/
function align(ranges, type, alignment, cellDescriptor, propertySetter) {
(0, _array.arrayEach)(ranges, range => {
range.forAll((row, col) => {
// Alignment classes should only collected within cell ranges. We skip header coordinates.
if (row >= 0 && col >= 0) {
applyAlignClassName(row, col, type, alignment, cellDescriptor, propertySetter);
}
});
});
}
/**
* @param {number} row The visual row index.
* @param {number} col The visual column index.
* @param {string} type The type of the alignment axis ('horizontal' or 'vertical').
* @param {string} alignment CSS class name to add.
* @param {Function} cellDescriptor The function which fetches the cell meta object based in passed coordinates.
* @param {Function} propertySetter The function which contains logic for added/removed alignment.
*/
function applyAlignClassName(row, col, type, alignment, cellDescriptor, propertySetter) {
const cellMeta = cellDescriptor(row, col);
let className = alignment;
if (cellMeta.className) {
if (type === 'vertical') {
className = prepareVerticalAlignClass(cellMeta.className, alignment);
} else {
className = prepareHorizontalAlignClass(cellMeta.className, alignment);
}
}
propertySetter(row, col, 'className', className);
}
/**
* @param {string} label The label text.
* @returns {string}
*/
function markLabelAsSelected(label) {
// workaround for https://github.com/handsontable/handsontable/issues/1946
return `<span class="selected">${String.fromCharCode(10003)}</span>${label}`;
}
/**
* @param {CellRange[]} ranges An array of the cell ranges.
* @param {Function} comparator The comparator function.
* @returns {boolean}
*/
function checkSelectionConsistency(ranges, comparator) {
let result = false;
if (Array.isArray(ranges)) {
(0, _array.arrayEach)(ranges, range => {
range.forAll((row, col) => {
// Selection consistency should only check within cell ranges. We skip header coordinates.
if (row >= 0 && col >= 0 && comparator(row, col)) {
result = true;
return false;
}
});
return result;
});
}
return result;
}
/**
* Returns document offset based on the passed element. If the document objects between element and the
* base document are not the same the offset as top and left properties will be returned.
*
* @param {Element} elementToCheck The element to compare with Document object.
* @param {Document} baseDocument The base Document object.
* @returns {{ top: number, left: number }}
*/
function getDocumentOffsetByElement(elementToCheck, baseDocument) {
const offset = {
top: 0,
left: 0
};
if (baseDocument !== elementToCheck.ownerDocument) {
const {
frameElement
} = baseDocument.defaultView;
const {
top,
left
} = frameElement.getBoundingClientRect();
offset.top = top;
offset.left = left;
}
return offset;
}
/**
* Prepares comparator function consumable by checkSelectionConsistency
* Comparator function checks if the cell has the provided class name.
*
* @param {string} htClassName The class name to check.
* @returns {Function} Returns the comparator function.
* Use with .bind, .call or .apply to pass the Handsontable instance.
*/
function getAlignmentComparatorByClass(htClassName) {
return function (row, col) {
const className = this.getCellMeta(row, col).className;
return className && className.indexOf(htClassName) !== -1;
};
}