Browse Source

:art: https://github.com/siyuan-note/siyuan/issues/9417

Vanessa 1 year ago
parent
commit
48e871c75e

+ 18 - 11
app/src/protyle/render/av/cell.ts

@@ -344,6 +344,23 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
     menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
 };
 
+export const cellScrollIntoView = (blockElement: HTMLElement, cellRect: DOMRect) => {
+    const avScrollElement = blockElement.querySelector(".av__scroll");
+    const avScrollRect = avScrollElement.getBoundingClientRect();
+    if (avScrollRect.left > cellRect.left) {
+        avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - avScrollRect.left;
+    } else if (avScrollRect.right < cellRect.right) {
+        avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.right - avScrollRect.right;
+    }
+    const avHeaderRect = blockElement.querySelector(".av__header").getBoundingClientRect()
+    if (avHeaderRect.bottom > cellRect.top) {
+        const contentElement = hasClosestByClassName(blockElement, "protyle-content");
+        if (contentElement) {
+            contentElement.scrollTop = contentElement.scrollTop + cellRect.top - avHeaderRect.bottom;
+        }
+    }
+}
+
 export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type?: TAVCol) => {
     if (!type) {
         type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
@@ -357,17 +374,7 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
     const blockElement = hasClosestBlock(cellElements[0]);
     let cellRect = cellElements[0].getBoundingClientRect();
     if (blockElement) {
-        const avScrollElement = blockElement.querySelector(".av__scroll");
-        const avScrollRect = avScrollElement.getBoundingClientRect();
-        if (avScrollRect.left > cellRect.left) {
-            avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - avScrollRect.left;
-        } else if (avScrollRect.right < cellRect.right) {
-            avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.right - avScrollRect.right;
-        }
-        const avHeaderRect = blockElement.querySelector(".av__header").getBoundingClientRect()
-        if (avHeaderRect.bottom > cellRect.top) {
-            protyle.contentElement.scrollTop = protyle.contentElement.scrollTop + cellRect.top - avHeaderRect.bottom;
-        }
+        cellScrollIntoView(blockElement, cellRect)
     }
     cellRect = cellElements[0].getBoundingClientRect();
     let html = "";

+ 65 - 0
app/src/protyle/render/av/keydown.ts

@@ -0,0 +1,65 @@
+import {matchHotKey} from "../../util/hotKey";
+import {selectRow, updateHeader} from "./row";
+import {cellScrollIntoView} from "./cell";
+
+export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement) => {
+    if (!nodeElement.classList.contains("av")) {
+        return false;
+    }
+    if (event.isComposing) {
+        event.stopPropagation();
+        return true;
+    }
+    // 避免浏览器默认快捷键
+    if (matchHotKey("⌘B", event) || matchHotKey("⌘I", event) || matchHotKey("⌘U", event)) {
+        event.preventDefault();
+        return true;
+    }
+    const selectCellElement = nodeElement.querySelector(".av__cell--select")
+    if (selectCellElement) {
+        if (event.key === "Escape") {
+            selectCellElement.classList.remove("av__cell--select");
+            selectRow(selectCellElement.parentElement.querySelector(".av__firstcol"), "select");
+            event.preventDefault();
+            return true;
+        }
+        if (event.key === "Enter") {
+            // TODO
+            event.preventDefault();
+            return true;
+        }
+        let cellRect
+        if (event.key === "ArrowLeft") {
+            const previousRowElement = selectCellElement.parentElement.previousElementSibling
+            if (selectCellElement.previousElementSibling && selectCellElement.previousElementSibling.classList.contains("av__cell")) {
+                selectCellElement.classList.remove("av__cell--select");
+                selectCellElement.previousElementSibling.classList.add("av__cell--select");
+                cellRect = nodeElement.querySelector(".av__cell--select").getBoundingClientRect();
+            } else if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
+                selectCellElement.classList.remove("av__cell--select");
+                previousRowElement.lastElementChild.previousElementSibling.classList.add("av__cell--select");
+                cellRect = nodeElement.querySelector(".av__cell--select").getBoundingClientRect();
+            }
+            if (cellRect) {
+                cellScrollIntoView(nodeElement, cellRect);
+            }
+            event.preventDefault();
+            return true;
+        }
+    }
+    const selectRowElement = nodeElement.querySelector(".av__row--select:not(.av__row--header)") as HTMLElement;
+    if (selectRowElement) {
+        if (event.key === "Escape") {
+            selectRowElement.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck");
+            selectRowElement.classList.remove("av__row--select");
+            updateHeader(selectRowElement);
+            return true;
+        }
+        // event.shiftKey
+        if (event.key === "ArrowUp") {
+            return true;
+        }
+    }
+    return false;
+}
+

+ 5 - 19
app/src/protyle/wysiwyg/keydown.ts

@@ -69,7 +69,7 @@ import {escapeHtml} from "../../util/escape";
 import {insertHTML} from "../util/insertHTML";
 import {removeSearchMark} from "../toolbar/util";
 import {copyPNG} from "../../menus/util";
-import {selectRow, updateHeader} from "../render/av/row";
+import {avKeydown} from "../render/av/keydown";
 
 
 const getContentByInlineHTML = (range: Range, cb: (content: string) => void) => {
@@ -119,14 +119,10 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
             return;
         }
 
-        if (nodeElement.classList.contains("av")) {
-            if (matchHotKey("⌘B", event) || matchHotKey("⌘I", event) || matchHotKey("⌘U", event)) {
-                event.preventDefault();
-            }
-            if (event.key !== "Escape") {
-                return;
-            }
+        if (avKeydown(event, nodeElement)) {
+            return;
         }
+
         if (nodeElement.classList.contains("protyle-wysiwyg--select") && !isCtrl(event) && !event.shiftKey && !event.altKey) {
             if (event.key.toLowerCase() === "a") {
                 event.stopPropagation();
@@ -1217,11 +1213,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
 
         // esc
         if (event.key === "Escape") {
-            const cellSelectElement = nodeElement.querySelector(".av__cell--select")
-            if (cellSelectElement) {
-                cellSelectElement.classList.remove("av__cell--select");
-                selectRow(cellSelectElement.parentElement.querySelector(".av__firstcol"), "select");
-            } else if (!protyle.toolbar.element.classList.contains("fn__none") ||
+            if (!protyle.toolbar.element.classList.contains("fn__none") ||
                 !protyle.hint.element.classList.contains("fn__none") ||
                 !protyle.toolbar.subElement.classList.contains("fn__none")) {
                 hideElements(["toolbar", "hint", "util"], protyle);
@@ -1237,12 +1229,6 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
                 range.collapse(false);
                 nodeElement.classList.add("protyle-wysiwyg--select");
                 countBlockWord([nodeElement.getAttribute("data-node-id")], protyle.block.rootID);
-                const selectRowElement = nodeElement.querySelector(".av__row--select:not(.av__row--header)") as HTMLElement;
-                if (selectRowElement) {
-                    selectRowElement.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck");
-                    selectRowElement.classList.remove("av__row--select");
-                    updateHeader(selectRowElement);
-                }
             }
             event.preventDefault();
             return;