UNPKG

@cairn214/fluent-editor

Version:

A rich text editor based on Quill 2.0, which extends rich modules and formats on the basis of Quill. It's powerful and out-of-the-box.

401 lines (400 loc) 16.1 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const Quill = require("quill"); const tableConfig = require("../table-config.cjs.js"); const index = require("../utils/index.cjs.js"); class TableColumnTool { constructor(table, quill, dom) { if (!table) { return null; } this.table = table; this.quill = quill; this.modulesContainer = dom; this.domNode = null; this.oldRootScrollTop = this.quill.root.scrollTop; this.initColTool(); if (this.quill.root === this.quill.scrollingContainer) { this.quill.root.addEventListener("scroll", this.handleQuillRootScroll.bind(this)); } } handleQuillRootScroll() { if (this.domNode) { this.domNode.style.marginTop = `${this.oldRootScrollTop - this.quill.root.scrollTop}px`; } } initColTool() { const parent = this.quill.root.parentNode; const containerRect = parent.getBoundingClientRect(); const tableViewRect = this.table.parentNode.getBoundingClientRect(); this.domNode = document.createElement("div"); this.domNode.classList.add("qlbt-table-control-panel"); this.columnCtrlPanel = document.createElement("div"); this.columnCtrlPanel.classList.add("qlbt-column-control-panel"); this.domNode.appendChild(this.columnCtrlPanel); this.leftMask = document.createElement("div"); this.leftMask.classList.add("qlbt-left-mask"); index.css(this.leftMask, { height: `${tableViewRect.height + 50}px` }); this.domNode.appendChild(this.leftMask); this.rowCtrlPanel = document.createElement("div"); this.rowCtrlPanel.classList.add("qlbt-row-control-panel"); this.domNode.appendChild(this.rowCtrlPanel); this.updateRowToolCells(); this.updateColToolCells(); this.modulesContainer.appendChild(this.domNode); index.css(this.domNode, { width: "100%", height: `${tableConfig.COL_TOOL_HEIGHT}px`, left: "0px", top: `${tableViewRect.top - containerRect.top + parent.scrollTop - 25}px` }); } createToolCell(isRow) { window.quillIsIntable = true; const toolCell = document.createElement("div"); const selector = document.createElement("div"); const resizeHolder = document.createElement("div"); if (isRow) { toolCell.classList.add("qlbt-row-tool-cell"); selector.classList.add("qlbt-row-tool-cell-selector"); resizeHolder.classList.add("qlbt-row-tool-cell-holder"); index.css(toolCell, { width: `${tableConfig.ROW_TOOL_WIDTH}px` }); } else { toolCell.classList.add("qlbt-col-tool-cell"); selector.classList.add("qlbt-col-tool-cell-selector"); resizeHolder.classList.add("qlbt-col-tool-cell-holder"); index.css(toolCell, { height: `${tableConfig.COL_TOOL_HEIGHT}px` }); } toolCell.appendChild(selector); toolCell.appendChild(resizeHolder); return toolCell; } updateColToolCells() { const tableContainer = Quill.find(this.table); if (!tableContainer) { return; } const tableCols = tableContainer.colGroup().children; const tableColsNum = Math.max(Array.from(tableCols).length, tableContainer.colGroup().domNode.children.length); const existCells = Array.from(this.columnCtrlPanel.querySelectorAll(".qlbt-col-tool-cell")); const cellsNumber = Math.max(existCells.length, tableColsNum); for (let index$1 = 0; index$1 < cellsNumber; index$1++) { let col = tableCols.at(index$1); let colWidth = 0; if (!col || col.domNode !== tableContainer.colGroup().domNode.children[index$1]) { col = tableContainer.colGroup().domNode.children[index$1]; colWidth = col ? col.width : tableContainer.colGroup().domNode.children[index$1 - 1].width; } else { colWidth = Number.parseInt(col.formats()[col.statics.blotName].width, 10); } let colToolCell = null; if (!existCells[index$1]) { colToolCell = this.createToolCell(false); this.columnCtrlPanel.appendChild(colToolCell); this.addColCellSelectHandler(colToolCell); this.addColCellHolderHandler(colToolCell); index.css(colToolCell, { "min-width": `${colWidth}px` }); } else if (existCells[index$1] && index$1 >= tableColsNum) { existCells[index$1].remove(); } else { colToolCell = existCells[index$1]; index.css(colToolCell, { "min-width": `${colWidth}px` }); } } } updateRowToolCells() { const tableContainer = Quill.find(this.table); if (!tableContainer) { return; } let tableRows = Array.from(tableContainer.domNode.querySelectorAll("tr")); tableRows = tableRows.filter((tr) => tr.children.length); const existCells = Array.from(this.rowCtrlPanel.querySelectorAll(".qlbt-row-tool-cell")); const rowNumber = Math.max(existCells.length, tableRows.length); for (let index$1 = 0; index$1 < rowNumber; index$1++) { const row = tableRows[index$1]; let computedHeight = row && getComputedStyle(row).height; if (computedHeight === "auto") { computedHeight = row.querySelector("td").style.height || "30px"; } let rowHeight = row && Number.parseFloat(computedHeight); if (rowHeight < tableConfig.CELL_MIN_HEIGHT) { const rowChildHeight = row && row.childNodes[0] && Number.parseFloat(getComputedStyle(row.childNodes[0]).height); rowHeight = rowChildHeight; } let rowToolCell = null; if (!existCells[index$1]) { rowToolCell = this.createToolCell(true); this.rowCtrlPanel.appendChild(rowToolCell); this.addRowCellSelectHandler(rowToolCell); this.addRowCellHolderHandler(rowToolCell); index.css(rowToolCell, { height: `${rowHeight}px` }); } else if (existCells[index$1] && index$1 >= tableRows.length) { existCells[index$1].remove(); } else { rowToolCell = existCells[index$1]; index.css(rowToolCell, { height: `${rowHeight}px` }); } } } destroy() { window.quillIsIntable = false; this.domNode.remove(); return null; } addRowCellSelectHandler(cell) { const selector = cell.querySelector(".qlbt-row-tool-cell-selector"); const handleClick = (e) => { e.preventDefault(); const dom = e.target.parentNode; const domRect = dom.getBoundingClientRect(); const containerRect = this.quill.root.parentNode.getBoundingClientRect(); const tableRect = this.table.getBoundingClientRect(); const tableSelection = this.quill.getModule("better-table").tableSelection; tableSelection.boundary = { x: tableRect.left - containerRect.left, // 表格左上角X轴坐标 x1: tableRect.left - containerRect.left + tableRect.width - 2, // 表格右上角X轴坐标 y: domRect.top - containerRect.top, // 表格左上角Y轴坐标 y1: domRect.top - containerRect.top + domRect.height - 1, // 表格右上角Y轴坐标 width: tableRect.width - 2, height: domRect.height - 1 }; tableSelection.selectedTds = tableSelection.computeSelectedTds(); tableSelection.repositionHelpLines(); dom.classList.add("qlbt-tool-cell-on"); this.activeToolCell = dom; }; selector.addEventListener("click", handleClick, false); } addRowCellHolderHandler(cell) { const holder = cell.querySelector(".qlbt-row-tool-cell-holder"); let dragging = false; let y0 = 0; let y = 0; let delta = 0; let height0 = 0; let tableRect = {}; let cellRect = {}; let helpLine = null; const handleDrag = (e) => { e.preventDefault(); if (dragging) { y = e.clientY; if (height0 + y - y0 >= tableConfig.CELL_MIN_HEIGHT) { delta = y - y0; } else { delta = tableConfig.CELL_MIN_HEIGHT - height0; } index.css(helpLine, { top: `${cellRect.top + cellRect.height + delta}px` }); } }; const handleMouseup = (e) => { e.preventDefault(); const existCells = Array.from(this.domNode.querySelectorAll(".qlbt-row-tool-cell")); const rowIndex = existCells.indexOf(cell); const rows = Array.from(this.table.querySelectorAll("tr")); const tds = Array.from(rows[rowIndex].childNodes); const hasContentTd = tds.find((td) => td.getAttribute("rowspan") === "1" && td.textContent !== "\n"); if (dragging) { let tdHeight = `${height0 + delta}px`; if (hasContentTd) { tds.forEach((td) => td.getAttribute("rowspan") === "1" && index.css(td, { height: tdHeight })); const currentHeight = getComputedStyle(hasContentTd).height; tdHeight = Number.parseInt(currentHeight, 10) > height0 + delta && currentHeight || tdHeight; } index.css(cell, { height: tdHeight }); tds.forEach((td) => td.getAttribute("rowspan") === "1" && index.css(td, { height: tdHeight })); const tableViewRect = this.table.parentNode.getBoundingClientRect(); index.css(this.leftMask, { height: `${tableViewRect.height + 50}px` }); y0 = 0; y = 0; delta = 0; height0 = 0; dragging = false; holder.classList.remove("dragging"); } this.quill.root.parentNode.removeEventListener("mousemove", handleDrag, false); document.removeEventListener("mouseup", handleMouseup, false); tableRect = {}; cellRect = {}; helpLine.remove(); helpLine = null; const betterTableModule = this.quill.getModule("better-table"); const tableScrollBar = betterTableModule.tableScrollBar; tableScrollBar.resetTableHeight(this.table); const tableSelection = betterTableModule.tableSelection; if (tableSelection && tableSelection.selectedTds.length) { tableSelection.refreshHelpLinesPosition(); } }; const handleMousedown = (e) => { e.preventDefault(); this.quill.root.parentNode.addEventListener("mousemove", handleDrag, false); document.addEventListener("mouseup", handleMouseup, false); tableRect = this.table.getBoundingClientRect(); const tableViewRect = this.table.parentNode.getBoundingClientRect(); const width = tableRect.width > tableViewRect.width && tableViewRect.width || tableRect.width; cellRect = cell.getBoundingClientRect(); helpLine = document.createElement("div"); index.css(helpLine, { position: "fixed", top: `${cellRect.top + cellRect.height}px`, left: `${cellRect.left}px`, zIndex: "100", width: `${width + tableConfig.ROW_TOOL_WIDTH + 9}px`, height: "1px", backgroundColor: tableConfig.PRIMARY_COLOR }); this.quill.root.parentNode.appendChild(helpLine); dragging = true; y0 = e.clientY; height0 = cellRect.height; holder.classList.add("dragging"); }; holder.addEventListener("mousedown", handleMousedown, false); } addColCellSelectHandler(cell) { const selector = cell.querySelector(".qlbt-col-tool-cell-selector"); const handleClick = (e) => { e.preventDefault(); const dom = e.target.parentNode; const domRect = dom.getBoundingClientRect(); const containerRect = this.quill.root.parentNode.getBoundingClientRect(); const tableRect = this.table.getBoundingClientRect(); const tableSelection = this.quill.getModule("better-table").tableSelection; tableSelection.boundary = { x: domRect.left - containerRect.left - 1, x1: domRect.left - containerRect.left + domRect.width - 2, y: tableRect.top - containerRect.top, y1: tableRect.top - containerRect.top + tableRect.height - 2, width: domRect.width, height: tableRect.height - 2 }; tableSelection.selectedTds = tableSelection.computeSelectedTds(); tableSelection.repositionHelpLines(); dom.classList.add("qlbt-tool-cell-on"); this.activeToolCell = dom; }; selector.addEventListener("click", handleClick, false); } addColCellHolderHandler(cell) { const tableContainer = Quill.find(this.table); const holder = cell.querySelector(".qlbt-col-tool-cell-holder"); let dragging = false; let x0 = 0; let x = 0; let delta = 0; let width0 = 0; let tableRect = {}; let scrollContainerRect = null; let cellRect = {}; let helpLine = null; const handleDrag = (e) => { e.preventDefault(); if (dragging) { x = e.clientX; if (width0 + x - x0 >= tableConfig.CELL_MIN_WIDTH) { delta = x - x0; } else { delta = tableConfig.CELL_MIN_WIDTH - width0; } let left = cellRect.left + cellRect.width - 1 + delta; if (scrollContainerRect) { left -= scrollContainerRect.left; } index.css(helpLine, { left: `${left}px` }); } }; const handleMouseup = (e) => { e.preventDefault(); const existCells = Array.from(this.domNode.querySelectorAll(".qlbt-col-tool-cell")); const colIndex = existCells.indexOf(cell); let colBlot = tableContainer.colGroup().children.at(colIndex); if (!colBlot || colBlot.domNode !== tableContainer.colGroup().domNode.children[colIndex]) { colBlot = tableContainer.colGroup().domNode.children[colIndex]; } if (dragging) { const colWidth = Number.parseInt(width0 + delta, 10); if (colBlot.format) { colBlot.format("width", colWidth); } else { colBlot.width = colWidth; } index.css(cell, { "min-width": `${colWidth}px` }); x0 = 0; x = 0; delta = 0; width0 = 0; dragging = false; holder.classList.remove("dragging"); } this.quill.root.parentNode.removeEventListener("mousemove", handleDrag, false); document.removeEventListener("mouseup", handleMouseup, false); tableRect = {}; scrollContainerRect = null; cellRect = {}; helpLine.remove(); helpLine = null; tableContainer.updateTableWidth(); setTimeout(() => { this.updateRowToolCells(); const betterTableModule = this.quill.getModule("better-table"); const tableScrollBar = betterTableModule.tableScrollBar; tableScrollBar.updateScrollBar(); const tableSelection = betterTableModule.tableSelection; if (tableSelection && tableSelection.selectedTds.length) { tableSelection.refreshHelpLinesPosition(); } }); }; const handleMousedown = (e) => { e.preventDefault(); this.quill.root.parentNode.addEventListener("mousemove", handleDrag, false); document.addEventListener("mouseup", handleMouseup, false); tableRect = this.table.getBoundingClientRect(); cellRect = cell.getBoundingClientRect(); let positionValue = "fixed"; let top = cellRect.top; let left = cellRect.left + cellRect.width - 1; if (this.quill.root === this.quill.scrollingContainer) { positionValue = "absolute"; scrollContainerRect = this.quill.root.getBoundingClientRect(); top -= scrollContainerRect.top; left -= scrollContainerRect.left; } helpLine = document.createElement("div"); index.css(helpLine, { position: positionValue, top: `${top}px`, left: `${left}px`, zIndex: "100", height: `${tableRect.height + tableConfig.COL_TOOL_HEIGHT + 8}px`, width: "1px", backgroundColor: tableConfig.PRIMARY_COLOR }); this.quill.root.parentNode.appendChild(helpLine); dragging = true; x0 = e.clientX; width0 = cellRect.width; holder.classList.add("dragging"); }; holder.addEventListener("mousedown", handleMousedown, false); } colToolCells() { return Array.from(this.domNode.querySelectorAll(".qlbt-col-tool-cell")); } } exports.default = TableColumnTool; //# sourceMappingURL=table-column-tool.cjs.js.map