UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

211 lines (205 loc) 11.2 kB
"use strict"; 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 = exports.areAllRectsZero = 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 }; }; var areAllRectsZero = exports.areAllRectsZero = function areAllRectsZero(entry) { var rects = [entry.boundingClientRect, entry.rootBounds, entry.intersectionRect]; return rects.every(function (rect) { return rect && rect.width === 0 && rect.height === 0 && rect.top === 0 && rect.left === 0 && rect.bottom === 0 && rect.right === 0 && rect.x === 0 && rect.y === 0; }); };