@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
205 lines (199 loc) • 10.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isTableControlsButton = exports.isTableContainerOrWrapper = exports.isRowControlsButton = exports.isResizeHandleDecoration = exports.isInsertRowButton = exports.isDragRowFloatingInsertDot = exports.isDragCornerButton = exports.isDragColumnFloatingInsertDot = exports.isCornerButton = exports.isColumnControlsDecorations = exports.isCell = exports.hasResizeHandler = exports.getTree = exports.getTop = exports.getMousePositionVerticalRelativeByElement = exports.getMousePositionHorizontalRelativeByElement = exports.getColumnOrRowIndex = exports.findNearestCellIndexToPoint = void 0;
var _utils = require("@atlaskit/editor-common/utils");
var _types = require("../../types");
var isCell = exports.isCell = function isCell(node) {
return Boolean(node && (['TH', 'TD'].indexOf(node.tagName) > -1 || !!(0, _utils.closestElement)(node, ".".concat(_types.TableCssClassName.TABLE_HEADER_CELL)) || !!(0, _utils.closestElement)(node, ".".concat(_types.TableCssClassName.TABLE_CELL))));
};
var isCornerButton = exports.isCornerButton = function isCornerButton(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.CONTROLS_CORNER_BUTTON);
};
var isInsertRowButton = exports.isInsertRowButton = function isInsertRowButton(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.CONTROLS_INSERT_ROW) || (0, _utils.closestElement)(node, ".".concat(_types.TableCssClassName.CONTROLS_INSERT_ROW)) || (0, _utils.containsClassName)(node, _types.TableCssClassName.CONTROLS_BUTTON_OVERLAY) && (0, _utils.closestElement)(node, ".".concat(_types.TableCssClassName.ROW_CONTROLS));
};
var getColumnOrRowIndex = exports.getColumnOrRowIndex = function getColumnOrRowIndex(target) {
return [parseInt(target.getAttribute('data-start-index') || '-1', 10), parseInt(target.getAttribute('data-end-index') || '-1', 10)];
};
var isColumnControlsDecorations = exports.isColumnControlsDecorations = function isColumnControlsDecorations(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.COLUMN_CONTROLS_DECORATIONS);
};
var isRowControlsButton = exports.isRowControlsButton = function isRowControlsButton(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.ROW_CONTROLS_BUTTON) || (0, _utils.containsClassName)(node, _types.TableCssClassName.NUMBERED_COLUMN_BUTTON);
};
var isResizeHandleDecoration = exports.isResizeHandleDecoration = function isResizeHandleDecoration(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.RESIZE_HANDLE_DECORATION);
};
var isTableControlsButton = exports.isTableControlsButton = function isTableControlsButton(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.CONTROLS_BUTTON) || (0, _utils.containsClassName)(node, _types.TableCssClassName.ROW_CONTROLS_BUTTON_WRAP);
};
var isTableContainerOrWrapper = exports.isTableContainerOrWrapper = function isTableContainerOrWrapper(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.TABLE_CONTAINER) || (0, _utils.containsClassName)(node, _types.TableCssClassName.TABLE_NODE_WRAPPER);
};
/** drag-and-drop classes */
var isDragRowFloatingInsertDot = exports.isDragRowFloatingInsertDot = function isDragRowFloatingInsertDot(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER);
};
var isDragColumnFloatingInsertDot = exports.isDragColumnFloatingInsertDot = function isDragColumnFloatingInsertDot(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER);
};
var isDragCornerButton = exports.isDragCornerButton = function isDragCornerButton(node) {
return (0, _utils.containsClassName)(node, _types.TableCssClassName.DRAG_CORNER_BUTTON) || (0, _utils.containsClassName)(node, _types.TableCssClassName.DRAG_CORNER_BUTTON_INNER);
};
/*
* This function returns which side of a given element the mouse cursor is,
* using as a base the half of the width by default, for example:
*
* legend
* ⌖ = mouse pointer
* ▒ = gap
*
* given this box:
* ┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
* ┃ ┊ ┃
* ┃ left ┊ right ┃
* ┃ ┊ ┃
* ┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┛
*
* if the mouse is on the left, it will return `left`,
* if it is on the right it will return `right`.
*
* You can extend this behavior using the parameter `gapInPixels`
* to determinate if the mouse is inside of a gap for each side,
* for example:
*
* given `gapInPixels` is `5`
* and given this box:
* ┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
* ┃▒▒▒▒▒ ┊ ▒▒▒▒▒┃
* ┃▒▒▒▒▒ left ┊ right ▒▒▒▒▒┃
* ┃▒▒▒▒▒ ┊ ▒▒▒▒▒┃
* ┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┛
*
* if the mouse cursor is inside of the gap like that:
*
* ┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
* ┃▒▒▒▒▒ ┊ ▒▒▒▒▒┃
* ┃▒▒⌖▒▒ left ┊ right ▒▒▒▒▒┃
* ┃▒▒▒▒▒ ┊ ▒▒▒▒▒┃
* ┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┛
*
* the function will return `left` because the mouse is inside of the gap on the left side.
*
* if the mouse cursor is outside of the gap like that:
*
* ┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
* ┃▒▒▒▒▒ ┊ ▒▒▒▒▒┃
* ┃▒▒▒▒▒ left ⌖ ┊ right ▒▒▒▒▒┃
* ┃▒▒▒▒▒ ┊ ▒▒▒▒▒┃
* ┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┛
*
* the function will return `null` because the mouse is inside of left
* but is outside of the gap.
*
* the same is valid to the right side.
*/
/**
* This can be used with mouse events to determine the left/right side of the target the pointer is closest too.
*
* WARNING: This metod reads properties which can trigger a reflow; use this wisely.
*
* @param mouseEvent
* @param gapInPixels
* @returns
*/
var getMousePositionHorizontalRelativeByElement = exports.getMousePositionHorizontalRelativeByElement = function getMousePositionHorizontalRelativeByElement(mouseEvent, offsetX, gapInPixels) {
var element = mouseEvent.target;
if (element instanceof HTMLElement) {
var width = element.clientWidth; // reflow
var x = !Number.isNaN(offsetX) ? offsetX : mouseEvent.offsetX; // reflow
if (width <= 0) {
return null;
}
if (!gapInPixels) {
return x / width > 0.5 ? 'right' : 'left';
} else {
if (x <= gapInPixels) {
return 'left';
} else if (x >= width - gapInPixels) {
return 'right';
}
}
}
return null;
};
var getMousePositionVerticalRelativeByElement = exports.getMousePositionVerticalRelativeByElement = function getMousePositionVerticalRelativeByElement(mouseEvent) {
var element = mouseEvent.target;
if (element instanceof HTMLElement) {
var elementRect = element.getBoundingClientRect();
if (elementRect.height <= 0) {
return null;
}
var y = mouseEvent.clientY - elementRect.top;
return y / elementRect.height > 0.5 ? 'bottom' : 'top';
}
return null;
};
var hasResizeHandler = exports.hasResizeHandler = function hasResizeHandler(_ref) {
var columnEndIndexTarget = _ref.columnEndIndexTarget,
target = _ref.target;
var tableElement = (0, _utils.closestElement)(target, 'table');
if (!tableElement) {
return false;
}
var query = [".".concat(_types.TableCssClassName.RESIZE_HANDLE_DECORATION), "[data-end-index=\"".concat(columnEndIndexTarget, "\"]")];
var decorationElement = tableElement.querySelectorAll(query.join(''));
if (!decorationElement || decorationElement.length === 0) {
return false;
}
return true;
};
var getTree = exports.getTree = function getTree(tr) {
// pm renders into tbody, owned by react
var tbody = tr.parentElement;
if (!tbody) {
return null;
}
// rendered by react
var table = tbody.parentElement;
if (!table) {
return null;
}
// rendered by react
var wrapper = table.parentElement;
if (!wrapper) {
return null;
}
return {
wrapper: wrapper,
table: table
};
};
var getTop = exports.getTop = function getTop(element) {
var _element$getBoundingC, _element$getBoundingC2;
if (!element || element instanceof Window) {
return 0;
}
return (_element$getBoundingC = element === null || element === void 0 || (_element$getBoundingC2 = element.getBoundingClientRect) === null || _element$getBoundingC2 === void 0 || (_element$getBoundingC2 = _element$getBoundingC2.call(element)) === null || _element$getBoundingC2 === void 0 ? void 0 : _element$getBoundingC2.top) !== null && _element$getBoundingC !== void 0 ? _element$getBoundingC : 0;
};
var findNearestCellIndexToPoint = exports.findNearestCellIndexToPoint = function findNearestCellIndexToPoint(x, y) {
var _cell$parentElement;
var elements = document.elementsFromPoint(x, y);
var cell = elements.find(function (el) {
return el.nodeName.toUpperCase() === 'TD' || el.nodeName.toUpperCase() === 'TH';
});
var row = (_cell$parentElement = cell === null || cell === void 0 ? void 0 : cell.parentElement) !== null && _cell$parentElement !== void 0 ? _cell$parentElement : undefined;
if (!Number.isFinite(row === null || row === void 0 ? void 0 : row.rowIndex) || !Number.isFinite(cell === null || cell === void 0 ? void 0 : cell.cellIndex)) {
return undefined;
}
return {
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
row: row.rowIndex,
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
col: cell.cellIndex
};
};