Prechádzať zdrojové kódy

:art: https://github.com/siyuan-note/siyuan/issues/1359 Shift+↑/↓

Vanessa 2 rokov pred
rodič
commit
abc87f9500

+ 2 - 0
app/src/layout/dock/Files.ts

@@ -259,6 +259,8 @@ export class Files extends Model {
                             this.getLeaf(target, notebookId);
                             this.setCurrent(target, false);
                         }
+                        this.element.querySelector('[select-end="true"]')?.removeAttribute("select-end");
+                        this.element.querySelector('[select-start="true"]')?.removeAttribute("select-start");
                         window.siyuan.menus.menu.remove();
                         event.stopPropagation();
                         event.preventDefault();

+ 1 - 1
app/src/protyle/wysiwyg/commonHotkey.ts

@@ -168,7 +168,7 @@ export const downSelect = (options: {
     options.event.preventDefault();
 };
 
-export const getStartEndElement = (selectElements: NodeListOf<Element>) => {
+export const getStartEndElement = (selectElements: NodeListOf<Element> | Element[]) => {
     let startElement;
     let endElement;
     selectElements.forEach(item => {

+ 46 - 0
app/src/protyle/wysiwyg/getBlock.ts

@@ -182,3 +182,49 @@ export const hasPreviousSibling = (element: Node) => {
     }
     return false;
 };
+
+export const getNextFileLi = (current: Element) => {
+    let nextElement = current.nextElementSibling
+    if (nextElement) {
+        if (nextElement.tagName === "LI") {
+            return nextElement
+        } else if (nextElement.tagName === "UL") {
+            return nextElement.firstElementChild
+        }
+        return false;
+    }
+    nextElement = current.parentElement
+    while (nextElement.tagName === "UL") {
+        if (!nextElement.nextElementSibling) {
+            nextElement = nextElement.parentElement
+        } else if (nextElement.nextElementSibling.tagName === "LI") {
+            return nextElement.nextElementSibling
+        } else  if (nextElement.nextElementSibling.tagName === "UL") {
+            return nextElement.nextElementSibling.firstElementChild;
+        }
+    }
+    return false;
+}
+
+export const getPreviousFileLi = (current: Element) => {
+    let previousElement = current.previousElementSibling
+    if (previousElement) {
+        if (previousElement.tagName === "LI") {
+            return previousElement
+        } else if (previousElement.tagName === "UL") {
+            return previousElement.lastElementChild
+        }
+        return false;
+    }
+    previousElement = current.parentElement
+    while (previousElement.tagName === "UL") {
+        if (!previousElement.previousElementSibling) {
+            previousElement = previousElement.parentElement
+        } else if (previousElement.previousElementSibling.tagName === "LI") {
+            return previousElement.previousElementSibling;
+        } else if (previousElement.previousElementSibling.tagName === "UL") {
+            return previousElement.previousElementSibling.lastElementChild;
+        }
+    }
+    return false;
+}

+ 131 - 74
app/src/util/globalShortcut.ts

@@ -39,6 +39,8 @@ import {deleteFile} from "../editor/deleteFile";
 import {escapeHtml} from "./escape";
 import {syncGuide} from "../sync/syncGuide";
 import {showPopover} from "../block/popover";
+import {getStartEndElement} from "../protyle/wysiwyg/commonHotkey";
+import {getNextFileLi, getPreviousFileLi} from "../protyle/wysiwyg/getBlock";
 
 const getRightBlock = (element: HTMLElement, x: number, y: number) => {
     let index = 1;
@@ -953,99 +955,154 @@ const fileTreeKeydown = (event: KeyboardEvent) => {
         event.preventDefault();
         return true;
     }
-    if ((event.key === "ArrowRight" && !liElements[0].querySelector(".b3-list-item__arrow--open") && !liElements[0].querySelector(".b3-list-item__toggle").classList.contains("fn__hidden")) ||
-        (event.key === "ArrowLeft" && liElements[0].querySelector(".b3-list-item__arrow--open"))) {
-        files.getLeaf(liElements[0], notebookId);
-        liElements.forEach((item, index) => {
-            if (index !== 0) {
-                item.classList.remove("b3-list-item--focus")
-            }
-        })
-        event.preventDefault();
-        return true;
-    }
-    const fileRect = files.element.getBoundingClientRect();
-    if (event.key === "ArrowLeft") {
-        let parentElement = liElements[0].parentElement.previousElementSibling;
-        if (parentElement) {
-            if (parentElement.tagName !== "LI") {
-                parentElement = files.element.querySelector(".b3-list-item");
-            }
-            liElements.forEach((item, index) => {
-                item.classList.remove("b3-list-item--focus")
-            })
-            parentElement.classList.add("b3-list-item--focus");
-            const parentRect = parentElement.getBoundingClientRect();
-            if (parentRect.top < fileRect.top || parentRect.bottom > fileRect.bottom) {
-                parentElement.scrollIntoView(parentRect.top < fileRect.top);
+    if (event.shiftKey) {
+        if (event.key === "ArrowUp") {
+            const startEndElement = getStartEndElement(liElements);
+            if (startEndElement.startElement.getBoundingClientRect().top >= startEndElement.endElement.getBoundingClientRect().top) {
+                const previousElement = getPreviousFileLi(startEndElement.endElement)
+                if (previousElement) {
+                    previousElement.classList.add("b3-list-item--focus");
+                    previousElement.setAttribute("select-end", "true");
+                    startEndElement.endElement.removeAttribute("select-end");
+
+                    const previousRect = previousElement.getBoundingClientRect();
+                    const fileRect = files.element.getBoundingClientRect();
+                    if (previousRect.top < fileRect.top || previousRect.bottom > fileRect.bottom) {
+                        previousElement.scrollIntoView(previousRect.top < fileRect.top);
+                    }
+                }
+            } else {
+                startEndElement.endElement.classList.remove("b3-list-item--focus");
+                startEndElement.endElement.removeAttribute("select-end");
+                const previousElement = getPreviousFileLi(startEndElement.endElement);
+                if (previousElement) {
+                    previousElement.setAttribute("select-end", "true");
+                }
             }
-        }
-        event.preventDefault();
-        return true;
-    }
-    if (event.key === "ArrowDown" || event.key === "ArrowRight") {
-        let nextElement = liElements[0];
-        while (nextElement) {
-            if (nextElement.nextElementSibling) {
-                if (nextElement.nextElementSibling.tagName === "UL") {
-                    nextElement = nextElement.nextElementSibling.firstElementChild;
-                } else {
-                    nextElement = nextElement.nextElementSibling;
+        } else if (event.key === "ArrowDown") {
+            const startEndElement = getStartEndElement(liElements);
+            if (startEndElement.startElement.getBoundingClientRect().top <= startEndElement.endElement.getBoundingClientRect().top) {
+                const nextElement = getNextFileLi(startEndElement.endElement);
+                if (nextElement) {
+                    nextElement.classList.add("b3-list-item--focus");
+                    nextElement.setAttribute("select-end", "true");
+                    startEndElement.endElement.removeAttribute("select-end");
+                    const nextRect = nextElement.getBoundingClientRect();
+                    const fileRect = files.element.getBoundingClientRect();
+                    if (nextRect.top < fileRect.top || nextRect.bottom > fileRect.bottom) {
+                        nextElement.scrollIntoView(nextRect.top < fileRect.top);
+                    }
                 }
-                break;
             } else {
-                if (nextElement.parentElement.classList.contains("fn__flex-1")) {
-                    break;
-                } else {
-                    nextElement = nextElement.parentElement;
+                startEndElement.endElement.classList.remove("b3-list-item--focus");
+                startEndElement.endElement.removeAttribute("select-end");
+                const nextElement = getNextFileLi(startEndElement.endElement);
+                if (nextElement) {
+                    nextElement.setAttribute("select-end", "true");
                 }
             }
         }
-        if (nextElement.classList.contains("b3-list-item")) {
+        return;
+    } else {
+        files.element.querySelector('[select-end="true"]')?.removeAttribute("select-end");
+        files.element.querySelector('[select-start="true"]')?.removeAttribute("select-start");
+        if ((event.key === "ArrowRight" && !liElements[0].querySelector(".b3-list-item__arrow--open") && !liElements[0].querySelector(".b3-list-item__toggle").classList.contains("fn__hidden")) ||
+            (event.key === "ArrowLeft" && liElements[0].querySelector(".b3-list-item__arrow--open"))) {
+            files.getLeaf(liElements[0], notebookId);
             liElements.forEach((item, index) => {
-                item.classList.remove("b3-list-item--focus")
+                if (index !== 0) {
+                    item.classList.remove("b3-list-item--focus")
+                }
             })
-            nextElement.classList.add("b3-list-item--focus");
-            const nextRect = nextElement.getBoundingClientRect();
-            if (nextRect.top < fileRect.top || nextRect.bottom > fileRect.bottom) {
-                nextElement.scrollIntoView(nextRect.top < fileRect.top);
+            event.preventDefault();
+            return true;
+        }
+        if (event.key === "ArrowLeft") {
+            let parentElement = liElements[0].parentElement.previousElementSibling;
+            if (parentElement) {
+                if (parentElement.tagName !== "LI") {
+                    parentElement = files.element.querySelector(".b3-list-item");
+                }
+                liElements.forEach((item) => {
+                    item.classList.remove("b3-list-item--focus")
+                })
+                parentElement.classList.add("b3-list-item--focus");
+                const parentRect = parentElement.getBoundingClientRect();
+                const fileRect = files.element.getBoundingClientRect();
+                if (parentRect.top < fileRect.top || parentRect.bottom > fileRect.bottom) {
+                    parentElement.scrollIntoView(parentRect.top < fileRect.top);
+                }
             }
+            event.preventDefault();
+            return true;
         }
-        event.preventDefault();
-        return true;
-    }
-    if (event.key === "ArrowUp") {
-        let previousElement = liElements[0];
-        while (previousElement) {
-            if (previousElement.previousElementSibling) {
-                if (previousElement.previousElementSibling.tagName === "LI") {
-                    previousElement = previousElement.previousElementSibling;
+        if (event.key === "ArrowDown" || event.key === "ArrowRight") {
+            let nextElement = liElements[0];
+            while (nextElement) {
+                if (nextElement.nextElementSibling) {
+                    if (nextElement.nextElementSibling.tagName === "UL") {
+                        nextElement = nextElement.nextElementSibling.firstElementChild;
+                    } else {
+                        nextElement = nextElement.nextElementSibling;
+                    }
+                    break;
                 } else {
-                    const liElements = previousElement.previousElementSibling.querySelectorAll(".b3-list-item");
-                    previousElement = liElements[liElements.length - 1];
+                    if (nextElement.parentElement.classList.contains("fn__flex-1")) {
+                        break;
+                    } else {
+                        nextElement = nextElement.parentElement;
+                    }
                 }
-                break;
-            } else {
-                if (previousElement.parentElement.classList.contains("fn__flex-1")) {
+            }
+            if (nextElement.classList.contains("b3-list-item")) {
+                liElements.forEach((item) => {
+                    item.classList.remove("b3-list-item--focus")
+                })
+                nextElement.classList.add("b3-list-item--focus");
+                const nextRect = nextElement.getBoundingClientRect();
+                const fileRect = files.element.getBoundingClientRect();
+                if (nextRect.top < fileRect.top || nextRect.bottom > fileRect.bottom) {
+                    nextElement.scrollIntoView(nextRect.top < fileRect.top);
+                }
+            }
+            event.preventDefault();
+            return true;
+        }
+        if (event.key === "ArrowUp") {
+            let previousElement = liElements[0];
+            while (previousElement) {
+                if (previousElement.previousElementSibling) {
+                    if (previousElement.previousElementSibling.tagName === "LI") {
+                        previousElement = previousElement.previousElementSibling;
+                    } else {
+                        const liElements = previousElement.previousElementSibling.querySelectorAll(".b3-list-item");
+                        previousElement = liElements[liElements.length - 1];
+                    }
                     break;
                 } else {
-                    previousElement = previousElement.parentElement;
+                    if (previousElement.parentElement.classList.contains("fn__flex-1")) {
+                        break;
+                    } else {
+                        previousElement = previousElement.parentElement;
+                    }
                 }
             }
-        }
-        if (previousElement.classList.contains("b3-list-item")) {
-            liElements.forEach((item, index) => {
-                item.classList.remove("b3-list-item--focus")
-            })
-            previousElement.classList.add("b3-list-item--focus");
-            const previousRect = previousElement.getBoundingClientRect();
-            if (previousRect.top < fileRect.top || previousRect.bottom > fileRect.bottom) {
-                previousElement.scrollIntoView(previousRect.top < fileRect.top);
+            if (previousElement.classList.contains("b3-list-item")) {
+                liElements.forEach((item) => {
+                    item.classList.remove("b3-list-item--focus")
+                })
+                previousElement.classList.add("b3-list-item--focus");
+                const previousRect = previousElement.getBoundingClientRect();
+                const fileRect = files.element.getBoundingClientRect();
+                if (previousRect.top < fileRect.top || previousRect.bottom > fileRect.bottom) {
+                    previousElement.scrollIntoView(previousRect.top < fileRect.top);
+                }
             }
+            event.preventDefault();
+            return true;
         }
-        event.preventDefault();
-        return true;
     }
+
     if (event.key === "Delete" || (event.key === "Backspace" && isMac())) {
         window.siyuan.menus.menu.remove();
         liElements.forEach(item => {