"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _xeUtils = _interopRequireDefault(require("xe-utils")); var _util = require("../../src/util"); var _dom = require("../../../ui/src/dom"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const browseObj = _xeUtils.default.browse(); function getTargetOffset(target, container) { let offsetTop = 0; let offsetLeft = 0; const triggerCheckboxLabel = !browseObj.firefox && (0, _dom.hasClass)(target, 'vxe-checkbox--label'); if (triggerCheckboxLabel) { const checkboxLabelStyle = getComputedStyle(target); offsetTop -= _xeUtils.default.toNumber(checkboxLabelStyle.paddingTop); offsetLeft -= _xeUtils.default.toNumber(checkboxLabelStyle.paddingLeft); } while (target && target !== container) { offsetTop += target.offsetTop; offsetLeft += target.offsetLeft; target = target.offsetParent; if (triggerCheckboxLabel) { const checkboxStyle = getComputedStyle(target); offsetTop -= _xeUtils.default.toNumber(checkboxStyle.paddingTop); offsetLeft -= _xeUtils.default.toNumber(checkboxStyle.paddingLeft); } } return { offsetTop, offsetLeft }; } function getCheckboxRangeRows($xeTable, evnt, params, targetTrElem, trRect, offsetClientTop, moveRange) { const props = $xeTable; const reactData = $xeTable; const internalData = $xeTable; const { showOverflow } = props; const { fullAllDataRowIdData, isResizeCellHeight } = internalData; const rowOpts = $xeTable.computeRowOpts; const cellOpts = $xeTable.computeCellOpts; const defaultRowHeight = $xeTable.computeDefaultRowHeight; const { row } = params; let countHeight = 0; let rangeRows = []; let moveSize = 0; const isDown = moveRange > 0; const { scrollYLoad } = reactData; const { afterFullData } = internalData; if (isDown) { moveSize = offsetClientTop + moveRange; } else { moveSize = trRect.height - offsetClientTop + Math.abs(moveRange); } if (scrollYLoad) { const _rowIndex = $xeTable.getVTRowIndex(row); const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height; if (!isCustomCellHeight && showOverflow) { if (isDown) { rangeRows = afterFullData.slice(_rowIndex, _rowIndex + Math.ceil(moveSize / defaultRowHeight)); } else { rangeRows = afterFullData.slice(_rowIndex - Math.floor(moveSize / defaultRowHeight), _rowIndex + 1); } } else { if (isDown) { for (let i = _rowIndex; i < afterFullData.length; i++) { const item = afterFullData[i]; const rowid = $xeTable.getRowid(item); const rowRest = fullAllDataRowIdData[rowid] || {}; countHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight; rangeRows.push(item); if (countHeight > moveSize) { return rangeRows; } } } else { for (let len = _rowIndex; len >= 0; len--) { const item = afterFullData[len]; const rowid = $xeTable.getRowid(item); const rowRest = fullAllDataRowIdData[rowid] || {}; countHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight; rangeRows.push(item); if (countHeight > moveSize) { return rangeRows; } } } } } else { const siblingProp = isDown ? 'next' : 'previous'; while (targetTrElem && countHeight < moveSize) { const rowNodeRest = $xeTable.getRowNode(targetTrElem); if (rowNodeRest) { rangeRows.push(rowNodeRest.item); countHeight += targetTrElem.offsetHeight; targetTrElem = targetTrElem[`${siblingProp}ElementSibling`]; } } } return rangeRows; } function handleMoveSelected($xeTable, evnt, args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow) { const internalData = $xeTable; const { afterFullData, visibleColumn } = internalData; const params = Object.assign({}, args); const _rowIndex = $xeTable.getVTRowIndex(params.row); const _columnIndex = $xeTable.getVTColumnIndex(params.column); evnt.preventDefault(); if (isUpArrow && _rowIndex > 0) { // 移动到上一行 params.rowIndex = _rowIndex - 1; params.row = afterFullData[params.rowIndex]; } else if (isDwArrow && _rowIndex < afterFullData.length - 1) { // 移动到下一行 params.rowIndex = _rowIndex + 1; params.row = afterFullData[params.rowIndex]; } else if (isLeftArrow && _columnIndex) { // 移动到左侧单元格 params.columnIndex = _columnIndex - 1; params.column = visibleColumn[params.columnIndex]; } else if (isRightArrow && _columnIndex < visibleColumn.length - 1) { // 移动到右侧单元格 params.columnIndex = _columnIndex + 1; params.column = visibleColumn[params.columnIndex]; } $xeTable.scrollToRow(params.row, params.column).then(() => { params.cell = $xeTable.getCellElement(params.row, params.column); $xeTable.handleSelected(params, evnt); }); return params; } var _default = exports.default = { methods: { // 处理 Tab 键移动 moveTabSelected(args, isLeft, evnt) { const $xeTable = this; const props = $xeTable; const internalData = $xeTable; const { editConfig } = props; const { afterFullData, visibleColumn } = internalData; const editOpts = $xeTable.computeEditOpts; const rowOpts = $xeTable.computeRowOpts; const currentRowOpts = $xeTable.computeCurrentRowOpts; const columnOpts = $xeTable.computeColumnOpts; const currentColumnOpts = $xeTable.computeCurrentColumnOpts; let targetRow; let targetRowIndex; let targetColumnIndex; const params = Object.assign({}, args); const _rowIndex = $xeTable.getVTRowIndex(params.row); const _columnIndex = $xeTable.getVTColumnIndex(params.column); evnt.preventDefault(); if (isLeft) { // 向左 if (_columnIndex <= 0) { // 如果已经是第一列,则移动到上一行 if (_rowIndex > 0) { targetRowIndex = _rowIndex - 1; targetRow = afterFullData[targetRowIndex]; targetColumnIndex = visibleColumn.length - 1; } } else { targetColumnIndex = _columnIndex - 1; } } else { if (_columnIndex >= visibleColumn.length - 1) { // 如果已经是第一列,则移动到上一行 if (_rowIndex < afterFullData.length - 1) { targetRowIndex = _rowIndex + 1; targetRow = afterFullData[targetRowIndex]; targetColumnIndex = 0; } } else { targetColumnIndex = _columnIndex + 1; } } const targetColumn = visibleColumn[targetColumnIndex]; if (targetColumn) { if (targetRow) { params.rowIndex = targetRowIndex; params.row = targetRow; } else { params.rowIndex = _rowIndex; } params.columnIndex = targetColumnIndex; params.column = targetColumn; params.cell = $xeTable.getCellElement(params.row, params.column); if (rowOpts.isCurrent && currentRowOpts.isFollowSelected) { $xeTable.triggerCurrentRowEvent(evnt, params); } if (columnOpts.isCurrent && currentColumnOpts.isFollowSelected) { $xeTable.triggerCurrentColumnEvent(evnt, params); } if (editConfig) { if (editOpts.trigger === 'click' || editOpts.trigger === 'dblclick') { if (editOpts.mode === 'row') { $xeTable.handleEdit(params, evnt); } else { $xeTable.scrollToRow(params.row, params.column).then(() => { $xeTable.handleSelected(params, evnt); }); } } } else { $xeTable.scrollToRow(params.row, params.column).then(() => { $xeTable.handleSelected(params, evnt); }); } } }, // 处理当前行方向键移动 moveCurrentRow(isUpArrow, isDwArrow, evnt) { const $xeTable = this; const props = $xeTable; const reactData = $xeTable; const internalData = $xeTable; const { treeConfig } = props; const { currentRow } = reactData; const { afterFullData } = internalData; const treeOpts = $xeTable.computeTreeOpts; const childrenField = treeOpts.children || treeOpts.childrenField; let targetRow; if (currentRow) { if (treeConfig) { const { index, items } = _xeUtils.default.findTree(afterFullData, item => item === currentRow, { children: childrenField }); if (isUpArrow && index > 0) { targetRow = items[index - 1]; } else if (isDwArrow && index < items.length - 1) { targetRow = items[index + 1]; } } else { const _rowIndex = $xeTable.getVTRowIndex(currentRow); if (isUpArrow && _rowIndex > 0) { targetRow = afterFullData[_rowIndex - 1]; } else if (isDwArrow && _rowIndex < afterFullData.length - 1) { targetRow = afterFullData[_rowIndex + 1]; } } } else { targetRow = afterFullData[0]; } if (targetRow) { evnt.preventDefault(); const params = { $table: $xeTable, row: targetRow, rowIndex: $xeTable.getRowIndex(targetRow), $rowIndex: $xeTable.getVMRowIndex(targetRow) }; $xeTable.scrollToRow(targetRow).then(() => $xeTable.triggerCurrentRowEvent(evnt, params)); } }, // 处理当前列方向键移动 moveCurrentColumn(isLeftArrow, isRightArrow, evnt) { const $xeTable = this; const reactData = $xeTable; const internalData = $xeTable; const { currentColumn } = reactData; const { visibleColumn } = internalData; let targetCol = null; if (currentColumn) { const _columnIndex = $xeTable.getVTColumnIndex(currentColumn); if (isLeftArrow && _columnIndex > 0) { targetCol = visibleColumn[_columnIndex - 1]; } else if (isRightArrow && _columnIndex < visibleColumn.length - 1) { targetCol = visibleColumn[_columnIndex + 1]; } } else { targetCol = visibleColumn[0]; } if (targetCol) { evnt.preventDefault(); const params = { $table: $xeTable, column: targetCol, columnIndex: $xeTable.getColumnIndex(targetCol), $columnIndex: $xeTable.getVMColumnIndex(targetCol) }; $xeTable.scrollToColumn(targetCol).then(() => $xeTable.triggerCurrentColumnEvent(evnt, params)); } }, // 处理可编辑方向键移动 moveArrowSelected(args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow, evnt) { const $xeTable = this; const props = $xeTable; const { highlightCurrentRow, highlightCurrentColumn } = props; const rowOpts = $xeTable.computeRowOpts; const currentRowOpts = $xeTable.computeCurrentRowOpts; const columnOpts = $xeTable.computeColumnOpts; const currentColumnOpts = $xeTable.computeCurrentColumnOpts; const params = handleMoveSelected($xeTable, evnt, args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow); if (rowOpts.isCurrent || highlightCurrentRow) { if (currentRowOpts.isFollowSelected) { $xeTable.triggerCurrentRowEvent(evnt, params); } else { // 当前行按键上下移动 if ((isUpArrow || isDwArrow) && (rowOpts.isCurrent || highlightCurrentRow)) { $xeTable.moveCurrentRow(isUpArrow, isDwArrow, evnt); } } } if (columnOpts.isCurrent || highlightCurrentColumn) { if (currentColumnOpts.isFollowSelected) { $xeTable.triggerCurrentColumnEvent(evnt, params); } else { // 当前行按键左右移动 if ((isLeftArrow || isRightArrow) && (columnOpts.isCurrent || highlightCurrentColumn)) { $xeTable.moveCurrentColumn(isLeftArrow, isRightArrow, evnt); } } } }, moveEnterSelected(args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow, evnt) { const $xeTable = this; const props = $xeTable; const { highlightCurrentRow, highlightCurrentColumn } = props; const rowOpts = $xeTable.computeRowOpts; const currentRowOpts = $xeTable.computeCurrentRowOpts; const columnOpts = $xeTable.computeColumnOpts; const currentColumnOpts = $xeTable.computeCurrentColumnOpts; const params = handleMoveSelected($xeTable, evnt, args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow); if ((rowOpts.isCurrent || highlightCurrentRow) && currentRowOpts.isFollowSelected) { $xeTable.triggerCurrentRowEvent(evnt, params); } if ((columnOpts.isCurrent || highlightCurrentColumn) && currentColumnOpts.isFollowSelected) { $xeTable.triggerCurrentColumnEvent(evnt, params); } }, // 处理可编辑方向键移动 moveSelected(args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow, evnt) { const $xeTable = this; handleMoveSelected($xeTable, evnt, args, isLeftArrow, isUpArrow, isRightArrow, isDwArrow); }, handleCellMousedownEvent(evnt, params) { const $xeTable = this; const { editConfig, editOpts, handleSelected, checkboxConfig, checkboxOpts, mouseConfig, mouseOpts } = this; if (mouseConfig && mouseOpts.area && $xeTable.triggerCellAreaModownEvent) { return $xeTable.triggerCellAreaModownEvent(evnt, params); } else { if (checkboxConfig && checkboxOpts.range) { this.handleCheckboxRangeEvent(evnt, params); } if (mouseConfig && mouseOpts.selected) { if (!editConfig || editOpts.mode === 'cell') { handleSelected(params, evnt); } } } }, handleCheckboxRangeEvent(evnt, params) { const $xeTable = this; const internalData = $xeTable; const { elemStore } = internalData; const bodyScrollElem = (0, _util.getRefElem)(elemStore['main-body-scroll']); const leftScrollElem = (0, _util.getRefElem)(elemStore['left-body-scroll']); const rightScrollElem = (0, _util.getRefElem)(elemStore['right-body-scroll']); const { column, cell } = params; if (column.type === 'checkbox') { let bodyWrapperElem = bodyScrollElem; if (leftScrollElem && column.fixed === 'left') { bodyWrapperElem = leftScrollElem; } else if (rightScrollElem && column.fixed === 'right') { bodyWrapperElem = rightScrollElem; } if (!bodyWrapperElem) { return; } const el = $xeTable.$refs.refElem; const disX = evnt.clientX; const disY = evnt.clientY; const checkboxRangeElem = bodyWrapperElem.querySelector('.vxe-table--checkbox-range'); const trElem = cell.parentNode; const selectRecords = this.getCheckboxRecords(); let lastRangeRows = []; const marginSize = 1; const offsetRest = getTargetOffset(evnt.target, bodyWrapperElem); const startTop = offsetRest.offsetTop + evnt.offsetY; const startLeft = offsetRest.offsetLeft + evnt.offsetX; const startScrollTop = bodyWrapperElem.scrollTop; const rowHeight = trElem.offsetHeight; const trRect = trElem.getBoundingClientRect(); const offsetClientTop = disY - trRect.y; let mouseScrollTimeout = null; let isMouseScrollDown = false; let mouseScrollSpaceSize = 1; const triggerEvent = (type, evnt) => { this.emitEvent(`checkbox-range-${type}`, { records: () => this.getCheckboxRecords(), reserves: () => this.getCheckboxReserveRecords() }, evnt); }; const handleChecked = evnt => { const { clientX, clientY } = evnt; const offsetLeft = clientX - disX; const offsetTop = clientY - disY + (bodyWrapperElem.scrollTop - startScrollTop); let rangeHeight = Math.abs(offsetTop); let rangeWidth = Math.abs(offsetLeft); let rangeTop = startTop; let rangeLeft = startLeft; if (offsetTop < marginSize) { // 向上 rangeTop += offsetTop; if (rangeTop < marginSize) { rangeTop = marginSize; rangeHeight = startTop; } } else { // 向下 rangeHeight = Math.min(rangeHeight, bodyWrapperElem.scrollHeight - startTop - marginSize); } if (offsetLeft < marginSize) { // 向左 rangeLeft += offsetLeft; if (rangeWidth > startLeft) { rangeLeft = marginSize; rangeWidth = startLeft; } } else { // 向右 rangeWidth = Math.min(rangeWidth, bodyWrapperElem.clientWidth - startLeft - marginSize); } checkboxRangeElem.style.height = `${rangeHeight}px`; checkboxRangeElem.style.width = `${rangeWidth}px`; checkboxRangeElem.style.left = `${rangeLeft}px`; checkboxRangeElem.style.top = `${rangeTop}px`; checkboxRangeElem.style.display = 'block'; const rangeRows = getCheckboxRangeRows(this, evnt, params, trElem, trRect, offsetClientTop, offsetTop < marginSize ? -rangeHeight : rangeHeight); // 至少滑动 10px 才能有效匹配 if (rangeHeight > 10 && rangeRows.length !== lastRangeRows.length) { const isControlKey = (0, _dom.hasControlKey)(evnt); lastRangeRows = rangeRows; if (isControlKey) { rangeRows.forEach(row => { $xeTable.handleBatchSelectRows([row], selectRecords.indexOf(row) === -1); }); } else { this.setAllCheckboxRow(false); this.handleCheckedCheckboxRow(rangeRows, true, false); } triggerEvent('change', evnt); } }; // 停止鼠标滚动 const stopMouseScroll = () => { clearTimeout(mouseScrollTimeout); mouseScrollTimeout = null; }; // 开始鼠标滚动 const startMouseScroll = evnt => { stopMouseScroll(); mouseScrollTimeout = setTimeout(() => { if (mouseScrollTimeout) { const { scrollLeft, scrollTop, clientHeight, scrollHeight } = bodyWrapperElem; const topSize = Math.ceil(mouseScrollSpaceSize * 50 / rowHeight); if (isMouseScrollDown) { if (scrollTop + clientHeight < scrollHeight) { this.scrollTo(scrollLeft, scrollTop + topSize); startMouseScroll(evnt); handleChecked(evnt); } else { stopMouseScroll(); } } else { if (scrollTop) { this.scrollTo(scrollLeft, scrollTop - topSize); startMouseScroll(evnt); handleChecked(evnt); } else { stopMouseScroll(); } } } }, 50); }; (0, _dom.addClass)(el, 'drag--range'); document.onmousemove = evnt => { evnt.preventDefault(); evnt.stopPropagation(); const { clientY } = evnt; const { boundingTop } = (0, _dom.getAbsolutePos)(bodyWrapperElem); // 如果超过可视区,触发滚动 if (clientY < boundingTop) { isMouseScrollDown = false; mouseScrollSpaceSize = boundingTop - clientY; if (!mouseScrollTimeout) { startMouseScroll(evnt); } } else if (clientY > boundingTop + bodyWrapperElem.clientHeight) { isMouseScrollDown = true; mouseScrollSpaceSize = clientY - boundingTop - bodyWrapperElem.clientHeight; if (!mouseScrollTimeout) { startMouseScroll(evnt); } } else if (mouseScrollTimeout) { stopMouseScroll(); } handleChecked(evnt); }; document.onmouseup = evnt => { stopMouseScroll(); (0, _dom.removeClass)(el, 'drag--range'); checkboxRangeElem.removeAttribute('style'); document.onmousemove = null; document.onmouseup = null; triggerEvent('end', evnt); }; triggerEvent('start', evnt); } } } };