From 1544786bb644d9edaf8fc158b409ac2105347e2a Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 14 Jan 2024 18:02:14 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/9867 --- app/src/assets/scss/business/_av.scss | 10 ++-- app/src/protyle/render/av/cell.ts | 3 + app/src/protyle/render/av/keydown.ts | 4 ++ app/src/protyle/render/av/row.ts | 2 +- app/src/protyle/wysiwyg/index.ts | 85 ++++++++++++++++++++++++++- 5 files changed, 96 insertions(+), 8 deletions(-) diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index eaea3ef45..99a3abd5d 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -106,7 +106,7 @@ &--hl { &:not(.av__row--header) .av__cell, &:not(.av__row--header) .av__firstcol { - background-color: var(--b3-av-background-hl); + background-color: var(--b3-av-background-hl) !important; } .av__firstcol svg { @@ -242,7 +242,7 @@ } &--select { - background-color: var(--b3-theme-primary-lightest); + background-color: var(--b3-menu-background); box-shadow: 2px 2px 0 var(--b3-theme-primary-lighter) inset, -2px -2px 0px var(--b3-theme-primary-lighter) inset; border-radius: var(--b3-border-radius); } @@ -358,7 +358,7 @@ display: flex; &.av__firstcol, - & > div { + & > div:not(.av__cell--select):not(.av__cell--active) { background-color: var(--av-background); } } @@ -450,8 +450,10 @@ .av__row--select .av__cell, .av__colsticky.av__firstcol, .av__colsticky > div, + .av__cell--select, + .av__cell--active, .av__counter { - background-color: var(--b3-av-background-hl); + background-color: var(--b3-av-background-hl) !important; } } diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index c39ca85a2..54348707e 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -661,6 +661,9 @@ export const getPositionByCellElement = (cellElement: HTMLElement) => { let celIndex = -2; while (cellElement) { cellElement = cellElement.previousElementSibling as HTMLElement; + if (cellElement && cellElement.classList.contains("av__colsticky")) { + cellElement = cellElement.lastElementChild as HTMLElement; + } celIndex++; } return {rowIndex, celIndex}; diff --git a/app/src/protyle/render/av/keydown.ts b/app/src/protyle/render/av/keydown.ts index 362100415..debd607ac 100644 --- a/app/src/protyle/render/av/keydown.ts +++ b/app/src/protyle/render/av/keydown.ts @@ -23,6 +23,10 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl if (!rowElement) { return false; } + nodeElement.querySelectorAll(".av__cell--active").forEach(item => { + item.classList.remove("av__cell--active"); + item.querySelector(".av__drag-fill")?.remove(); + }) if (event.key === "Escape") { selectCellElement.classList.remove("av__cell--select"); selectRow(rowElement.querySelector(".av__firstcol"), "select"); diff --git a/app/src/protyle/render/av/row.ts b/app/src/protyle/render/av/row.ts index f3d3a786f..89ca8f154 100644 --- a/app/src/protyle/render/av/row.ts +++ b/app/src/protyle/render/av/row.ts @@ -12,7 +12,7 @@ export const selectRow = (checkElement: Element, type: "toggle" | "select" | "un } const useElement = checkElement.querySelector("use"); if (rowElement.classList.contains("av__row--header") || type === "unselectAll") { - if ("#iconCheck" === useElement.getAttribute("xlink:href")) { + if ("#iconCheck" === useElement.getAttribute("xlink:href") || type === "unselectAll") { rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => { item.querySelector("use").setAttribute("xlink:href", "#iconUncheck"); const rowItemElement = hasClosestByClassName(item, "av__row"); diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 8805fd083..96d0a2866 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -76,12 +76,18 @@ 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 {stickyRow, updateHeader} from "../render/av/row"; +import {selectRow, stickyRow, updateHeader} from "../render/av/row"; import {showColMenu} from "../render/av/col"; import {openViewMenu} from "../render/av/view"; import {avRender} from "../render/av/render"; import {checkFold} from "../../util/noRelyPCFunction"; -import {getCellText, getPositionByCellElement, updateCellsValue} from "../render/av/cell"; +import { + genCellValueByElement, + getCellText, + getPositionByCellElement, + getTypeByCellElement, + updateCellsValue +} from "../render/av/cell"; export class WYSIWYG { public lastHTMLs: { [key: string]: string } = {}; @@ -438,6 +444,78 @@ export class WYSIWYG { event.preventDefault(); return; } + // av drag fill + const avDragFillElement = hasClosestByClassName(target, "av__drag-fill"); + if (!protyle.disabled && avDragFillElement) { + const nodeElement = hasClosestBlock(avDragFillElement); + if (!nodeElement) { + return; + } + const originData: { [key: string]: IAVCellValue[] } = {} + let lastOriginCellElement + const lastOriginCellId: string[] = [] + nodeElement.querySelectorAll(".av__cell--active").forEach((item: HTMLElement, index: number) => { + const rowElement = hasClosestByClassName(item, "av__row"); + if (rowElement) { + if (!originData[rowElement.dataset.id]) { + originData[rowElement.dataset.id] = []; + } + originData[rowElement.dataset.id].push(genCellValueByElement(getTypeByCellElement(item), item)); + lastOriginCellElement = item + lastOriginCellId.push(item.dataset.id) + } + }); + const dragFillCellIndex = getPositionByCellElement(lastOriginCellElement); + const firstCellIndex = getPositionByCellElement(nodeElement.querySelector(".av__cell--active")); + let moveCellElement: HTMLElement; + let lastCellElement: HTMLElement; + documentSelf.onmousemove = (moveEvent: MouseEvent) => { + const tempCellElement = hasClosestByClassName(moveEvent.target as HTMLElement, "av__cell") as HTMLElement; + if (moveCellElement && tempCellElement && tempCellElement.isSameNode(moveCellElement)) { + return; + } + moveCellElement = tempCellElement; + if (moveCellElement && moveCellElement.dataset.id) { + const newIndex = getPositionByCellElement(moveCellElement); + nodeElement.querySelectorAll(".av__cell--active").forEach((item: HTMLElement) => { + if (!lastOriginCellId.includes(item.dataset.id)) { + item.classList.remove("av__cell--active"); + } + }); + if (newIndex.celIndex !== dragFillCellIndex.celIndex || dragFillCellIndex.rowIndex >= newIndex.rowIndex) { + lastCellElement = undefined + return; + } + nodeElement.querySelectorAll(".av__row").forEach((rowElement: HTMLElement, index: number) => { + if (index >= dragFillCellIndex.rowIndex && index <= newIndex.rowIndex) { + rowElement.querySelectorAll(".av__cell").forEach((cellElement: HTMLElement, cellIndex: number) => { + if (cellIndex >= firstCellIndex.celIndex && cellIndex <= newIndex.celIndex) { + cellElement.classList.add("av__cell--active"); + lastCellElement = cellElement; + } + }); + } + }); + } + }; + + documentSelf.onmouseup = () => { + documentSelf.onmousemove = null; + documentSelf.onmouseup = null; + documentSelf.ondragstart = null; + documentSelf.onselectstart = null; + documentSelf.onselect = null; + if (lastCellElement) { + nodeElement.querySelector(".av__drag-fill")?.remove(); + selectRow(nodeElement.querySelector(".av__firstcol"), "unselectAll"); + focusBlock(nodeElement); + lastCellElement.insertAdjacentHTML("beforeend", `
`); + this.preventClick = true; + } + return false; + }; + return false; + } // av cell select const avCellElement = hasClosestByClassName(target, "av__cell"); if (!protyle.disabled && avCellElement && avCellElement.dataset.id) { @@ -461,7 +539,7 @@ export class WYSIWYG { return; } moveCellElement = tempCellElement; - if (moveCellElement && moveCellElement.dataset.id && !avCellElement.isSameNode(moveCellElement)) { + if (moveCellElement && moveCellElement.dataset.id) { const newIndex = getPositionByCellElement(moveCellElement); nodeElement.querySelectorAll(".av__cell--active").forEach((item: HTMLElement) => { item.classList.remove("av__cell--active"); @@ -486,6 +564,7 @@ export class WYSIWYG { documentSelf.onselectstart = null; documentSelf.onselect = null; if (lastCellElement) { + selectRow(nodeElement.querySelector(".av__firstcol"), "unselectAll"); focusBlock(nodeElement); lastCellElement.insertAdjacentHTML("beforeend", `
`); this.preventClick = true;