mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 17:40:13 +01:00
This commit is contained in:
parent
6d72ce0e18
commit
14b22d6bf8
8 changed files with 155 additions and 125 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export class Menu {
|
|||
if (this.isOpen) {
|
||||
return;
|
||||
}
|
||||
this.menu.addSeparator(index);
|
||||
return this.menu.addSeparator(index);
|
||||
}
|
||||
|
||||
open(options:IPosition) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ export const getViewHTML = (data: IAVTable) => {
|
|||
};
|
||||
|
||||
export const getSwitcherHTML = (views: IAVView[], viewId: string) => {
|
||||
let html = ""
|
||||
let html = "";
|
||||
views.forEach((item) => {
|
||||
html += `<button draggable="true" class="b3-menu__item" data-id="${item.id}">
|
||||
<svg class="b3-menu__icon"><use xlink:href="#iconDrag"></use></svg>
|
||||
|
|
@ -173,8 +173,8 @@ export const getSwitcherHTML = (views: IAVView[], viewId: string) => {
|
|||
</button>
|
||||
<button class="b3-menu__separator"></button>
|
||||
${html}
|
||||
</div>`
|
||||
}
|
||||
</div>`;
|
||||
};
|
||||
|
||||
export const addView = (protyle: IProtyle, blockElement: Element) => {
|
||||
const id = Lute.NewNodeID();
|
||||
|
|
@ -188,4 +188,4 @@ export const addView = (protyle: IProtyle, blockElement: Element) => {
|
|||
avID,
|
||||
id
|
||||
}]);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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")) {
|
||||
export const toggleReplaceHistory = (searchElement: Element) => {
|
||||
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 += `<div class="b3-list-item${html ? "" : " b3-list-item--focus"}">${escapeHtml(s)}</div>`;
|
||||
}
|
||||
});
|
||||
if (html === "") {
|
||||
const menu = new Menu("search-replace-history");
|
||||
if (menu.isOpen) {
|
||||
return;
|
||||
}
|
||||
replaceHistoryElement.classList.remove("fn__none");
|
||||
replaceHistoryElement.innerHTML = html;
|
||||
} else {
|
||||
replaceHistoryElement.classList.add("fn__none");
|
||||
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]);
|
||||
}
|
||||
historyElement.classList.add("fn__none");
|
||||
});
|
||||
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")) {
|
||||
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;
|
||||
}
|
||||
let html = "";
|
||||
list.keys.forEach((s: string) => {
|
||||
if (s !== searchInputElement.value && s) {
|
||||
html += `<div class="b3-list-item${html ? "" : " b3-list-item--focus"}">${escapeHtml(s)}</div>`;
|
||||
}
|
||||
});
|
||||
if (html === "") {
|
||||
const menu = new Menu("search-history");
|
||||
if (menu.isOpen) {
|
||||
return;
|
||||
}
|
||||
historyElement.classList.remove("fn__none");
|
||||
historyElement.innerHTML = html;
|
||||
} else {
|
||||
historyElement.classList.add("fn__none");
|
||||
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]);
|
||||
}
|
||||
replaceHistoryElement.classList.add("fn__none");
|
||||
});
|
||||
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
|
|||
</span>
|
||||
</div>
|
||||
<div class="b3-form__icon search__header">
|
||||
<span class="fn__a" id="searchHistoryBtn">
|
||||
<span class="fn__a ariaLabel" id="searchHistoryBtn" aria-label="${updateHotkeyTip("⌥↓")}">
|
||||
<svg data-menu="true" class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
|
||||
<svg class="search__arrowdown"><use xlink:href="#iconDown"></use></svg>
|
||||
</span>
|
||||
<input id="searchInput" style="padding-right: 60px" class="b3-text-field b3-text-field--text" placeholder="${window.siyuan.languages.showRecentUpdatedBlocks}">
|
||||
<div id="searchHistoryList" data-close="false" class="fn__none b3-menu b3-list b3-list--background"></div>
|
||||
<div class="block__icons">
|
||||
<span id="searchRefresh" aria-label="${window.siyuan.languages.refresh}" class="block__icon ariaLabel" data-position="9bottom">
|
||||
<svg><use xlink:href="#iconRefresh"></use></svg>
|
||||
|
|
@ -218,7 +308,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
|
|||
</div>
|
||||
</div>
|
||||
<div class="b3-form__icon search__header${config.hasReplace ? "" : " fn__none"}">
|
||||
<span class="fn__a" id="replaceHistoryBtn">
|
||||
<span class="fn__a ariaLabel" id="replaceHistoryBtn" aria-label="${updateHotkeyTip("⌥↓")}">
|
||||
<svg data-menu="true" class="b3-form__icon-icon"><use xlink:href="#iconReplace"></use></svg>
|
||||
<svg class="search__arrowdown"><use xlink:href="#iconDown"></use></svg>
|
||||
</span>
|
||||
|
|
@ -228,7 +318,6 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
|
|||
<div class="fn__space"></div>
|
||||
<button id="replaceBtn" class="b3-button b3-button--small b3-button--outline fn__flex-center">↵ ${window.siyuan.languages.replace}</button>
|
||||
<div class="fn__space"></div>
|
||||
<div id="replaceHistoryList" data-close="false" class="fn__none b3-menu b3-list b3-list--background"></div>
|
||||
</div>
|
||||
<div id="criteria" class="search__header"></div>
|
||||
<div class="search__layout${(closeCB ? data.layout === 1 : data.layoutTab === 1) ? " search__layout--row" : ""}">
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue