diff --git a/app/src/boot/globalEvent/searchKeydown.ts b/app/src/boot/globalEvent/searchKeydown.ts index 34b64da79..4d89b1a1b 100644 --- a/app/src/boot/globalEvent/searchKeydown.ts +++ b/app/src/boot/globalEvent/searchKeydown.ts @@ -6,7 +6,6 @@ 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"; @@ -64,71 +63,24 @@ export const searchKeydown = (app: App, event: KeyboardEvent) => { 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); + toggleReplaceHistory(element); } else { - toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); + toggleSearchHistory(element, config, edit); } } 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 (!window.siyuan.menus.menu.element.classList.contains("fn__none")) { + // 不能返回 true,否则历史菜单无法使用快捷键 + return false; } if (currentList.getAttribute("data-type") === "search-new") { if (event.key === "Enter") { @@ -268,6 +220,7 @@ export const searchKeydown = (app: App, event: KeyboardEvent) => { return true; } const lineHeight = 28; + const assetPreviewElement = assetsElement.querySelector("#searchAssetPreview"); if (event.key === "ArrowDown") { currentList.classList.remove("b3-list-item--focus"); if (!currentList.nextElementSibling) { diff --git a/app/src/menus/Menu.ts b/app/src/menus/Menu.ts index 150295980..677f4a1d0 100644 --- a/app/src/menus/Menu.ts +++ b/app/src/menus/Menu.ts @@ -84,7 +84,7 @@ export class Menu { } public addSeparator(index?: number) { - this.addItem({type: "separator", index}); + return this.addItem({type: "separator", index}); } public addItem(option: IMenu) { diff --git a/app/src/mobile/util/keyboardToolbar.ts b/app/src/mobile/util/keyboardToolbar.ts index 0ea1d59e7..e9298706f 100644 --- a/app/src/mobile/util/keyboardToolbar.ts +++ b/app/src/mobile/util/keyboardToolbar.ts @@ -12,7 +12,6 @@ import {getCurrentEditor} from "../editor"; import {fontEvent, getFontNodeElements} from "../../protyle/toolbar/Font"; import {hideElements} from "../../protyle/ui/hideElements"; import {input} from "../../protyle/wysiwyg/input"; -import {showMessage} from "../../dialog/message"; let renderKeyboardToolbarTimeout: number; let showUtil = false; diff --git a/app/src/plugin/Menu.ts b/app/src/plugin/Menu.ts index e6744ad69..2d00739cb 100644 --- a/app/src/plugin/Menu.ts +++ b/app/src/plugin/Menu.ts @@ -38,7 +38,7 @@ export class Menu { if (this.isOpen) { return; } - this.menu.addSeparator(index); + return this.menu.addSeparator(index); } open(options:IPosition) { diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index a368fcf0c..a97fd46a9 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -98,7 +98,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle event.stopPropagation(); return true; } else if (type === "av-add") { - addView(protyle, blockElement) + addView(protyle, blockElement); event.preventDefault(); event.stopPropagation(); return true; diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index 49c1d749e..0a3e77301 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -231,11 +231,11 @@ export const openMenuPanel = (options: { previousID: sourceElement.previousElementSibling?.getAttribute("data-id") }]); if (isTop) { - targetElement.before(sourceElement) - targetElement.classList.remove("dragover__top") + targetElement.before(sourceElement); + targetElement.classList.remove("dragover__top"); } else { - targetElement.after(sourceElement) - targetElement.classList.remove("dragover__bottom") + targetElement.after(sourceElement); + targetElement.classList.remove("dragover__bottom"); } return; } @@ -953,8 +953,8 @@ export const openMenuPanel = (options: { blockElement: options.blockElement as HTMLElement, element: target.parentElement }); - avPanelElement.querySelector(".b3-chip--primary").classList.remove("b3-chip--primary") - target.parentElement.querySelector(".b3-chip").classList.add("b3-chip--primary") + avPanelElement.querySelector(".b3-chip--primary").classList.remove("b3-chip--primary"); + target.parentElement.querySelector(".b3-chip").classList.add("b3-chip--primary"); }, target.parentElement.dataset.id); } event.preventDefault(); diff --git a/app/src/protyle/render/av/view.ts b/app/src/protyle/render/av/view.ts index dd9ac01b5..1c9107542 100644 --- a/app/src/protyle/render/av/view.ts +++ b/app/src/protyle/render/av/view.ts @@ -153,7 +153,7 @@ export const getViewHTML = (data: IAVTable) => { }; export const getSwitcherHTML = (views: IAVView[], viewId: string) => { - let html = "" + let html = ""; views.forEach((item) => { html += ` ${html} -` -} +`; +}; export const addView = (protyle: IProtyle, blockElement: Element) => { const id = Lute.NewNodeID(); @@ -188,4 +188,4 @@ export const addView = (protyle: IProtyle, blockElement: Element) => { avID, id }]); -} +}; diff --git a/app/src/search/util.ts b/app/src/search/util.ts index 74332bf31..c0536a2d2 100644 --- a/app/src/search/util.ts +++ b/app/src/search/util.ts @@ -38,51 +38,142 @@ import { toggleAssetHistory } from "./assets"; import {resize} from "../protyle/util/resize"; +import {Menu} from "../plugin/Menu"; -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) { - return; - } - let html = ""; - list.replaceKeys.forEach((s: string) => { - if (s !== replaceInputElement.value && s) { - html += `
${escapeHtml(s)}
`; - } - }); - if (html === "") { - return; - } - replaceHistoryElement.classList.remove("fn__none"); - replaceHistoryElement.innerHTML = html; - } else { - replaceHistoryElement.classList.add("fn__none"); +export const toggleReplaceHistory = (searchElement: Element) => { + const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]; + if (!list.replaceKeys || list.replaceKeys.length === 0) { + return; } - historyElement.classList.add("fn__none"); + const menu = new Menu("search-replace-history"); + if (menu.isOpen) { + return; + } + menu.addItem({ + iconHTML: "", + label: window.siyuan.languages.clearHistory, + click() { + window.siyuan.storage[Constants.LOCAL_SEARCHKEYS].replaceKeys = []; + setStorageVal(Constants.LOCAL_SEARCHKEYS, window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]); + } + }); + const separatorElement = menu.addSeparator(1); + let current = true; + const replaceInputElement = searchElement.querySelector("#replaceInput") as HTMLInputElement; + list.replaceKeys.forEach((s: string) => { + if (s !== replaceInputElement.value && s) { + const menuItem = menu.addItem({ + iconHTML: "", + label: escapeHtml(s), + action: "iconCloseRound", + bind(element) { + element.addEventListener("click", (itemEvent) => { + if (hasClosestByClassName(itemEvent.target as Element, "b3-menu__action")) { + list.replaceKeys.find((item: string, index: number) => { + if (item === s) { + list.replaceKeys.splice(index, 1); + return true; + } + }); + window.siyuan.storage[Constants.LOCAL_SEARCHKEYS].replaceKeys = list.replaceKeys; + setStorageVal(Constants.LOCAL_SEARCHKEYS, window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]); + if (element.previousElementSibling?.classList.contains("b3-menu__separator") && !element.nextElementSibling) { + window.siyuan.menus.menu.remove(); + } else { + element.remove(); + } + } else { + replaceInputElement.value = element.textContent; + window.siyuan.menus.menu.remove(); + } + itemEvent.preventDefault(); + itemEvent.stopPropagation(); + }); + } + }); + if (current) { + menuItem.classList.add("b3-menu__item--current"); + } + current = false; + } + }); + if (current) { + separatorElement.remove(); + } + const rect = searchElement.querySelector("#replaceHistoryBtn").getBoundingClientRect(); + menu.open({ + x: rect.left, + y: rect.bottom + }); }; -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) { - return; - } - let html = ""; - list.keys.forEach((s: string) => { - if (s !== searchInputElement.value && s) { - html += `
${escapeHtml(s)}
`; - } - }); - if (html === "") { - return; - } - historyElement.classList.remove("fn__none"); - historyElement.innerHTML = html; - } else { - historyElement.classList.add("fn__none"); +export const toggleSearchHistory = (searchElement: Element, config: ISearchOption, edit: Protyle) => { + const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]; + if (!list.keys || list.keys.length === 0) { + return; } - replaceHistoryElement.classList.add("fn__none"); + const menu = new Menu("search-history"); + if (menu.isOpen) { + return; + } + menu.addItem({ + iconHTML: "", + label: window.siyuan.languages.clearHistory, + click() { + window.siyuan.storage[Constants.LOCAL_SEARCHKEYS].keys = []; + setStorageVal(Constants.LOCAL_SEARCHKEYS, window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]); + } + }); + const separatorElement = menu.addSeparator(1); + let current = true; + const searchInputElement = searchElement.querySelector("#searchInput") as HTMLInputElement; + list.keys.forEach((s: string) => { + if (s !== searchInputElement.value && s) { + const menuItem = menu.addItem({ + iconHTML: "", + label: escapeHtml(s), + action: "iconCloseRound", + bind(element) { + element.addEventListener("click", (itemEvent) => { + if (hasClosestByClassName(itemEvent.target as Element, "b3-menu__action")) { + list.keys.find((item: string, index: number) => { + if (item === s) { + list.keys.splice(index, 1); + return true; + } + }); + window.siyuan.storage[Constants.LOCAL_SEARCHKEYS].keys = list.keys; + setStorageVal(Constants.LOCAL_SEARCHKEYS, window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]); + if (element.previousElementSibling?.classList.contains("b3-menu__separator") && !element.nextElementSibling) { + window.siyuan.menus.menu.remove(); + } else { + element.remove(); + } + } else { + searchInputElement.value = element.textContent; + config.page = 1; + inputEvent(searchElement, config, edit, true); + window.siyuan.menus.menu.remove(); + } + itemEvent.preventDefault(); + itemEvent.stopPropagation(); + }); + } + }); + if (current) { + menuItem.classList.add("b3-menu__item--current"); + } + current = false; + } + }); + if (current) { + separatorElement.remove(); + } + const rect = searchElement.querySelector("#searchHistoryBtn").getBoundingClientRect(); + menu.open({ + x: rect.left, + y: rect.bottom + }); }; const saveKeyList = (type: "keys" | "replaceKeys", value: string) => { @@ -183,12 +274,11 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
- + -
@@ -218,7 +308,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
- + @@ -228,7 +318,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
-
@@ -253,8 +342,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo const searchPanelElement = element.querySelector("#searchList"); const searchInputElement = element.querySelector("#searchInput") as HTMLInputElement; const replaceInputElement = element.querySelector("#replaceInput") as HTMLInputElement; - const replaceHistoryElement = element.querySelector("#replaceHistoryList"); - const historyElement = element.querySelector("#searchHistoryList"); const edit = new Protyle(app, element.querySelector("#searchPreview") as HTMLElement, { blockId: "", @@ -706,7 +793,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo event.preventDefault(); break; } else if (target.id === "searchHistoryBtn") { - toggleSearchHistory(historyElement, replaceHistoryElement, searchInputElement); + toggleSearchHistory(element, config, edit); event.stopPropagation(); event.preventDefault(); return; @@ -716,7 +803,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo event.preventDefault(); return; } else if (target.id === "replaceHistoryBtn") { - toggleReplaceHistory(replaceHistoryElement, historyElement, replaceInputElement); + toggleReplaceHistory(element); event.stopPropagation(); event.preventDefault(); return; @@ -743,16 +830,9 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo break; } else if (target.classList.contains("b3-list-item")) { const searchAssetInputElement = element.querySelector("#searchAssetInput") as HTMLInputElement; - if (target.parentElement.id === "searchHistoryList") { - searchInputElement.value = target.textContent; - config.page = 1; - inputEvent(element, config, edit, true); - } else if (target.parentElement.id === "searchAssetHistoryList") { + if (target.parentElement.id === "searchAssetHistoryList") { searchAssetInputElement.value = target.textContent; assetInputEvent(assetsElement); - } else if (target.parentElement.id === "replaceHistoryList") { - replaceInputElement.value = target.textContent; - replaceHistoryElement.classList.add("fn__none"); } else if (type === "search-new") { newFileByName(app, searchInputElement.value); } else if (type === "search-item") { @@ -846,8 +926,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } target = target.parentElement; } - historyElement.classList.add("fn__none"); - replaceHistoryElement.classList.add("fn__none"); element.querySelector("#searchAssetHistoryList")?.classList.add("fn__none"); }, false);