diff --git a/app/src/menus/commonMenuItem.ts b/app/src/menus/commonMenuItem.ts
index 333e76b2a..873bed15e 100644
--- a/app/src/menus/commonMenuItem.ts
+++ b/app/src/menus/commonMenuItem.ts
@@ -4,7 +4,7 @@ import {shell} from "electron";
import {getDockByType} from "../layout/util";
import {confirmDialog} from "../dialog/confirmDialog";
import {getSearch, isMobile} from "../util/functions";
-import {isLocalPath, movePathTo, pathPosix} from "../util/pathName";
+import {isLocalPath, movePathTo, moveToPath, pathPosix} from "../util/pathName";
import {MenuItem} from "./Menu";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {saveExport} from "../protyle/export";
@@ -805,7 +805,9 @@ export const movePathToMenu = (paths: string[]) => {
icon: "iconMove",
accelerator: window.siyuan.config.keymap.general.move.custom,
click() {
- movePathTo(paths);
+ movePathTo((toPath, toNotebook) =>{
+ moveToPath(paths, toNotebook[0], toPath[0]);
+ }, paths);
}
}).element;
};
diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts
index f210a3c21..c76273780 100644
--- a/app/src/protyle/gutter/index.ts
+++ b/app/src/protyle/gutter/index.ts
@@ -648,8 +648,8 @@ export class Gutter {
accelerator: window.siyuan.config.keymap.general.move.custom,
icon: "iconMove",
click: () => {
- movePathTo([], undefined, (toPath) => {
- hintMoveBlock(toPath, selectsElement, protyle);
+ movePathTo((toPath) => {
+ hintMoveBlock(toPath[0], selectsElement, protyle);
});
}
}).element);
@@ -1019,8 +1019,8 @@ export class Gutter {
accelerator: window.siyuan.config.keymap.general.move.custom,
icon: "iconMove",
click: () => {
- movePathTo([], undefined, (toPath) => {
- hintMoveBlock(toPath, [nodeElement], protyle);
+ movePathTo((toPath) => {
+ hintMoveBlock(toPath[0], [nodeElement], protyle);
});
}
}).element);
diff --git a/app/src/search/spread.ts b/app/src/search/spread.ts
index edeab9ff8..001564bd0 100644
--- a/app/src/search/spread.ts
+++ b/app/src/search/spread.ts
@@ -62,17 +62,17 @@ export const openSearch = async (hotkey: string, key?: string, notebookId?: stri
};
}
let hPath = ""
- let idPath = ""
+ const idPath: string[] = []
if (notebookId) {
hPath = escapeHtml(getNotebookName(notebookId));
- idPath = notebookId;
+ idPath.push(notebookId);
if (searchPath && searchPath !== "/") {
const response = await fetchSyncPost("/api/filetree/getHPathByPath", {
notebook: notebookId,
path: searchPath.endsWith(".sy") ? searchPath : searchPath + ".sy"
});
hPath = pathPosix().join(hPath, escapeHtml(response.data));
- idPath = pathPosix().join(idPath, searchPath);
+ idPath[0] = pathPosix().join(idPath[0], searchPath);
}
}
diff --git a/app/src/search/util.ts b/app/src/search/util.ts
index 4ff0911e6..aad3b35cd 100644
--- a/app/src/search/util.ts
+++ b/app/src/search/util.ts
@@ -62,7 +62,7 @@ export const openGlobalSearch = (text: string, replace: boolean) => {
hasReplace: false,
method: localData.method || 0,
hPath: "",
- idPath: "",
+ idPath: [],
list: [],
replaceList: [],
group: localData.group || 0,
@@ -183,7 +183,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
let target = event.target as HTMLElement;
while (target && !target.isSameNode(element)) {
if (target.classList.contains("search__rmpath")) {
- config.idPath = "";
+ config.idPath = [];
config.hPath = "";
element.querySelector("#searchPathInput").innerHTML = config.hPath;
inputTimeout = inputEvent(element, config, inputTimeout, edit, false);
@@ -211,21 +211,17 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
event.preventDefault();
break;
} else if (target.id === "searchPath") {
- movePathTo([], undefined, (toPath, toNotebook) => {
- if (toPath === "/") {
- config.idPath = toNotebook;
- config.hPath = escapeHtml(getNotebookName(toNotebook));
+ movePathTo((toPath, toNotebook) => {
+ fetchPost("/api/filetree/getHPathsByPaths", {paths: toPath}, (response) => {
+ config.idPath = []
+ toNotebook.forEach((item, index) => {
+ config.idPath.push(pathPosix().join(item, toPath[index]));
+ })
+ config.hPath = escapeHtml(response.data ? response.data.join(", ") : "");
element.querySelector("#searchPathInput").innerHTML = `${config.hPath}`;
inputTimeout = inputEvent(element, config, inputTimeout, edit, false);
- } else {
- config.idPath = pathPosix().join(toNotebook, toPath);
- fetchPost("/api/filetree/getHPathsByPaths", {paths: [toPath]}, (response) => {
- config.hPath = escapeHtml(response.data ? response.data[0] : "");
- element.querySelector("#searchPathInput").innerHTML = `${config.hPath}`;
- inputTimeout = inputEvent(element, config, inputTimeout, edit, false);
- });
- }
- }, window.siyuan.languages.specifyPath);
+ });
+ }, [], undefined, window.siyuan.languages.specifyPath);
event.stopPropagation();
event.preventDefault();
break;
@@ -278,30 +274,36 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
break;
} else if (target.id === "searchFilter") {
window.siyuan.menus.menu.remove();
+ let includeChild = true
+ config.idPath.find(item => {
+ if (!item.endsWith(".sy")) {
+ includeChild = false
+ return true;
+ }
+ });
window.siyuan.menus.menu.append(new MenuItem({
label: `
${window.siyuan.languages.includeChildDoc}
-
`,
+`,
bind(menuItemElement) {
menuItemElement.addEventListener("click", (event: MouseEvent & { target: HTMLElement }) => {
const inputElement = menuItemElement.querySelector("input");
if (event.target.tagName !== "INPUT") {
inputElement.checked = !inputElement.checked;
}
- let reload = false;
if (!inputElement.checked) {
- if (!config.idPath.endsWith(".sy") && config.idPath.split("/").length > 1) {
- config.idPath = config.idPath + ".sy";
- reload = true;
- }
+ config.idPath.forEach((item, index) => {
+ if (!item.endsWith(".sy") && item.split("/").length > 1) {
+ config.idPath[index] = item + ".sy";
+ }
+ });
} else {
- if (config.idPath.endsWith(".sy")) {
- config.idPath = config.idPath.replace(".sy", "");
- reload = true;
- }
- }
- if (reload) {
- inputTimeout = inputEvent(element, config, inputTimeout, edit);
+ config.idPath.forEach((item, index) => {
+ if (item.endsWith(".sy")) {
+ config.idPath[index] = item.replace(".sy", "");
+ }
+ });
}
+ inputTimeout = inputEvent(element, config, inputTimeout, edit);
window.siyuan.menus.menu.remove();
});
}
@@ -730,7 +732,7 @@ const inputEvent = (element: Element, config: ISearchOption, inputTimeout: numbe
query: inputValue,
method: config.method,
types: config.types,
- path: config.idPath || "",
+ paths: config.idPath || [],
groupBy: config.group, // 0:不分组,1:按文档分组
}, (response) => {
onSearch(response.data.blocks, edit, element);
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index 9d9e097e7..c7bd0b62a 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -53,7 +53,7 @@ interface ISearchOption {
hasReplace: boolean,
method: number // 0:文本,1:查询语法,2:SQL,3:正则表达式
hPath: string
- idPath: string
+ idPath: string[]
k: string
r: string
replaceList: string[]
diff --git a/app/src/util/globalShortcut.ts b/app/src/util/globalShortcut.ts
index 5d68567f6..976bef9c3 100644
--- a/app/src/util/globalShortcut.ts
+++ b/app/src/util/globalShortcut.ts
@@ -22,7 +22,7 @@ import {hideElements} from "../protyle/ui/hideElements";
import {fetchPost} from "./fetch";
import {goBack, goForward} from "./backForward";
import {onGet} from "../protyle/util/onGet";
-import {getDisplayName, getNotebookName, getTopPaths, movePathTo} from "./pathName";
+import {getDisplayName, getNotebookName, getTopPaths, movePathTo, moveToPath} from "./pathName";
import {openFileById} from "../editor/util";
import {getAllDocks, getAllModels, getAllTabs} from "../layout/getAll";
import {openGlobalSearch} from "../search/util";
@@ -817,14 +817,16 @@ const editKeydown = (event: KeyboardEvent) => {
nodeElement = hasClosestBlock(range.startContainer);
}
if (protyle.title?.editElement.contains(range.startContainer)) {
- movePathTo([protyle.path], range);
+ movePathTo((toPath, toNotebook) => {
+ moveToPath([protyle.path], toNotebook[0], toPath[0]);
+ }, [protyle.path], range);
} else if (nodeElement && range && protyle.element.contains(range.startContainer)) {
let selectElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
if (selectElements.length === 0) {
selectElements = [nodeElement];
}
- movePathTo([], undefined, (toPath) => {
- hintMoveBlock(toPath, selectElements, protyle);
+ movePathTo((toPath) => {
+ hintMoveBlock(toPath[0], selectElements, protyle);
});
}
event.preventDefault();
@@ -939,7 +941,10 @@ const fileTreeKeydown = (event: KeyboardEvent) => {
}
if (isFile && matchHotKey(window.siyuan.config.keymap.general.move.custom, event)) {
window.siyuan.menus.menu.remove();
- movePathTo(getTopPaths(liElements));
+ const pathes = getTopPaths(liElements)
+ movePathTo((toPath, toNotebook) => {
+ moveToPath(pathes, toNotebook[0], toPath[0]);
+ }, pathes);
event.preventDefault();
event.stopPropagation();
return true;
diff --git a/app/src/util/pathName.ts b/app/src/util/pathName.ts
index 74d199dc9..03742ada1 100644
--- a/app/src/util/pathName.ts
+++ b/app/src/util/pathName.ts
@@ -77,7 +77,7 @@ export const getTopPaths = (liElements: Element[]) => {
return fromPaths;
};
-const moveToPath = (fromPaths: string[], toNotebook: string, toPath: string) => {
+export const moveToPath = (fromPaths: string[], toNotebook: string, toPath: string) => {
fetchPost("/api/filetree/moveDocs", {
toNotebook,
fromPaths,
@@ -85,7 +85,7 @@ const moveToPath = (fromPaths: string[], toNotebook: string, toPath: string) =>
});
};
-export const movePathTo = (paths?: string[], range?: Range, cb?: (toPath: string, toNotebook:string) => void, title?: string) => {
+export const movePathTo = (cb: (toPath: string[], toNotebook: string[]) => void, paths?: string[], range?: Range, title?: string) => {
const exitDialog = window.siyuan.dialogs.find((item) => {
if (item.element.querySelector("#foldList")) {
item.destroy();
@@ -178,10 +178,18 @@ export const movePathTo = (paths?: string[], range?: Range, cb?: (toPath: string
return;
}
const currentPanelElement = searchListElement.classList.contains("fn__none") ? searchTreeElement : searchListElement;
- let currentItemElement: HTMLElement = currentPanelElement.querySelector(".b3-list-item--focus");
- if (!currentItemElement) {
+ const currentItemElements = currentPanelElement.querySelectorAll(".b3-list-item--focus");
+ if (currentItemElements.length === 0) {
return;
}
+ let currentItemElement: HTMLElement = currentItemElements[0] as HTMLElement;
+ if (event.key.startsWith("Arrow")) {
+ currentItemElements.forEach((item, index) => {
+ if (index !== 0) {
+ item.classList.remove("b3-list-item--focus")
+ }
+ })
+ }
if (searchListElement.classList.contains("fn__none")) {
if ((event.key === "ArrowRight" && !currentItemElement.querySelector(".b3-list-item__arrow--open") && !currentItemElement.querySelector(".b3-list-item__toggle").classList.contains("fn__hidden")) ||
(event.key === "ArrowLeft" && currentItemElement.querySelector(".b3-list-item__arrow--open"))) {
@@ -308,11 +316,17 @@ export const movePathTo = (paths?: string[], range?: Range, cb?: (toPath: string
}
}
if (event.key === "Enter") {
- if (cb) {
- cb(currentItemElement.getAttribute("data-path"), currentItemElement.getAttribute("data-box"));
- } else {
- moveToPath(paths, currentItemElement.getAttribute("data-box"), currentItemElement.getAttribute("data-path"));
+ const currentItemElements = currentPanelElement.querySelectorAll(".b3-list-item--focus");
+ if (currentItemElements.length === 0) {
+ return;
}
+ const pathList: string[] = []
+ const notebookIdList: string[] = []
+ currentItemElements.forEach(item => {
+ pathList.push(item.getAttribute("data-path"))
+ notebookIdList.push(item.getAttribute("data-box"))
+ })
+ cb(pathList, notebookIdList);
dialog.destroy();
event.preventDefault();
}
@@ -327,15 +341,17 @@ export const movePathTo = (paths?: string[], range?: Range, cb?: (toPath: string
break;
} else if (target.classList.contains("b3-button--text")) {
const currentPanelElement = searchListElement.classList.contains("fn__none") ? searchTreeElement : searchListElement;
- const currentItemElement: HTMLElement = currentPanelElement.querySelector(".b3-list-item--focus");
- if (!currentItemElement) {
+ const currentItemElements = currentPanelElement.querySelectorAll(".b3-list-item--focus");
+ if (currentItemElements.length === 0) {
return;
}
- if (cb) {
- cb(currentItemElement.getAttribute("data-path"), currentItemElement.getAttribute("data-box"));
- } else {
- moveToPath(paths, currentItemElement.getAttribute("data-box"), currentItemElement.getAttribute("data-path"));
- }
+ const pathList: string[] = []
+ const notebookIdList: string[] = []
+ currentItemElements.forEach(item => {
+ pathList.push(item.getAttribute("data-path"))
+ notebookIdList.push(item.getAttribute("data-box"))
+ })
+ cb(pathList, notebookIdList);
dialog.destroy();
event.preventDefault();
event.stopPropagation();
@@ -347,12 +363,20 @@ export const movePathTo = (paths?: string[], range?: Range, cb?: (toPath: string
break;
} else if (target.classList.contains("b3-list-item")) {
const currentPanelElement = searchListElement.classList.contains("fn__none") ? searchTreeElement : searchListElement;
- const currentItemElement: HTMLElement = currentPanelElement.querySelector(".b3-list-item--focus");
- if (!currentItemElement) {
+ const currentItemElements = currentPanelElement.querySelectorAll(".b3-list-item--focus");
+ if (currentItemElements.length === 0) {
return;
}
- currentItemElement.classList.remove("b3-list-item--focus");
- target.classList.add("b3-list-item--focus");
+ if (title === window.siyuan.languages.specifyPath && (event.ctrlKey || event.metaKey)) {
+ if (currentItemElements.length === 1 && currentItemElements[0].isSameNode(target)) {
+ // 至少需选中一个
+ } else {
+ target.classList.toggle("b3-list-item--focus");
+ }
+ } else {
+ currentItemElements[0].classList.remove("b3-list-item--focus");
+ target.classList.add("b3-list-item--focus");
+ }
event.preventDefault();
event.stopPropagation();
break;