diff --git a/app/src/assets/scss/business/_search.scss b/app/src/assets/scss/business/_search.scss index 01c89340e..229b1b1d2 100644 --- a/app/src/assets/scss/business/_search.scss +++ b/app/src/assets/scss/business/_search.scss @@ -61,7 +61,7 @@ top: 42px; position: absolute; left: 8px; - z-index: 1; + z-index: 3; } } diff --git a/app/src/boot/globalEvent/keydown.ts b/app/src/boot/globalEvent/keydown.ts index fac61df0c..8cee4904c 100644 --- a/app/src/boot/globalEvent/keydown.ts +++ b/app/src/boot/globalEvent/keydown.ts @@ -64,6 +64,7 @@ import {transaction} from "../../protyle/wysiwyg/transaction"; import {quickMakeCard} from "../../card/makeCard"; import {copyPNG} from "../../menus/util"; import {getContentByInlineHTML} from "../../protyle/wysiwyg/keydown"; +import {searchKeydown} from "./searchKeydown"; const switchDialogEvent = (app: App, event: MouseEvent) => { event.preventDefault(); @@ -1018,6 +1019,12 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => { return; } + if (searchKeydown(app, event)) { + event.preventDefault(); + event.stopPropagation(); + return; + } + const isTabWindow = isWindow(); if (event.ctrlKey && !event.metaKey && event.key === "Tab") { if (switchDialog && switchDialog.element.parentElement) { @@ -1580,7 +1587,6 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => { event.preventDefault(); return; } - // https://github.com/siyuan-note/insider/issues/445 if (matchHotKey("⌘S", event)) { event.preventDefault(); diff --git a/app/src/boot/globalEvent/searchKeydown.ts b/app/src/boot/globalEvent/searchKeydown.ts new file mode 100644 index 000000000..04f131a7f --- /dev/null +++ b/app/src/boot/globalEvent/searchKeydown.ts @@ -0,0 +1,291 @@ +/// #if !BROWSER +import * as path from "path"; +/// #endif +import {matchHotKey} from "../../protyle/util/hotKey"; +import {fetchPost} from "../../util/fetch"; +import {openFileById} from "../../editor/util"; +import {Constants} from "../../constants"; +import {newFileByName} from "../../util/newFile"; +import {upDownHint} from "../../util/upDownHint"; +import {App} from "../../index"; +import {Dialog} from "../../dialog"; +import {getAllModels} from "../../layout/getAll"; +import {hasClosestByClassName} from "../../protyle/util/hasClosest"; +import {getArticle, inputEvent, replace, toggleReplaceHistory, toggleSearchHistory} from "../../search/util"; +import {showFileInFolder} from "../../util/pathName"; +import {assetInputEvent, renderPreview, toggleAssetHistory} from "../../search/assets"; + +export const searchKeydown = (app: App, event: KeyboardEvent) => { + if (getSelection().rangeCount === 0) { + return false; + } + const range = getSelection().getRangeAt(0); + if (hasClosestByClassName(range.startContainer, "protyle", true)) { + return false; + } + let element: HTMLElement + let dialog: Dialog + let edit + let config: ISearchOption + window.siyuan.dialogs.find((item) => { + if (item.element.contains(range.startContainer) && item.element.querySelector("#searchList")) { + element = item.element.querySelector(".b3-dialog__body"); + dialog = item + config = dialog.data + edit = dialog.editor + return true; + } + }); + if (!element) { + getAllModels().search.find((item) => { + if (item.element.contains(range.startContainer)) { + element = item.element; + edit = item.edit; + config = item.config + return true; + } + }); + } + if (!element) { + return false; + } + const assetsElement = element.querySelector("#searchAssets"); + const isAsset = !assetsElement.classList.contains("fn__none") + const listElement = isAsset ? assetsElement.querySelector("#searchAssetList") : element.querySelector("#searchList"); + let currentList: HTMLElement = listElement.querySelector(".b3-list-item--focus"); + if (!currentList) { + return false; + } + const searchInputElement = element.querySelector("#searchInput") as HTMLInputElement; + if (!isAsset && matchHotKey(window.siyuan.config.keymap.general.newFile.custom, event)) { + newFileByName(app, searchInputElement.value); + return true; + } + const targetId = (event.target as HTMLElement).id + const historyElement = element.querySelector("#searchHistoryList"); + const replaceHistoryElement = element.querySelector("#replaceHistoryList"); + const replaceInputElement = element.querySelector("#replaceInput") as HTMLInputElement; + const assetHistoryElement = assetsElement.querySelector("#searchAssetHistoryList"); + const assetInputElement = assetsElement.querySelector("#searchAssetInput") as HTMLInputElement; + const assetPreviewElement = assetsElement.querySelector("#searchAssetPreview"); + if (event.key === "ArrowDown" && event.altKey) { + if (isAsset) { + toggleAssetHistory(assetHistoryElement, assetInputElement); + } else { + if (targetId === "replaceInput") { + toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); + } else { + toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); + } + } + return true; + } + const assetLocal = window.siyuan.storage[Constants.LOCAL_SEARCHASSET] as ISearchAssetOption + let history; + if (!historyElement.classList.contains("fn__none")) { + history = "history" + } else if (!replaceHistoryElement.classList.contains("fn__none")) { + history = "replaceHistory" + } else if (isAsset && !assetHistoryElement.classList.contains("fn__none")) { + history = "assetHistory" + } + if (history) { + if (event.key === "Escape") { + if (isAsset) { + toggleAssetHistory(assetHistoryElement, assetInputElement); + } else { + if ((event.target as HTMLElement).id === "replaceInput") { + toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); + } else { + toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); + } + } + } else if (event.key === "Enter") { + if (history === "replaceHistory") { + replaceInputElement.value = replaceHistoryElement.querySelector(".b3-list-item--focus").textContent.trim(); + toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); + } else if (history === "assetHistory") { + assetInputElement.value = assetHistoryElement.querySelector(".b3-list-item--focus").textContent.trim(); + assetInputEvent(assetsElement, assetLocal); + toggleAssetHistory(assetHistoryElement, assetInputElement); + renderPreview(assetPreviewElement, currentList.dataset.id, assetInputElement.value, assetLocal.method); + } else { + searchInputElement.value = historyElement.querySelector(".b3-list-item--focus").textContent.trim(); + config.page = 1; + inputEvent(element, config, edit, true); + toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); + } + } else { + if (history === "assetHistory") { + upDownHint(assetHistoryElement, event); + } else { + if (history === "replaceHistory") { + upDownHint(replaceHistoryElement, event); + } else { + upDownHint(historyElement, event); + } + } + } + return true; + } + if (currentList.getAttribute("data-type") === "search-new") { + if (event.key === "Enter") { + newFileByName(app, searchInputElement.value); + return true; + } + return false; + } + if (!isAsset && matchHotKey(window.siyuan.config.keymap.editor.general.insertRight.custom, event)) { + const id = currentList.getAttribute("data-node-id"); + fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => { + openFileById({ + app, + id, + position: "right", + action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : + (id === currentList.getAttribute("data-root-id") ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ROOTSCROLL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT]), + zoomIn: foldResponse.data + }); + if (dialog) { + dialog.destroy({focus: "false"}); + } + }); + return true; + } + // TODO https://github.com/siyuan-note/siyuan/issues/9548 + if (Constants.KEYCODELIST[event.keyCode] === "PageUp") { + if (isAsset) { + if (!assetsElement.querySelector('[data-type="assetPrevious"]').getAttribute("disabled")) { + let currentPage = parseInt(assetsElement.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[0]); + if (currentPage > 1) { + currentPage--; + assetInputEvent(assetsElement, assetLocal, currentPage); + } + } + } else { + if (!element.querySelector('[data-type="previous"]').getAttribute("disabled")) { + if (config.page > 1) { + config.page--; + inputEvent(element, config, edit); + } + } + } + return true + } + if (Constants.KEYCODELIST[event.keyCode] === "PageDown") { + if (isAsset) { + if (!assetsElement.querySelector('[data-type="assetNext"]').getAttribute("disabled")) { + const assetPages = assetsElement.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/") + let currentPage = parseInt(assetPages[0]); + if (currentPage < parseInt(assetPages[1])) { + currentPage++; + assetInputEvent(assetsElement, assetLocal, currentPage); + } + } + } else { + const nextElement = element.querySelector('[data-type="next"]'); + if (!nextElement.getAttribute("disabled")) { + if (config.page < parseInt(nextElement.parentElement.querySelector("#searchResult").getAttribute("data-pagecount"))) { + config.page++; + inputEvent(element, config, edit); + } + } + } + return true + } + if (!window.siyuan.menus.menu.element.classList.contains("fn__none")) { + return false; + } + if (event.key === "Enter") { + if (!isAsset) { + if (targetId === "replaceInput") { + replace(element, config, edit, false); + } else { + const id = currentList.getAttribute("data-node-id"); + fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => { + openFileById({ + app, + id, + action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : + (id === currentList.getAttribute("data-root-id") ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ROOTSCROLL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT]), + zoomIn: foldResponse.data + }); + if (dialog) { + dialog.destroy({focus: "false"}); + } + }); + } + } else { + /// #if !BROWSER + showFileInFolder(path.join(window.siyuan.config.system.dataDir, currentList.lastElementChild.getAttribute("aria-label"))); + /// #endif + } + return true; + } + const lineHeight = 28; + if (event.key === "ArrowDown") { + currentList.classList.remove("b3-list-item--focus"); + if (!currentList.nextElementSibling) { + if (config.group === 1 && !isAsset) { + if (currentList.parentElement.nextElementSibling) { + currentList.parentElement.nextElementSibling.nextElementSibling.firstElementChild.classList.add("b3-list-item--focus"); + } else { + listElement.children[1].firstElementChild.classList.add("b3-list-item--focus"); + } + } else { + listElement.firstElementChild.classList.add("b3-list-item--focus"); + } + } else { + currentList.nextElementSibling.classList.add("b3-list-item--focus"); + } + currentList = listElement.querySelector(".b3-list-item--focus"); + if (listElement.scrollTop < currentList.offsetTop - listElement.clientHeight + lineHeight || + listElement.scrollTop > currentList.offsetTop) { + listElement.scrollTop = currentList.offsetTop - listElement.clientHeight + lineHeight; + } + if (isAsset) { + renderPreview(assetPreviewElement, currentList.dataset.id, searchInputElement.value, assetLocal.method); + } else { + getArticle({ + id: currentList.getAttribute("data-node-id"), + config, + value: searchInputElement.value, + edit, + }); + } + return true + } + if (event.key === "ArrowUp") { + currentList.classList.remove("b3-list-item--focus"); + if (!currentList.previousElementSibling) { + if (config.group === 1 && !isAsset) { + if (currentList.parentElement.previousElementSibling.previousElementSibling) { + currentList.parentElement.previousElementSibling.previousElementSibling.lastElementChild.classList.add("b3-list-item--focus"); + } else { + listElement.lastElementChild.lastElementChild.classList.add("b3-list-item--focus"); + } + } else { + listElement.lastElementChild.classList.add("b3-list-item--focus"); + } + } else { + currentList.previousElementSibling.classList.add("b3-list-item--focus"); + } + currentList = listElement.querySelector(".b3-list-item--focus"); + if (listElement.scrollTop < currentList.offsetTop - listElement.clientHeight + lineHeight || + listElement.scrollTop > currentList.offsetTop - lineHeight * 2) { + listElement.scrollTop = currentList.offsetTop - lineHeight * 2; + } + if (isAsset) { + renderPreview(assetPreviewElement, currentList.dataset.id, searchInputElement.value, assetLocal.method); + } else { + getArticle({ + id: currentList.getAttribute("data-node-id"), + config, + value: searchInputElement.value, + edit, + }); + } + return true; + } + return false; +}; diff --git a/app/src/dialog/index.ts b/app/src/dialog/index.ts index 77cdc383f..fe6ad68e9 100644 --- a/app/src/dialog/index.ts +++ b/app/src/dialog/index.ts @@ -12,6 +12,7 @@ export class Dialog { private id: string; private disableClose: boolean; public editor: Protyle; + public data: any; constructor(options: { title?: string, diff --git a/app/src/search/assets.ts b/app/src/search/assets.ts index daaf7749c..90679fd77 100644 --- a/app/src/search/assets.ts +++ b/app/src/search/assets.ts @@ -1,9 +1,5 @@ -/// #if !BROWSER -import * as path from "path"; -/// #endif import {Constants} from "../constants"; import {fetchPost} from "../util/fetch"; -import {upDownHint} from "../util/upDownHint"; import {escapeAriaLabel, escapeHtml} from "../util/escape"; import {setStorageVal} from "../protyle/util/compatibility"; /// #if !MOBILE @@ -11,7 +7,6 @@ import {getQueryTip} from "./util"; /// #endif import {MenuItem} from "../menus/Menu"; import {Dialog} from "../dialog"; -import {showFileInFolder} from "../util/pathName"; export const openSearchAsset = (element: Element, isStick: boolean) => { /// #if !MOBILE @@ -78,7 +73,6 @@ export const openSearchAsset = (element: Element, isStick: boolean) => { Click ${window.siyuan.languages.searchTip3} Esc ${window.siyuan.languages.searchTip5} `; - const searchPanelElement = element.querySelector("#searchAssetList"); if (element.querySelector("#searchAssetList").innerHTML !== "") { return; } @@ -123,95 +117,6 @@ export const openSearchAsset = (element: Element, isStick: boolean) => { window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = list; setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]); }); - const historyElement = element.querySelector("#searchAssetHistoryList"); - const lineHeight = 28; - searchInputElement.addEventListener("keydown", (event: KeyboardEvent) => { - if (event.isComposing) { - return; - } - let currentList: HTMLElement = searchPanelElement.querySelector(".b3-list-item--focus"); - const isHistory = !historyElement.classList.contains("fn__none"); - if (event.key === "Enter") { - if (!isHistory) { - if (currentList) { - /// #if !BROWSER - showFileInFolder(path.join(window.siyuan.config.system.dataDir, currentList.lastElementChild.getAttribute("aria-label"))); - /// #endif - } - } else { - searchInputElement.value = historyElement.querySelector(".b3-list-item--focus").textContent.trim(); - assetInputEvent(element, localSearch); - toggleAssetHistory(historyElement, searchInputElement); - renderPreview(previewElement, currentList.dataset.id, searchInputElement.value, localSearch.method); - } - event.preventDefault(); - return; - } - if (event.key === "ArrowDown" && event.altKey) { - toggleAssetHistory(historyElement, searchInputElement); - return; - } - if (isHistory) { - if (event.key === "Escape") { - toggleAssetHistory(historyElement, searchInputElement); - } else { - upDownHint(historyElement, event); - } - event.stopPropagation(); - event.preventDefault(); - return; - } - if (!currentList) { - return; - } - if (event.key === "ArrowDown") { - currentList.classList.remove("b3-list-item--focus"); - if (!currentList.nextElementSibling) { - searchPanelElement.firstElementChild.classList.add("b3-list-item--focus"); - } else { - currentList.nextElementSibling.classList.add("b3-list-item--focus"); - } - currentList = searchPanelElement.querySelector(".b3-list-item--focus"); - if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight || - searchPanelElement.scrollTop > currentList.offsetTop) { - searchPanelElement.scrollTop = currentList.offsetTop - searchPanelElement.clientHeight + lineHeight; - } - event.preventDefault(); - renderPreview(previewElement, currentList.dataset.id, searchInputElement.value, localSearch.method); - } else if (event.key === "ArrowUp") { - currentList.classList.remove("b3-list-item--focus"); - if (!currentList.previousElementSibling) { - searchPanelElement.lastElementChild.classList.add("b3-list-item--focus"); - } else { - currentList.previousElementSibling.classList.add("b3-list-item--focus"); - } - currentList = searchPanelElement.querySelector(".b3-list-item--focus"); - if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight || - searchPanelElement.scrollTop > currentList.offsetTop - lineHeight * 2) { - searchPanelElement.scrollTop = currentList.offsetTop - lineHeight * 2; - } - event.preventDefault(); - renderPreview(previewElement, currentList.dataset.id, searchInputElement.value, localSearch.method); - } else if (Constants.KEYCODELIST[event.keyCode] === "PageUp") { - if (!element.querySelector('[data-type="assetPrevious"]').getAttribute("disabled")) { - let currentPage = parseInt(element.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[0]); - if (currentPage > 1) { - currentPage--; - assetInputEvent(element, localSearch, currentPage); - } - } - event.preventDefault(); - } else if (Constants.KEYCODELIST[event.keyCode] === "PageDown") { - if (!element.querySelector('[data-type="assetNext"]').getAttribute("disabled")) { - let currentPage = parseInt(element.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[0]); - if (currentPage < parseInt(element.querySelector("#searchAssetResult .fn__flex-center").textContent.split("/")[1])) { - currentPage++; - assetInputEvent(element, localSearch, currentPage); - } - } - event.preventDefault(); - } - }); assetInputEvent(element, localSearch); const dragElement = element.querySelector(".search__drag"); diff --git a/app/src/search/index.ts b/app/src/search/index.ts index e1bcc779f..d75ef50b6 100644 --- a/app/src/search/index.ts +++ b/app/src/search/index.ts @@ -6,7 +6,7 @@ import {setPanelFocus} from "../layout/util"; import {App} from "../index"; export class Search extends Model { - private element: HTMLElement; + public element: HTMLElement; public config: ISearchOption; public edit: Protyle; diff --git a/app/src/search/spread.ts b/app/src/search/spread.ts index a11a2655f..796d2a84c 100644 --- a/app/src/search/spread.ts +++ b/app/src/search/spread.ts @@ -98,7 +98,7 @@ export const openSearch = async (options: { } }); dialog.element.setAttribute("data-key", options.hotkey); - const edit = genSearch(options.app, { + const config = { removed: localData.removed, k: options.key || localData.k, r: localData.r, @@ -110,8 +110,10 @@ export const openSearch = async (options: { sort: localData.sort, types: Object.assign({}, localData.types), page: options.key ? 1 : localData.page - }, dialog.element.querySelector(".b3-dialog__body"), () => { + } + const edit = genSearch(options.app, config, dialog.element.querySelector(".b3-dialog__body"), () => { dialog.destroy({focus: "false"}); }); dialog.editor = edit; + dialog.data = config; }; diff --git a/app/src/search/util.ts b/app/src/search/util.ts index b1033c992..6814360bf 100644 --- a/app/src/search/util.ts +++ b/app/src/search/util.ts @@ -25,10 +25,8 @@ import {unicode2Emoji} from "../emoji"; import {hasClosestByClassName} from "../protyle/util/hasClosest"; import {setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility"; import {newFileByName} from "../util/newFile"; -import {matchHotKey} from "../protyle/util/hotKey"; import {filterMenu, getKeyByLiElement, initCriteriaMenu, moreMenu, queryMenu, saveCriterion} from "./menu"; import {App} from "../index"; -import {upDownHint} from "../util/upDownHint"; import { assetFilterMenu, assetInputEvent, @@ -41,7 +39,7 @@ import { } from "./assets"; import {resize} from "../protyle/util/resize"; -const toggleReplaceHistory = (replaceHistoryElement: Element, historyElement: Element, replaceInputElement: HTMLInputElement) => { +export const toggleReplaceHistory = (replaceHistoryElement: Element, historyElement: Element, replaceInputElement: HTMLInputElement) => { if (replaceHistoryElement.classList.contains("fn__none")) { const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]; if (!list.replaceKeys || list.replaceKeys.length === 0) { @@ -64,7 +62,7 @@ const toggleReplaceHistory = (replaceHistoryElement: Element, historyElement: El historyElement.classList.add("fn__none"); }; -const toggleSearchHistory = (historyElement: Element, replaceHistoryElement: Element, searchInputElement: HTMLInputElement) => { +export const toggleSearchHistory = (historyElement: Element, replaceHistoryElement: Element, searchInputElement: HTMLInputElement) => { if (historyElement.classList.contains("fn__none")) { const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]; if (!list.keys || list.keys.length === 0) { @@ -256,7 +254,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo const replaceHistoryElement = element.querySelector("#replaceHistoryList"); const historyElement = element.querySelector("#searchHistoryList"); - const lineHeight = 28; const edit = new Protyle(app, element.querySelector("#searchPreview") as HTMLElement, { blockId: "", render: { @@ -291,7 +288,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } let clickTimeout: number; let lastClickTime = new Date().getTime(); - let inputTimeout: number; searchInputElement.value = config.k || ""; replaceInputElement.value = config.r || ""; @@ -383,7 +379,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (!target.getAttribute("disabled")) { if (config.page < parseInt(target.parentElement.querySelector("#searchResult").getAttribute("data-pagecount"))) { config.page++; - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputEvent(element, config, edit); } } event.stopPropagation(); @@ -393,7 +389,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (!target.getAttribute("disabled")) { if (config.page > 1) { config.page--; - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputEvent(element, config, edit); } } event.stopPropagation(); @@ -431,7 +427,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo config.page = 1; searchPathInputElement.innerHTML = config.hPath; searchPathInputElement.setAttribute("aria-label", ""); - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); + inputEvent(element, config, edit, true); const includeElement = element.querySelector("#searchInclude"); includeElement.classList.remove("b3-button--cancel"); includeElement.setAttribute("disabled", "disabled"); @@ -487,7 +483,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } else { includeElement.setAttribute("disabled", "disabled"); } - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); + inputEvent(element, config, edit, true); }); }, [], undefined, window.siyuan.languages.specifyPath); event.stopPropagation(); @@ -509,7 +505,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo }); } config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); + inputEvent(element, config, edit, true); event.stopPropagation(); event.preventDefault(); break; @@ -548,14 +544,14 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo event.preventDefault(); break; } else if (target.id === "searchRefresh") { - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputEvent(element, config, edit); event.stopPropagation(); event.preventDefault(); break; } else if (target.id === "searchMore") { moreMenu(config, criteriaData, element, () => { config.page = 1; - inputEvent(element, config, undefined, edit, true); + inputEvent(element, config, edit, true); }, () => { updateConfig(element, { removed: true, @@ -646,7 +642,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo window.siyuan.menus.menu.remove(); filterMenu(config, () => { config.page = 1; - inputEvent(element, config, undefined, edit, true); + inputEvent(element, config, edit, true); }); event.stopPropagation(); event.preventDefault(); @@ -699,7 +695,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo queryMenu(config, () => { element.querySelector("#searchSyntaxCheck").setAttribute("aria-label", getQueryTip(config.method)); config.page = 1; - inputEvent(element, config, undefined, edit, true); + inputEvent(element, config, edit, true); }); const rect = target.getBoundingClientRect(); window.siyuan.menus.menu.popup({x: rect.right, y: rect.bottom, isLeft: true}); @@ -747,7 +743,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (target.parentElement.id === "searchHistoryList") { searchInputElement.value = target.textContent; config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); + inputEvent(element, config, edit, true); } else if (target.parentElement.id === "searchAssetHistoryList") { searchAssetInputElement.value = target.textContent; assetInputEvent(assetsElement); @@ -857,14 +853,14 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (event.isComposing) { return; } - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); + inputEvent(element, config, edit, true); }); searchInputElement.addEventListener("input", (event: InputEvent) => { config.page = 1; if (event.isComposing) { return; } - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); + inputEvent(element, config, edit, true); }); searchInputElement.addEventListener("blur", () => { if (config.removed) { @@ -874,186 +870,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } saveKeyList("keys", searchInputElement.value); }); - searchInputElement.addEventListener("keydown", (event: KeyboardEvent) => { - let currentList: HTMLElement = searchPanelElement.querySelector(".b3-list-item--focus"); - if (!currentList || event.isComposing) { - return; - } - if (searchInputElement.value && matchHotKey(window.siyuan.config.keymap.editor.general.insertRight.custom, event)) { - const id = currentList.getAttribute("data-node-id"); - fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => { - openFileById({ - app, - id, - position: "right", - action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : - (id === currentList.getAttribute("data-root-id") ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ROOTSCROLL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT]), - zoomIn: foldResponse.data - }); - if (closeCB) { - closeCB(); - } - }); - event.preventDefault(); - event.stopPropagation(); - return; - } - if (searchInputElement.value && matchHotKey(window.siyuan.config.keymap.general.newFile.custom, event)) { - newFileByName(app, searchInputElement.value); - event.preventDefault(); - event.stopPropagation(); - return; - } - const focusIsNew = currentList.getAttribute("data-type") === "search-new"; - const isHistory = !historyElement.classList.contains("fn__none"); - if (event.key === "Enter") { - if (!isHistory) { - if (focusIsNew) { - newFileByName(app, searchInputElement.value); - } else { - const id = currentList.getAttribute("data-node-id"); - fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => { - openFileById({ - app, - id, - action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : - (id === currentList.getAttribute("data-root-id") ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ROOTSCROLL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT]), - zoomIn: foldResponse.data - }); - if (closeCB) { - closeCB(); - } - }); - } - } else { - searchInputElement.value = historyElement.querySelector(".b3-list-item--focus").textContent.trim(); - config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit, true); - toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); - } - event.preventDefault(); - } - if (event.key === "ArrowDown" && event.altKey) { - toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); - return; - } - if (isHistory) { - if (event.key === "Escape") { - toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); - } else { - upDownHint(historyElement, event); - } - event.stopPropagation(); - event.preventDefault(); - return; - } - if (focusIsNew && !isHistory) { - return; - } - if (event.key === "ArrowDown") { - currentList.classList.remove("b3-list-item--focus"); - if (!currentList.nextElementSibling) { - if (config.group === 1) { - if (currentList.parentElement.nextElementSibling) { - currentList.parentElement.nextElementSibling.nextElementSibling.firstElementChild.classList.add("b3-list-item--focus"); - } else { - searchPanelElement.children[1].firstElementChild.classList.add("b3-list-item--focus"); - } - } else { - searchPanelElement.firstElementChild.classList.add("b3-list-item--focus"); - } - } else { - currentList.nextElementSibling.classList.add("b3-list-item--focus"); - } - currentList = searchPanelElement.querySelector(".b3-list-item--focus"); - if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight || - searchPanelElement.scrollTop > currentList.offsetTop) { - searchPanelElement.scrollTop = currentList.offsetTop - searchPanelElement.clientHeight + lineHeight; - } - getArticle({ - id: currentList.getAttribute("data-node-id"), - config, - value: searchInputElement.value, - edit, - }); - event.preventDefault(); - } else if (event.key === "ArrowUp") { - currentList.classList.remove("b3-list-item--focus"); - if (!currentList.previousElementSibling) { - if (config.group === 1) { - if (currentList.parentElement.previousElementSibling.previousElementSibling) { - currentList.parentElement.previousElementSibling.previousElementSibling.lastElementChild.classList.add("b3-list-item--focus"); - } else { - searchPanelElement.lastElementChild.lastElementChild.classList.add("b3-list-item--focus"); - } - } else { - searchPanelElement.lastElementChild.classList.add("b3-list-item--focus"); - } - } else { - currentList.previousElementSibling.classList.add("b3-list-item--focus"); - } - currentList = searchPanelElement.querySelector(".b3-list-item--focus"); - if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight || - searchPanelElement.scrollTop > currentList.offsetTop - lineHeight * 2) { - searchPanelElement.scrollTop = currentList.offsetTop - lineHeight * 2; - } - getArticle({ - id: currentList.getAttribute("data-node-id"), - config, - value: searchInputElement.value, - edit, - }); - event.preventDefault(); - } else if (Constants.KEYCODELIST[event.keyCode] === "PageUp") { - const previousElement = element.querySelector('[data-type="previous"]'); - if (!previousElement.getAttribute("disabled")) { - if (config.page > 1) { - config.page--; - inputTimeout = inputEvent(element, config, inputTimeout, edit); - } - } - event.preventDefault(); - } else if (Constants.KEYCODELIST[event.keyCode] === "PageDown") { - const nextElement = element.querySelector('[data-type="next"]'); - if (!nextElement.getAttribute("disabled")) { - if (config.page < parseInt(nextElement.parentElement.querySelector("#searchResult").getAttribute("data-pagecount"))) { - config.page++; - inputTimeout = inputEvent(element, config, inputTimeout, edit); - } - } - event.preventDefault(); - } - }); - replaceInputElement.addEventListener("keydown", (event: KeyboardEvent) => { - if (event.isComposing) { - return; - } - const isHistory = !replaceHistoryElement.classList.contains("fn__none"); - if (event.key === "Enter") { - if (isHistory) { - replaceInputElement.value = replaceHistoryElement.querySelector(".b3-list-item--focus").textContent.trim(); - toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); - } else { - replace(element, config, edit, false); - } - event.preventDefault(); - } - if (event.key === "ArrowDown" && event.altKey) { - toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); - return; - } - if (isHistory) { - if (event.key === "Escape") { - toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); - } else { - upDownHint(replaceHistoryElement, event); - } - event.stopPropagation(); - event.preventDefault(); - return; - } - }); - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputEvent(element, config, edit); return edit; }; @@ -1132,7 +949,7 @@ const updateConfig = (element: Element, item: ISearchOption, config: ISearchOpti Object.assign(config, item); window.siyuan.storage[Constants.LOCAL_SEARCHDATA] = Object.assign({}, config); setStorageVal(Constants.LOCAL_SEARCHDATA, window.siyuan.storage[Constants.LOCAL_SEARCHDATA]); - inputEvent(element, config, undefined, edit); + inputEvent(element, config, edit); window.siyuan.menus.menu.remove(); }; @@ -1160,7 +977,7 @@ const renderNextSearchMark = (options: { } }; -const getArticle = (options: { +export const getArticle = (options: { id: string, config: ISearchOption, edit: Protyle @@ -1193,7 +1010,7 @@ const getArticle = (options: { }); }; -const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: boolean) => { +export const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: boolean) => { if (config.method === 1 || config.method === 2) { showMessage(window.siyuan.languages._kernel[132]); return; @@ -1278,7 +1095,8 @@ const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: }); }; -const inputEvent = (element: Element, config: ISearchOption, inputTimeout: number, edit: Protyle, rmCurrentCriteria = false) => { +export const inputEvent = (element: Element, config: ISearchOption, edit: Protyle, rmCurrentCriteria = false) => { + let inputTimeout = parseInt(element.getAttribute("data-timeout") || "0"); clearTimeout(inputTimeout); inputTimeout = window.setTimeout(() => { if (rmCurrentCriteria) { @@ -1338,10 +1156,10 @@ const inputEvent = (element: Element, config: ISearchOption, inputTimeout: numbe }); } }, Constants.TIMEOUT_INPUT); - return inputTimeout; + element.setAttribute("data-timeout", inputTimeout.toString()); }; -const getAttr =(block:IBlock) => { +const getAttr = (block: IBlock) => { let attrHTML = ""; if (block.name) { attrHTML += `${block.name}`;