From 10bce0e608d10b674aa3399adbebf4484c980f67 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 8 May 2025 17:58:26 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/14777 --- app/src/protyle/util/insertHTML.ts | 13 +++-- app/src/protyle/util/table.ts | 25 +++++++-- app/src/protyle/wysiwyg/index.ts | 84 +++++++++++++++++++++--------- 3 files changed, 89 insertions(+), 33 deletions(-) diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index 726b226a4..5af080e0b 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -18,6 +18,7 @@ import {input} from "../wysiwyg/input"; import {objEquals} from "../../util/functions"; import {fetchPost} from "../../util/fetch"; import {mergeAddOption} from "../render/av/select"; +import {isIncludeCell} from "./table"; const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: HTMLElement) => { const tempElement = document.createElement("template"); @@ -253,14 +254,18 @@ const processTable = (range: Range, html: string, protyle: IProtyle, blockElemen return false; } const scrollLeft = blockElement.firstElementChild.scrollLeft; + const scrollTop = blockElement.querySelector("table").scrollTop; const tableSelectElement = blockElement.querySelector(".table__select") as HTMLElement; let index = 0; const matchCellsElement: HTMLTableCellElement[] = []; blockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight && - copyCellElements.length > index) { + if (!item.classList.contains("fn__none") && copyCellElements.length > index && + isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + })) { matchCellsElement.push(item); index++; } diff --git a/app/src/protyle/util/table.ts b/app/src/protyle/util/table.ts index e68342a75..f2d83af3b 100644 --- a/app/src/protyle/util/table.ts +++ b/app/src/protyle/util/table.ts @@ -722,6 +722,21 @@ export const fixTable = (protyle: IProtyle, event: KeyboardEvent, range: Range) } }; +export const isIncludeCell = (options: { + tableSelectElement: HTMLElement, + scrollLeft: number, + scrollTop: number, + item: HTMLTableCellElement, +}) => { + if (options.item.offsetLeft + 6 > options.tableSelectElement.offsetLeft + options.scrollLeft && + options.item.offsetLeft + options.item.clientWidth - 6 < options.tableSelectElement.offsetLeft + options.scrollLeft + options.tableSelectElement.clientWidth && + options.item.offsetTop + 6 > options.tableSelectElement.offsetTop + options.scrollTop && + options.item.offsetTop + options.item.clientHeight - 6 < options.tableSelectElement.offsetTop + options.scrollTop + options.tableSelectElement.clientHeight) { + return true; + } + return false; +}; + export const clearTableCell = (protyle: IProtyle, tableBlockElement: HTMLElement) => { if (!tableBlockElement) { return; @@ -729,10 +744,14 @@ export const clearTableCell = (protyle: IProtyle, tableBlockElement: HTMLElement const tableSelectElement = tableBlockElement.querySelector(".table__select") as HTMLElement; const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight) { + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + })) { selectCellElements.push(item); } }); diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index c8f4499ef..264711e49 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -70,7 +70,7 @@ import {copyPlainText, isInIOS, isMac, isOnlyMeta, readClipboard} from "../util/ import {MenuItem} from "../../menus/Menu"; import {fetchPost} from "../../util/fetch"; import {onGet} from "../util/onGet"; -import {clearTableCell, setTableAlign} from "../util/table"; +import {clearTableCell, isIncludeCell, setTableAlign} from "../util/table"; import {countBlockWord, countSelectWord} from "../../layout/status"; import {showMessage} from "../../dialog/message"; import {getBacklinkHeadingMore, loadBreadcrumb} from "./renderBacklink"; @@ -345,12 +345,16 @@ export class WYSIWYG { } else if (selectTableElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = nodeElement.firstElementChild.scrollLeft; + const scrollTop = nodeElement.querySelector("table").scrollTop; const tableSelectElement = nodeElement.querySelector(".table__select") as HTMLElement; html = ""; nodeElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight) { + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + })) { selectCellElements.push(item); } }); @@ -890,7 +894,7 @@ export class WYSIWYG { } }); protyle.wysiwyg.element.classList.add("protyle-wysiwyg--hiderange"); - tableBlockElement.querySelector(".table__select").setAttribute("style", `left:${left - tableBlockElement.firstElementChild.scrollLeft}px;top:${top}px;height:${height}px;width:${width + 1}px;`); + tableBlockElement.querySelector(".table__select").setAttribute("style", `left:${left - tableBlockElement.firstElementChild.scrollLeft}px;top:${top - tableBlockElement.querySelector('table').scrollTop}px;height:${height}px;width:${width + 1}px;`); moveCellElement = moveTarget; } return; @@ -1118,6 +1122,7 @@ export class WYSIWYG { const colCount = tableBlockElement.querySelectorAll("th").length; let fnNoneMax = 0; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; let isTHead = false; let isTBody = false; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement, index: number) => { @@ -1141,8 +1146,12 @@ export class WYSIWYG { } } } else { - if (item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight) { + if (isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + })) { selectCellElements.push(item); if (!isTHead && item.parentElement.parentElement.tagName === "THEAD") { isTHead = true; @@ -1234,11 +1243,15 @@ export class WYSIWYG { if (tableBlockElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight && - (selectCellElements.length === 0 || (selectCellElements.length > 0 && item.offsetTop === selectCellElements[0].offsetTop))) { + isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + }) && (selectCellElements.length === 0 || (selectCellElements.length > 0 && item.offsetTop === selectCellElements[0].offsetTop))) { selectCellElements.push(item); } }); @@ -1255,10 +1268,14 @@ export class WYSIWYG { if (tableBlockElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight && + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + }) && (selectCellElements.length === 0 || (selectCellElements.length > 0 && item.offsetTop === selectCellElements[0].offsetTop))) { selectCellElements.push(item); } @@ -1276,11 +1293,14 @@ export class WYSIWYG { if (tableBlockElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight && - (selectCellElements.length === 0 || (selectCellElements.length > 0 && item.offsetTop === selectCellElements[0].offsetTop))) { + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + }) && (selectCellElements.length === 0 || (selectCellElements.length > 0 && item.offsetTop === selectCellElements[0].offsetTop))) { selectCellElements.push(item); } }); @@ -1296,10 +1316,14 @@ export class WYSIWYG { if (tableBlockElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight && + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + }) && (selectCellElements.length === 0 || (selectCellElements.length > 0 && item.offsetTop === selectCellElements[0].offsetTop))) { selectCellElements.push(item); } @@ -1318,11 +1342,15 @@ export class WYSIWYG { if (tableBlockElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = tableBlockElement.firstElementChild.scrollLeft; + const scrollTop = tableBlockElement.querySelector("table").scrollTop; const tableSelectElement = tableBlockElement.querySelector(".table__select") as HTMLElement; tableBlockElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight) { + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + })) { selectCellElements.push(item); } }); @@ -1547,12 +1575,16 @@ export class WYSIWYG { } else if (selectTableElement) { const selectCellElements: HTMLTableCellElement[] = []; const scrollLeft = nodeElement.firstElementChild.scrollLeft; + const scrollTop = nodeElement.querySelector("table").scrollTop; const tableSelectElement = nodeElement.querySelector(".table__select") as HTMLElement; html = "
"; nodeElement.querySelectorAll("th, td").forEach((item: HTMLTableCellElement) => { - if (!item.classList.contains("fn__none") && - item.offsetLeft + 6 > tableSelectElement.offsetLeft + scrollLeft && item.offsetLeft + item.clientWidth - 6 < tableSelectElement.offsetLeft + scrollLeft + tableSelectElement.clientWidth && - item.offsetTop + 6 > tableSelectElement.offsetTop && item.offsetTop + item.clientHeight - 6 < tableSelectElement.offsetTop + tableSelectElement.clientHeight) { + if (!item.classList.contains("fn__none") && isIncludeCell({ + tableSelectElement, + scrollLeft, + scrollTop, + item, + })) { selectCellElements.push(item); } });