Vanessa 2024-12-11 23:24:33 +08:00
parent a5363fa0b4
commit 5c87b0cd7f
9 changed files with 306 additions and 243 deletions

View file

@ -35,6 +35,7 @@
@import "business/resize";
@import "business/av";
@import "business/emojis";
@import "component/svg";
/*
.status: 2
@ -93,25 +94,6 @@ html {
}
}
.svg {
fill: currentColor;
display: inline-block;
stroke-width: 0;
stroke: currentColor;
width: 14px;
height: 14px;
flex-shrink: 0;
&--mid {
width: 16px;
height: 16px;
}
&--small {
width: 12px;
height: 12px;
}
}
.toolbar {
background-color: var(--b3-toolbar-background);

View file

@ -0,0 +1,24 @@
.svg {
fill: currentColor;
display: inline-block;
stroke-width: 0;
stroke: currentColor;
width: 14px;
height: 14px;
flex-shrink: 0;
&--mid {
width: 16px;
height: 16px;
}
&--small {
width: 12px;
height: 12px;
}
&--smaller {
width: 10px;
height: 10px;
}
}

View file

@ -28,6 +28,7 @@
@import "business/av";
@import "business/search";
@import "business/emojis";
@import "component/svg";
.block__popover {
width: 80vw;
@ -138,6 +139,15 @@
&:not(.toolbar__icon-deactivate):hover {
background-color: var(--b3-list-hover);
}
&--history {
height: 36px;
width: 36px;
display: flex;
justify-content: center;
align-items: center;
padding: 0;
}
}
&__title {
@ -152,10 +162,6 @@
color: var(--b3-theme-on-background);
}
&__search {
margin: 8px;
}
&__text {
@include text-clamp(1);
flex: 1;
@ -395,6 +401,7 @@
stroke: currentColor;
width: 14px;
height: 14px;
flex-shrink: 0;
&--mid {
width: 16px;
@ -405,6 +412,11 @@
width: 12px;
height: 12px;
}
&--smaller {
width: 10px;
height: 10px;
}
}
#empty {

View file

@ -10,13 +10,14 @@ 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 {getArticle, inputEvent, replace} from "../../search/util";
import {showFileInFolder} from "../../util/pathName";
import {assetInputEvent, renderPreview, toggleAssetHistory} from "../../search/assets";
import {assetInputEvent, renderPreview} from "../../search/assets";
import {initSearchMenu} from "../../menus/search";
import {writeText} from "../../protyle/util/compatibility";
import {checkFold} from "../../util/noRelyPCFunction";
import {getUnRefList} from "../../search/unRef";
import {toggleAssetHistory, toggleReplaceHistory, toggleSearchHistory} from "../../search/toggleHistory";
export const searchKeydown = (app: App, event: KeyboardEvent) => {
if (getSelection().rangeCount === 0) {
@ -72,7 +73,7 @@ export const searchKeydown = (app: App, event: KeyboardEvent) => {
toggleAssetHistory(assetsElement);
} else if (searchType === "doc") {
if (targetId === "replaceInput") {
toggleReplaceHistory(element);
toggleReplaceHistory(element.querySelector("#replaceInput"));
} else {
toggleSearchHistory(element, config, edit);
}

View file

@ -1,13 +1,19 @@
export const openModel = (obj: {
html: string,
icon: string,
icon?: string,
title: string,
bindEvent: (element: HTMLElement) => void
}) => {
const modelElement = document.getElementById("model");
modelElement.style.transform = "translateY(0px)";
modelElement.style.zIndex = (++window.siyuan.zIndex).toString();
modelElement.querySelector(".toolbar__icon use").setAttribute("xlink:href", "#" + obj.icon);
const iconElement = modelElement.querySelector(".toolbar__icon")
if(obj.icon) {
iconElement.classList.remove("fn__none")
iconElement.querySelector("use").setAttribute("xlink:href", "#" + obj.icon);
} else {
iconElement.classList.add("fn__none")
}
modelElement.querySelector(".toolbar__text").innerHTML = obj.title;
const modelMainElement = modelElement.querySelector("#modelMain") as HTMLElement;
modelMainElement.innerHTML = obj.html;

View file

@ -26,6 +26,7 @@ import {
import {addClearButton} from "../../util/addClearButton";
import {checkFold} from "../../util/noRelyPCFunction";
import {getDefaultType} from "../../search/getDefault";
import {toggleAssetHistory, toggleReplaceHistory, toggleSearchHistory} from "../../search/toggleHistory";
const replace = (element: Element, config: Config.IUILayoutTabSearchConfig, isAll: boolean) => {
if (config.method === 1 || config.method === 2) {
@ -313,7 +314,17 @@ const initSearchEvent = (app: App, element: Element, config: Config.IUILayoutTab
let target = event.target as HTMLElement;
while (target && !target.isSameNode(element)) {
const type = target.getAttribute("data-type");
if (type === "previous") {
if (type === "replaceHistory") {
toggleReplaceHistory(target.nextElementSibling as HTMLInputElement)
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "assetHistory") {
toggleAssetHistory(assetsElement)
event.stopPropagation();
event.preventDefault();
break;
} else if (type === "previous") {
if (!target.getAttribute("disabled")) {
config.page--;
updateSearchResult(config, element);
@ -663,13 +674,19 @@ export const popSearch = (app: App, searchConfig?: any) => {
openModel({
title: `<div class="fn__flex">
<span data-menu="true" class="toolbar__icon toolbar__icon--history" data-type="history">
<svg class="svg--mid"><use xlink:href="#iconSearch"></use></svg>
<svg class="svg--smaller"><use xlink:href="#iconDown"></use></svg>
</span>
<input id="toolbarSearch" placeholder="${window.siyuan.languages.showRecentUpdatedBlocks}" class="toolbar__title fn__block">
<svg id="toolbarSearchNew" class="toolbar__icon"><use xlink:href="#iconFile"></use></svg>
</div>`,
icon: "iconSearch",
html: `<div class="fn__flex-column" style="height: 100%">
<div class="toolbar toolbar--border${config.hasReplace ? "" : " fn__none"}">
<svg class="toolbar__icon"><use xlink:href="#iconReplace"></use></svg>
<span data-menu="true" class="toolbar__icon toolbar__icon--history" data-type="replaceHistory">
<svg class="svg--mid"><use xlink:href="#iconReplace"></use></svg>
<svg class="svg--smaller"><use xlink:href="#iconDown"></use></svg>
</span>
<input id="toolbarReplace" class="toolbar__title">
<svg class="fn__rotate fn__none toolbar__icon"><use xlink:href="#iconRefresh"></use></svg>
<div class="fn__space"></div>
@ -707,7 +724,10 @@ export const popSearch = (app: App, searchConfig?: any) => {
</div>
<div class="fn__none fn__flex-column" style="position: fixed;top: 0;width: 100%;background: var(--b3-theme-surface);height: 100%;" id="searchAssetsPanel">
<div class="toolbar toolbar--border">
<svg class="toolbar__icon"><use xlink:href="#iconSearch"></use></svg>
<span data-menu="true" class="toolbar__icon toolbar__icon--history" data-type="assetHistory">
<svg class="svg--mid"><use xlink:href="#iconSearch"></use></svg>
<svg class="svg--smaller"><use xlink:href="#iconDown"></use></svg>
</span>
<input id="searchAssetInput" placeholder="${window.siyuan.languages.keyword}" class="toolbar__title fn__block">
</div>
<div class="toolbar">
@ -750,6 +770,10 @@ export const popSearch = (app: App, searchConfig?: any) => {
document.querySelector("#toolbarSearchNew").addEventListener("click", () => {
newFileByName(app, (document.querySelector("#toolbarSearch") as HTMLInputElement).value);
});
const historyElement = document.querySelector('.toolbar [data-type="history"]')
historyElement.addEventListener("click", () => {
toggleSearchHistory(document.querySelector("#model"), config, undefined);
});
initSearchEvent(app, element.firstElementChild, config);
updateSearchResult(config, element);
}

View file

@ -242,75 +242,6 @@ export const assetInputEvent = (element: Element, localSearch?: ISearchAssetOpti
}, Constants.TIMEOUT_INPUT);
};
export const toggleAssetHistory = (assetElement: Element) => {
const keys = window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys;
if (!keys || keys.length === 0) {
return;
}
const menu = new Menu("search-asset-history");
if (menu.isOpen) {
return;
}
menu.element.classList.add("b3-menu--list");
menu.addItem({
iconHTML: "",
label: window.siyuan.languages.clearHistory,
click() {
window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = [];
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
}
});
const separatorElement = menu.addSeparator(1);
let current = true;
const assetInputElement = assetElement.querySelector("#searchAssetInput") as HTMLInputElement;
keys.forEach((s: string) => {
if (s !== assetInputElement.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")) {
keys.find((item: string, index: number) => {
if (item === s) {
keys.splice(index, 1);
return true;
}
});
window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = keys;
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
if (element.previousElementSibling?.classList.contains("b3-menu__separator") && !element.nextElementSibling) {
window.siyuan.menus.menu.remove();
} else {
element.remove();
}
} else {
assetInputElement.value = element.textContent;
assetInputEvent(assetElement);
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 = assetInputElement.getBoundingClientRect();
menu.open({
x: rect.left,
y: rect.bottom
});
};
export const renderPreview = (element: Element, id: string, query: string, queryMethod: number) => {
fetchPost("/api/search/getAssetContent", {id, query, queryMethod}, (response) => {
element.innerHTML = `<p style="white-space: pre-wrap;">${response.data.assetContent.content}</p>`;

View file

@ -0,0 +1,222 @@
import {Constants} from "../constants";
import {Menu} from "../plugin/Menu";
import {setStorageVal} from "../protyle/util/compatibility";
import {escapeHtml} from "../util/escape";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {Protyle} from "../protyle";
import {assetInputEvent} from "./assets";
/// #if MOBILE
import {updateSearchResult} from "../mobile/menu/search";
/// #else
import {inputEvent} from "./util";
/// #endif
export const toggleReplaceHistory = (replaceInputElement: HTMLInputElement) => {
const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS];
if (!list.replaceKeys || list.replaceKeys.length === 0) {
return;
}
const menu = new Menu("search-replace-history");
if (menu.isOpen) {
return;
}
menu.element.classList.add("b3-menu--list");
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;
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 = replaceInputElement.previousElementSibling.getBoundingClientRect();
menu.open({
x: rect.left,
y: rect.bottom
});
};
export const toggleSearchHistory = (searchElement: Element, config: Config.IUILayoutTabSearchConfig, edit: Protyle) => {
const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS];
if (!list.keys || list.keys.length === 0) {
return;
}
const menu = new Menu("search-history");
if (menu.isOpen) {
return;
}
menu.element.classList.add("b3-menu--list");
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, #toolbarSearch") 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;
/// #if MOBILE
updateSearchResult(config, searchElement, true);
/// #else
inputEvent(searchElement, config, edit, true);
/// #endif
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 = searchInputElement.previousElementSibling.getBoundingClientRect();
menu.open({
x: rect.left,
y: rect.bottom
});
};
export const toggleAssetHistory = (assetElement: Element) => {
const keys = window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys;
if (!keys || keys.length === 0) {
return;
}
const menu = new Menu("search-asset-history");
if (menu.isOpen) {
return;
}
menu.element.classList.add("b3-menu--list");
menu.addItem({
iconHTML: "",
label: window.siyuan.languages.clearHistory,
click() {
window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = [];
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
}
});
const separatorElement = menu.addSeparator(1);
let current = true;
const assetInputElement = assetElement.querySelector("#searchAssetInput") as HTMLInputElement;
keys.forEach((s: string) => {
if (s !== assetInputElement.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")) {
keys.find((item: string, index: number) => {
if (item === s) {
keys.splice(index, 1);
return true;
}
});
window.siyuan.storage[Constants.LOCAL_SEARCHASSET].keys = keys;
setStorageVal(Constants.LOCAL_SEARCHASSET, window.siyuan.storage[Constants.LOCAL_SEARCHASSET]);
if (element.previousElementSibling?.classList.contains("b3-menu__separator") && !element.nextElementSibling) {
window.siyuan.menus.menu.remove();
} else {
element.remove();
}
} else {
assetInputElement.value = element.textContent;
assetInputEvent(assetElement);
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 = assetInputElement.previousElementSibling.getBoundingClientRect();
menu.open({
x: rect.left,
y: rect.bottom
});
};

View file

@ -43,153 +43,14 @@ import {
openSearchAsset,
renderNextAssetMark,
renderPreview,
toggleAssetHistory
} from "./assets";
import {resize} from "../protyle/util/resize";
import {Menu} from "../plugin/Menu";
import {addClearButton} from "../util/addClearButton";
import {checkFold} from "../util/noRelyPCFunction";
import {getUnRefList, openSearchUnRef, unRefMoreMenu} from "./unRef";
import {getDefaultType} from "./getDefault";
import {isSupportCSSHL, searchMarkRender} from "../protyle/render/searchMarkRender";
export const toggleReplaceHistory = (searchElement: Element) => {
const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS];
if (!list.replaceKeys || list.replaceKeys.length === 0) {
return;
}
const menu = new Menu("search-replace-history");
if (menu.isOpen) {
return;
}
menu.element.classList.add("b3-menu--list");
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 = replaceInputElement.getBoundingClientRect();
menu.open({
x: rect.left,
y: rect.bottom
});
};
export const toggleSearchHistory = (searchElement: Element, config: Config.IUILayoutTabSearchConfig, edit: Protyle) => {
const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS];
if (!list.keys || list.keys.length === 0) {
return;
}
const menu = new Menu("search-history");
if (menu.isOpen) {
return;
}
menu.element.classList.add("b3-menu--list");
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 = searchInputElement.getBoundingClientRect();
menu.open({
x: rect.left,
y: rect.bottom
});
};
import {toggleAssetHistory, toggleReplaceHistory, toggleSearchHistory} from "./toggleHistory";
const saveKeyList = (type: "keys" | "replaceKeys", value: string) => {
let list: string[] = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS][type];
@ -296,7 +157,7 @@ export const genSearch = (app: App, config: Config.IUILayoutTabSearchConfig, ele
</div>
<div class="b3-form__icon search__header">
<div style="position: relative" class="fn__flex-1">
<span class="search__history-icon ariaLabel" id="searchHistoryBtn" aria-label="${updateHotkeyTip("")}">
<span class="search__history-icon 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>
@ -908,7 +769,7 @@ export const genSearch = (app: App, config: Config.IUILayoutTabSearchConfig, ele
event.preventDefault();
return;
} else if (target.id === "replaceHistoryBtn") {
toggleReplaceHistory(element);
toggleReplaceHistory(element.querySelector("#replaceInput"));
event.stopPropagation();
event.preventDefault();
return;