diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index 7b3233d97..fe81fb14b 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -2400,18 +2400,46 @@ export const tableMenu = (protyle: IProtyle, nodeElement: Element, cellElement: ${window.siyuan.languages.insertRowBefore.replace("${x}", ``)} `, accelerator: window.siyuan.config.keymap.editor.table.insertRowAbove.custom, - click: (element: HTMLElement) => { - insertRowAbove(protyle, range, cellElement, nodeElement, parseInt(element.querySelector("input").value)); + bind(element: HTMLElement) { + const inputElement = element.querySelector("input"); + element.addEventListener("click", () => { + if (document.activeElement === inputElement) { + return; + } + insertRowAbove(protyle, range, cellElement, nodeElement); + window.siyuan.menus.menu.remove(); + }); + inputElement.addEventListener("keydown", (event: KeyboardEvent) => { + if (!event.isComposing && event.key === "Enter") { + insertRowAbove(protyle, range, cellElement, nodeElement, parseInt(element.querySelector("input").value)); + window.siyuan.menus.menu.remove(); + } + }); } }); if (!nextHasNone || (nextHasNone && !nextHasRowSpan && nextHasColSpan)) { insertMenus.push({ id: "insertRowBelow", icon: "iconAfter", - label: window.siyuan.languages.insertRowBelow, + label: `
+${window.siyuan.languages.insertRowAfter.replace("${x}", ``)} +
`, accelerator: window.siyuan.config.keymap.editor.table.insertRowBelow.custom, - click: () => { - insertRow(protyle, range, cellElement, nodeElement); + bind(element: HTMLElement) { + const inputElement = element.querySelector("input"); + element.addEventListener("click", () => { + if (document.activeElement === inputElement) { + return; + } + insertRow(protyle, range, cellElement, nodeElement); + window.siyuan.menus.menu.remove(); + }); + inputElement.addEventListener("keydown", (event: KeyboardEvent) => { + if (!event.isComposing && event.key === "Enter") { + insertRow(protyle, range, cellElement, nodeElement, parseInt(element.querySelector("input").value)); + window.siyuan.menus.menu.remove(); + } + }); } }); } @@ -2419,10 +2447,25 @@ ${window.siyuan.languages.insertRowBefore.replace("${x}", ` +${window.siyuan.languages.insertColumnLeft1.replace("${x}", ``)} +`, accelerator: window.siyuan.config.keymap.editor.table.insertColumnLeft.custom, - click: () => { - insertColumn(protyle, nodeElement, cellElement, "beforebegin", range); + bind(element: HTMLElement) { + const inputElement = element.querySelector("input"); + element.addEventListener("click", () => { + if (document.activeElement === inputElement) { + return; + } + insertColumn(protyle, nodeElement, cellElement, "beforebegin", range); + window.siyuan.menus.menu.remove(); + }); + inputElement.addEventListener("keydown", (event: KeyboardEvent) => { + if (!event.isComposing && event.key === "Enter") { + insertColumn(protyle, nodeElement, cellElement, "beforebegin", range, parseInt(element.querySelector("input").value)); + window.siyuan.menus.menu.remove(); + } + }); } }); } @@ -2430,10 +2473,25 @@ ${window.siyuan.languages.insertRowBefore.replace("${x}", ` +${window.siyuan.languages.insertColumnRight1.replace("${x}", ``)} +`, accelerator: window.siyuan.config.keymap.editor.table.insertColumnRight.custom, - click: () => { - insertColumn(protyle, nodeElement, cellElement, "afterend", range); + bind(element: HTMLElement) { + const inputElement = element.querySelector("input"); + element.addEventListener("click", () => { + if (document.activeElement === inputElement) { + return; + } + insertColumn(protyle, nodeElement, cellElement, "afterend", range); + window.siyuan.menus.menu.remove(); + }); + inputElement.addEventListener("keydown", (event: KeyboardEvent) => { + if (!event.isComposing && event.key === "Enter") { + insertColumn(protyle, nodeElement, cellElement, "afterend", range, parseInt(element.querySelector("input").value)); + window.siyuan.menus.menu.remove(); + } + }); } }); } diff --git a/app/src/protyle/util/table.ts b/app/src/protyle/util/table.ts index 4e106b9fa..bdc92cba3 100644 --- a/app/src/protyle/util/table.ts +++ b/app/src/protyle/util/table.ts @@ -90,7 +90,7 @@ export const setTableAlign = (protyle: IProtyle, cellElements: HTMLElement[], no focusByWbr(tableElement, range); }; -export const insertRow = (protyle: IProtyle, range: Range, cellElement: HTMLElement, nodeElement: Element) => { +export const insertRow = (protyle: IProtyle, range: Range, cellElement: HTMLElement, nodeElement: Element, count = 1) => { const wbrElement = document.createElement("wbr"); range.insertNode(wbrElement); const html = nodeElement.outerHTML; @@ -104,14 +104,14 @@ export const insertRow = (protyle: IProtyle, range: Range, cellElement: HTMLElem if (cellElement.tagName === "TH") { const tbodyElement = nodeElement.querySelector("tbody"); if (tbodyElement) { - tbodyElement.insertAdjacentHTML("afterbegin", `${rowHTML}`); + tbodyElement.insertAdjacentHTML("afterbegin", `${rowHTML}`.repeat(count)); newRowElement = tbodyElement.firstElementChild as HTMLTableRowElement; } else { - cellElement.parentElement.parentElement.insertAdjacentHTML("afterend", `${rowHTML}`); + cellElement.parentElement.parentElement.insertAdjacentHTML("afterend", `${`${rowHTML}`.repeat(count)}`); newRowElement = cellElement.parentElement.parentElement.nextElementSibling.firstElementChild as HTMLTableRowElement; } } else { - cellElement.parentElement.insertAdjacentHTML("afterend", `${rowHTML}`); + cellElement.parentElement.insertAdjacentHTML("afterend", `${rowHTML}`.repeat(count)); newRowElement = cellElement.parentElement.nextElementSibling as HTMLTableRowElement; } range.selectNodeContents(newRowElement.cells[getColIndex(cellElement)]); @@ -160,10 +160,10 @@ export const insertRowAbove = (protyle: IProtyle, range: Range, cellElement: HTM if (cellElement.parentElement.parentElement.tagName === "THEAD" && !cellElement.parentElement.previousElementSibling) { cellElement.parentElement.parentElement.insertAdjacentHTML("beforebegin", `${rowHTML}`); newRowElement = nodeElement.querySelector("thead tr"); + cellElement.parentElement.parentElement.nextElementSibling.insertAdjacentHTML("afterbegin", cellElement.parentElement.parentElement.innerHTML.replace(//g, "")); if (count > 1) { cellElement.parentElement.parentElement.nextElementSibling.insertAdjacentHTML("afterbegin", `${rowHTML.replace(//g, "")}`.repeat(count - 1)); } - cellElement.parentElement.parentElement.nextElementSibling.insertAdjacentHTML("afterbegin", cellElement.parentElement.parentElement.innerHTML.replace(//g, "")); cellElement.parentElement.parentElement.remove(); } else { cellElement.parentElement.insertAdjacentHTML("beforebegin", `${rowHTML}`.repeat(count)); @@ -176,7 +176,7 @@ export const insertRowAbove = (protyle: IProtyle, range: Range, cellElement: HTM scrollToView(nodeElement, newRowElement, protyle); }; -export const insertColumn = (protyle: IProtyle, nodeElement: Element, cellElement: HTMLElement, type: InsertPosition, range: Range) => { +export const insertColumn = (protyle: IProtyle, nodeElement: Element, cellElement: HTMLElement, type: InsertPosition, range: Range, count = 1) => { const wbrElement = document.createElement("wbr"); range.insertNode(wbrElement); const html = nodeElement.outerHTML; @@ -185,19 +185,23 @@ export const insertColumn = (protyle: IProtyle, nodeElement: Element, cellElemen const tableElement = nodeElement.querySelector("table"); for (let i = 0; i < tableElement.rows.length; i++) { const colCellElement = tableElement.rows[i].cells[index]; - const newCellElement = document.createElement(colCellElement.tagName); - colCellElement.insertAdjacentElement(type, newCellElement); + const tag = colCellElement.tagName.toLowerCase(); + let html = ""; if (colCellElement === cellElement) { - newCellElement.innerHTML = " "; - // 滚动条横向定位 - if (newCellElement.offsetLeft + newCellElement.clientWidth > nodeElement.firstElementChild.scrollLeft + nodeElement.firstElementChild.clientWidth) { - nodeElement.firstElementChild.scrollLeft = newCellElement.offsetLeft + newCellElement.clientWidth - nodeElement.firstElementChild.clientWidth; - } + html = `<${tag}> ` + `<${tag}> `.repeat(count - 1); } else { - newCellElement.textContent = " "; + html = `<${tag}> `.repeat(count); } + colCellElement.insertAdjacentHTML(type, html); } - tableElement.querySelectorAll("col")[index].insertAdjacentHTML(type, ""); + // 滚动条横向定位 + if (type === "afterend" && cellElement.offsetLeft + cellElement.clientWidth + 60 > + nodeElement.firstElementChild.scrollLeft + nodeElement.firstElementChild.clientWidth) { + nodeElement.firstElementChild.scrollLeft = cellElement.offsetLeft + cellElement.clientWidth + 60 - nodeElement.firstElementChild.clientWidth; + } else if (type === "beforebegin" && cellElement.offsetLeft - 60 * count < nodeElement.firstElementChild.scrollLeft) { + nodeElement.firstElementChild.scrollLeft = cellElement.offsetLeft - 60 * count; + } + tableElement.querySelectorAll("col")[index].insertAdjacentHTML(type, "".repeat(count)); focusByWbr(nodeElement, range); updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, html); };