From ed31305d1d291010c3d4b6b223b924823b7be95e Mon Sep 17 00:00:00 2001 From: Vanessa Date: Fri, 13 Oct 2023 11:08:56 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/9421 --- app/src/menus/protyle.ts | 2 +- app/src/protyle/render/av/action.ts | 58 ++++-------------- app/src/protyle/render/av/col.ts | 29 --------- app/src/protyle/render/av/row.ts | 74 +++++++++++++++++++++++ app/src/protyle/util/editorCommonEvent.ts | 2 +- app/src/protyle/wysiwyg/index.ts | 8 ++- 6 files changed, 92 insertions(+), 81 deletions(-) create mode 100644 app/src/protyle/render/av/row.ts diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index 7fd31b318..9be589032 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -45,7 +45,7 @@ import {hideElements} from "../protyle/ui/hideElements"; import {emitOpenMenu} from "../plugin/EventBus"; import {openMobileFileById} from "../mobile/editor"; import {openBacklink, openGraph} from "../layout/dock/util"; -import {updateHeader} from "../protyle/render/av/col"; +import {updateHeader} from "../protyle/render/av/row"; export const fileAnnotationRefMenu = (protyle: IProtyle, refElement: HTMLElement) => { const nodeElement = hasClosestBlock(refElement); diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index 990f59c91..76e4d91b0 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -4,7 +4,8 @@ import {transaction} from "../../wysiwyg/transaction"; import {openEditorTab} from "../../../menus/util"; import {copySubMenu} from "../../../menus/commonMenuItem"; import {openCalcMenu, popTextCell} from "./cell"; -import {getColIconByType, showColMenu, updateHeader} from "./col"; +import {getColIconByType, showColMenu} from "./col"; +import {insertAttrViewBlockAnimation, updateHeader} from "./row"; import {emitOpenMenu} from "../../../plugin/EventBus"; import {addCol} from "./addCol"; import {openMenuPanel} from "./openMenuPanel"; @@ -18,6 +19,7 @@ import {Constants} from "../../../constants"; import {openAsset} from "../../../editor/util"; import {getSearch, isMobile} from "../../../util/functions"; import {unicode2Emoji} from "../../../emoji"; +import {selectRow} from "./row"; export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLElement }) => { const blockElement = hasClosestBlock(event.target); @@ -61,30 +63,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle const checkElement = hasClosestByClassName(event.target, "av__firstcol"); if (checkElement) { window.siyuan.menus.menu.remove(); - const rowElement = checkElement.parentElement; - const useElement = checkElement.querySelector("use"); - if (rowElement.classList.contains("av__row--header")) { - if ("#iconCheck" === useElement.getAttribute("xlink:href")) { - rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => { - item.querySelector("use").setAttribute("xlink:href", "#iconUncheck"); - item.parentElement.classList.remove("av__row--select"); - }); - } else { - rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => { - item.querySelector("use").setAttribute("xlink:href", "#iconCheck"); - item.parentElement.classList.add("av__row--select"); - }); - } - } else { - if (useElement.getAttribute("xlink:href") === "#iconUncheck") { - checkElement.parentElement.classList.add("av__row--select"); - useElement.setAttribute("xlink:href", "#iconCheck"); - } else { - checkElement.parentElement.classList.remove("av__row--select"); - useElement.setAttribute("xlink:href", "#iconUncheck"); - } - } - updateHeader(rowElement); + selectRow(checkElement, "toggle"); event.preventDefault(); event.stopPropagation(); return true; @@ -176,11 +155,13 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle const cellElement = hasClosestByClassName(event.target, "av__cell"); if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) { - cellElement.parentElement.parentElement.querySelectorAll(".av__row--select").forEach(item => { - item.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck"); - item.classList.remove("av__row--select"); - }); - popTextCell(protyle, [cellElement]); + const type = cellElement.parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol; + if (type === "updated" || type === "created") { + selectRow(cellElement.parentElement.querySelector(".av__firstcol"), "toggle"); + } else { + selectRow(cellElement.parentElement.querySelector(".av__firstcol"), "unselect"); + popTextCell(protyle, [cellElement]); + } event.preventDefault(); event.stopPropagation(); return true; @@ -367,20 +348,3 @@ export const removeAttrViewColAnimation = (blockElement: Element, id: string) => item.remove(); }); }; - -export const insertAttrViewBlockAnimation = (blockElement: Element, size: number, previousId: string, avId?: string) => { - const previousElement = blockElement.querySelector(`.av__row[data-id="${previousId}"]`) || blockElement.querySelector(".av__row--header"); - let colHTML = ""; - previousElement.querySelectorAll(".av__cell").forEach((item: HTMLElement) => { - colHTML += `
`; - }); - - let html = ""; - new Array(size).fill(1).forEach(() => { - html += `
-
- ${colHTML} -
`; - }); - previousElement.insertAdjacentHTML("afterend", html); -}; diff --git a/app/src/protyle/render/av/col.ts b/app/src/protyle/render/av/col.ts index fa91446c8..3f0124468 100644 --- a/app/src/protyle/render/av/col.ts +++ b/app/src/protyle/render/av/col.ts @@ -306,35 +306,6 @@ export const getColIconByType = (type: TAVCol) => { } }; -export const updateHeader = (rowElement: HTMLElement) => { - const blockElement = hasClosestBlock(rowElement); - if (!blockElement) { - return; - } - const selectCount = rowElement.parentElement.querySelectorAll(".av__row--select:not(.av__row--header)").length; - const diffCount = rowElement.parentElement.childElementCount - 3 - selectCount; - const headElement = rowElement.parentElement.firstElementChild; - const headUseElement = headElement.querySelector("use"); - const counterElement = blockElement.querySelector(".av__counter"); - const avHeadElement = blockElement.querySelector(".av__header") as HTMLElement; - if (diffCount === 0 && rowElement.parentElement.childElementCount - 3 !== 0) { - headElement.classList.add("av__row--select"); - headUseElement.setAttribute("xlink:href", "#iconCheck"); - } else if (diffCount === rowElement.parentElement.childElementCount - 3) { - headElement.classList.remove("av__row--select"); - headUseElement.setAttribute("xlink:href", "#iconUncheck"); - counterElement.classList.add("fn__none"); - avHeadElement.style.position = ""; - return; - } else if (diffCount > 0) { - headElement.classList.add("av__row--select"); - headUseElement.setAttribute("xlink:href", "#iconIndeterminateCheck"); - } - counterElement.classList.remove("fn__none"); - counterElement.innerHTML = `${selectCount} selected`; - avHeadElement.style.position = "sticky"; -}; - export const addAttrViewColAnimation = (options: { blockElement: Element, protyle: IProtyle, diff --git a/app/src/protyle/render/av/row.ts b/app/src/protyle/render/av/row.ts new file mode 100644 index 000000000..6a16597c1 --- /dev/null +++ b/app/src/protyle/render/av/row.ts @@ -0,0 +1,74 @@ +import {hasClosestBlock} from "../../util/hasClosest"; + +export const selectRow = (checkElement: Element, type: "toggle" | "select" | "unselect") => { + const rowElement = checkElement.parentElement; + const useElement = checkElement.querySelector("use"); + if (rowElement.classList.contains("av__row--header")) { + if ("#iconCheck" === useElement.getAttribute("xlink:href")) { + rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => { + item.querySelector("use").setAttribute("xlink:href", "#iconUncheck"); + item.parentElement.classList.remove("av__row--select"); + }); + } else { + rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => { + item.querySelector("use").setAttribute("xlink:href", "#iconCheck"); + item.parentElement.classList.add("av__row--select"); + }); + } + } else { + if (type === "select" || (useElement.getAttribute("xlink:href") === "#iconUncheck" && type === "toggle")) { + checkElement.parentElement.classList.add("av__row--select"); + useElement.setAttribute("xlink:href", "#iconCheck"); + } else if (type === "unselect" || (useElement.getAttribute("xlink:href") === "#iconCheck" && type === "toggle")) { + checkElement.parentElement.classList.remove("av__row--select"); + useElement.setAttribute("xlink:href", "#iconUncheck"); + } + } + updateHeader(rowElement); +} + +export const updateHeader = (rowElement: HTMLElement) => { + const blockElement = hasClosestBlock(rowElement); + if (!blockElement) { + return; + } + const selectCount = rowElement.parentElement.querySelectorAll(".av__row--select:not(.av__row--header)").length; + const diffCount = rowElement.parentElement.childElementCount - 3 - selectCount; + const headElement = rowElement.parentElement.firstElementChild; + const headUseElement = headElement.querySelector("use"); + const counterElement = blockElement.querySelector(".av__counter"); + const avHeadElement = blockElement.querySelector(".av__header") as HTMLElement; + if (diffCount === 0 && rowElement.parentElement.childElementCount - 3 !== 0) { + headElement.classList.add("av__row--select"); + headUseElement.setAttribute("xlink:href", "#iconCheck"); + } else if (diffCount === rowElement.parentElement.childElementCount - 3) { + headElement.classList.remove("av__row--select"); + headUseElement.setAttribute("xlink:href", "#iconUncheck"); + counterElement.classList.add("fn__none"); + avHeadElement.style.position = ""; + return; + } else if (diffCount > 0) { + headElement.classList.add("av__row--select"); + headUseElement.setAttribute("xlink:href", "#iconIndeterminateCheck"); + } + counterElement.classList.remove("fn__none"); + counterElement.innerHTML = `${selectCount} selected`; + avHeadElement.style.position = "sticky"; +}; + +export const insertAttrViewBlockAnimation = (blockElement: Element, size: number, previousId: string, avId?: string) => { + const previousElement = blockElement.querySelector(`.av__row[data-id="${previousId}"]`) || blockElement.querySelector(".av__row--header"); + let colHTML = ""; + previousElement.querySelectorAll(".av__cell").forEach((item: HTMLElement) => { + colHTML += `
`; + }); + + let html = ""; + new Array(size).fill(1).forEach(() => { + html += `
+
+ ${colHTML} +
`; + }); + previousElement.insertAdjacentHTML("afterend", html); +}; diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index aebb5a4cb..049186273 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -19,7 +19,7 @@ import {uploadLocalFiles} from "../upload"; import {insertHTML} from "./insertHTML"; import {isBrowser} from "../../util/functions"; import {hideElements} from "../ui/hideElements"; -import {insertAttrViewBlockAnimation} from "../render/av/action"; +import {insertAttrViewBlockAnimation} from "../render/av/row"; const moveToNew = (protyle: IProtyle, sourceElements: Element[], targetElement: Element, newSourceElement: Element, isSameDoc: boolean, isBottom: boolean, isCopy: boolean) => { diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 1ab5979ae..6d25e1015 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -76,7 +76,7 @@ import {removeSearchMark} from "../toolbar/util"; import {activeBlur, hideKeyboardToolbar} from "../../mobile/util/keyboardToolbar"; import {commonClick} from "./commonClick"; import {avClick, avContextmenu, updateAVName} from "../render/av/action"; -import {updateHeader} from "../render/av/col"; +import {updateHeader} from "../render/av/row"; export class WYSIWYG { public lastHTMLs: { [key: string]: string } = {}; @@ -187,10 +187,12 @@ export class WYSIWYG { private setEmptyOutline(protyle: IProtyle, element: HTMLElement) { // 图片移除选择状态应放在前面,否则 https://github.com/siyuan-note/siyuan/issues/4173 protyle.wysiwyg.element.querySelectorAll(".img--select, .av__cell--select, .av__row--select").forEach((item: HTMLElement) => { - if (item.classList.contains("av__row--select")) { + if (item.classList.contains("av__row--select") && !hasClosestByClassName(element, "av")) { updateHeader(item); + item.classList.remove("av__row--select"); + } - item.classList.remove("img--select", "av__cell--select", "av__row--select"); + item.classList.remove("img--select", "av__cell--select"); }); let nodeElement = element;