Fix type errors related to siyuan.config (#10724)

* 🎨 Improve the type definition of `siyuan.config`

* 🐛 Fix type errors related to `siyuan.config`

* 💄 `types/config.d.ts`

* 🐛 Fix type errors related to `siyuan.config`
This commit is contained in:
Yingyi / 颖逸 2024-03-25 09:33:22 +08:00 committed by GitHub
parent 433c0b6dde
commit 6b2ac5e630
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 692 additions and 306 deletions

View file

@ -30,7 +30,7 @@ export const searchKeydown = (app: App, event: KeyboardEvent) => {
let dialog: Dialog; let dialog: Dialog;
let edit; let edit;
let unRefEdit; let unRefEdit;
let config: ISearchOption; let config: Config.IUILayoutTabSearchConfig;
window.siyuan.dialogs.find((item) => { window.siyuan.dialogs.find((item) => {
if (item.element.contains(range.startContainer) && item.element.querySelector("#searchList")) { if (item.element.contains(range.startContainer) && item.element.querySelector("#searchList")) {
element = item.element.querySelector(".b3-dialog__body"); element = item.element.querySelector(".b3-dialog__body");

View file

@ -29,10 +29,10 @@ import {sendGlobalShortcut} from "./globalEvent/keydown";
import {closeWindow} from "../window/closeWin"; import {closeWindow} from "../window/closeWin";
import {checkFold} from "../util/noRelyPCFunction"; import {checkFold} from "../util/noRelyPCFunction";
const matchKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => { const matchKeymap = (keymap: Config.IKeys, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
if (key1 === "general") { if (key1 === "general") {
if (!window.siyuan.config.keymap[key1]) { if (!window.siyuan.config.keymap[key1]) {
window.siyuan.config.keymap[key1] = keymap; window.siyuan.config.keymap[key1] = keymap as Config.IKeymapGeneral;
return false; return false;
} }
} else { } else {
@ -41,7 +41,7 @@ const matchKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "edi
return false; return false;
} }
if (!window.siyuan.config.keymap[key1][key2]) { if (!window.siyuan.config.keymap[key1][key2]) {
window.siyuan.config.keymap[key1][key2] = keymap; (window.siyuan.config.keymap[key1][key2] as Config.IKeymapEditor[typeof key2]) = keymap as Config.IKeymapEditor[typeof key2];
return false; return false;
} }
} }

View file

@ -354,7 +354,7 @@ export const about = {
}); });
/// #endif /// #endif
about.element.querySelector("#aboutConfirm").addEventListener("click", () => { about.element.querySelector("#aboutConfirm").addEventListener("click", () => {
const scheme = (about.element.querySelector("#aboutScheme") as HTMLInputElement).value; const scheme = (about.element.querySelector("#aboutScheme") as HTMLInputElement).value as Config.TSystemNetworkProxyScheme;
const host = (about.element.querySelector("#aboutHost") as HTMLInputElement).value; const host = (about.element.querySelector("#aboutHost") as HTMLInputElement).value;
const port = (about.element.querySelector("#aboutPort") as HTMLInputElement).value; const port = (about.element.querySelector("#aboutPort") as HTMLInputElement).value;
fetchPost("/api/system/setNetworkProxy", {scheme, host, port}, async () => { fetchPost("/api/system/setNetworkProxy", {scheme, host, port}, async () => {

View file

@ -12,7 +12,7 @@ import {sendGlobalShortcut} from "../boot/globalEvent/keydown";
export const keymap = { export const keymap = {
element: undefined as Element, element: undefined as Element,
_genItem(keymap: Record<string, IKeymapItem>, keys: string) { _genItem(keymap: Record<string, Config.IKey>, keys: string) {
let html = ""; let html = "";
Object.keys(keymap).forEach(key => { Object.keys(keymap).forEach(key => {
if (window.siyuan.languages[key]) { if (window.siyuan.languages[key]) {

View file

@ -451,7 +451,7 @@ export abstract class Constants {
plugin: {}, plugin: {},
}; };
public static readonly SIYUAN_EMPTY_LAYOUT: Record<string, unknown> = { public static readonly SIYUAN_EMPTY_LAYOUT: Config.IUiLayout = {
hideDock: false, hideDock: false,
layout: { layout: {
"direction": "tb", "direction": "tb",
@ -482,7 +482,14 @@ export abstract class Constants {
"size": "auto", "size": "auto",
"type": "center", "type": "center",
"instance": "Layout", "instance": "Layout",
"children": [{"instance": "Wnd", "children": [{"instance": "Tab", "children": []}]}] "children": [{
"instance": "Wnd",
"children": [],
// "children": [{
// "instance": "Tab",
// "children": []
// }]
}]
}, { }, {
"direction": "tb", "direction": "tb",
"size": "0px", "size": "0px",
@ -580,9 +587,7 @@ export abstract class Constants {
} }
}; };
public static readonly SIYUAN_DEFAULT_REPLACETYPES: { public static readonly SIYUAN_DEFAULT_REPLACETYPES: Required<Config.IUILayoutTabSearchConfigReplaceTypes> = {
[key: string]: boolean;
} = {
"text": true, "text": true,
"imgText": true, "imgText": true,
"imgTitle": true, "imgTitle": true,

View file

@ -47,9 +47,9 @@ export class Wnd {
public element: HTMLElement; public element: HTMLElement;
public headersElement: HTMLElement; public headersElement: HTMLElement;
public children: Tab[] = []; public children: Tab[] = [];
public resize?: TDirection; public resize?: Config.TUILayoutDirection;
constructor(app: App, resize?: TDirection, parentType?: TLayout) { constructor(app: App, resize?: Config.TUILayoutDirection, parentType?: Config.TUILayoutType) {
this.id = genUUID(); this.id = genUUID();
this.app = app; this.app = app;
this.resize = resize; this.resize = resize;
@ -896,7 +896,7 @@ export class Wnd {
/// #endif /// #endif
} }
public split(direction: TDirection) { public split(direction: Config.TUILayoutDirection) {
if (this.children.length === 1 && !this.children[0].headElement) { if (this.children.length === 1 && !this.children[0].headElement) {
// 场景:没有打开的文档,点击标签面板打开 // 场景:没有打开的文档,点击标签面板打开
return this; return this;

View file

@ -35,7 +35,7 @@ export class Dock {
app: App, app: App,
data: { data: {
pin: boolean, pin: boolean,
data: IDockTab[][] data: Config.IUILayoutDockTab[][]
}, },
position: TDockPosition position: TDockPosition
}) { }) {
@ -679,7 +679,7 @@ export class Dock {
return max; return max;
} }
public genButton(data: IDockTab[], index: number, tabIndex?: number) { public genButton(data: Config.IUILayoutDockTab[], index: number, tabIndex?: number) {
let html = ""; let html = "";
data.forEach(item => { data.forEach(item => {
if (typeof tabIndex === "undefined" && !TYPES.includes(item.type)) { if (typeof tabIndex === "undefined" && !TYPES.includes(item.type)) {

View file

@ -131,19 +131,19 @@ export const getAllTabs = () => {
}; };
export const getAllDocks = () => { export const getAllDocks = () => {
const docks: IDockTab[] = []; const docks: Config.IUILayoutDockTab[] = [];
window.siyuan.config.uiLayout.left.data.forEach((item: IDockTab[]) => { window.siyuan.config.uiLayout.left.data.forEach((item) => {
item.forEach((dock: IDockTab) => { item.forEach((dock) => {
docks.push(dock); docks.push(dock);
}); });
}); });
window.siyuan.config.uiLayout.right.data.forEach((item: IDockTab[]) => { window.siyuan.config.uiLayout.right.data.forEach((item) => {
item.forEach((dock: IDockTab) => { item.forEach((dock) => {
docks.push(dock); docks.push(dock);
}); });
}); });
window.siyuan.config.uiLayout.bottom.data.forEach((item: IDockTab[]) => { window.siyuan.config.uiLayout.bottom.data.forEach((item) => {
item.forEach((dock: IDockTab) => { item.forEach((dock) => {
docks.push(dock); docks.push(dock);
}); });
}); });

View file

@ -11,14 +11,14 @@ export class Layout {
public element: HTMLElement; public element: HTMLElement;
public children?: Array<Layout | Wnd>; public children?: Array<Layout | Wnd>;
public parent?: Layout; public parent?: Layout;
public direction: TDirection; public direction: Config.TUILayoutDirection;
public type?: TLayout; public type?: Config.TUILayoutType;
public id?: string; public id?: string;
public resize?: TDirection; public resize?: Config.TUILayoutDirection;
public size?: string; public size?: string;
constructor(options?: ILayoutOptions) { constructor(options?: ILayoutOptions) {
const mergedOptions = Object.assign({ const mergedOptions: ILayoutOptions = Object.assign({
direction: "tb", direction: "tb",
size: "auto", size: "auto",
type: "normal" type: "normal"

View file

@ -1,39 +1,39 @@
import {Layout} from "./index"; import { Layout } from "./index";
import {Wnd} from "./Wnd"; import { Wnd } from "./Wnd";
import {Tab} from "./Tab"; import { Tab } from "./Tab";
import {Model} from "./Model"; import { Model } from "./Model";
import {Graph} from "./dock/Graph"; import { Graph } from "./dock/Graph";
import {Editor} from "../editor"; import { Editor } from "../editor";
import {Files} from "./dock/Files"; import { Files } from "./dock/Files";
import {Outline} from "./dock/Outline"; import { Outline } from "./dock/Outline";
import {Bookmark} from "./dock/Bookmark"; import { Bookmark } from "./dock/Bookmark";
import {Tag} from "./dock/Tag"; import { Tag } from "./dock/Tag";
import {getAllModels, getAllTabs} from "./getAll"; import { getAllModels, getAllTabs } from "./getAll";
import {Asset} from "../asset"; import { Asset } from "../asset";
import {Search} from "../search"; import { Search } from "../search";
import {Dock} from "./dock"; import { Dock } from "./dock";
import {focusByOffset, focusByRange, getSelectionOffset} from "../protyle/util/selection"; import { focusByOffset, focusByRange, getSelectionOffset } from "../protyle/util/selection";
import {hideElements} from "../protyle/ui/hideElements"; import { hideElements } from "../protyle/ui/hideElements";
import {fetchPost} from "../util/fetch"; import { fetchPost } from "../util/fetch";
import {hasClosestBlock, hasClosestByClassName} from "../protyle/util/hasClosest"; import { hasClosestBlock, hasClosestByClassName } from "../protyle/util/hasClosest";
import {getContenteditableElement} from "../protyle/wysiwyg/getBlock"; import { getContenteditableElement } from "../protyle/wysiwyg/getBlock";
import {Constants} from "../constants"; import { Constants } from "../constants";
import {saveScroll} from "../protyle/scroll/saveScroll"; import { saveScroll } from "../protyle/scroll/saveScroll";
import {Backlink} from "./dock/Backlink"; import { Backlink } from "./dock/Backlink";
import {openFileById} from "../editor/util"; import { openFileById } from "../editor/util";
import {isWindow} from "../util/functions"; import { isWindow } from "../util/functions";
/// #if !BROWSER /// #if !BROWSER
import {setTabPosition} from "../window/setHeader"; import { setTabPosition } from "../window/setHeader";
/// #endif /// #endif
import {showMessage} from "../dialog/message"; import { showMessage } from "../dialog/message";
import {getIdZoomInByPath} from "../util/pathName"; import { getIdZoomInByPath } from "../util/pathName";
import {Custom} from "./dock/Custom"; import { Custom } from "./dock/Custom";
import {newCardModel} from "../card/newCardTab"; import { newCardModel } from "../card/newCardTab";
import {App} from "../index"; import { App } from "../index";
import {afterLoadPlugin} from "../plugin/loader"; import { afterLoadPlugin } from "../plugin/loader";
import {setTitle} from "../dialog/processSystem"; import { setTitle } from "../dialog/processSystem";
import {newCenterEmptyTab, resizeTabs} from "./tabUtil"; import { newCenterEmptyTab, resizeTabs } from "./tabUtil";
import {setStorageVal} from "../protyle/util/compatibility"; import { setStorageVal } from "../protyle/util/compatibility";
export const setPanelFocus = (element: Element) => { export const setPanelFocus = (element: Element) => {
if (element.getAttribute("data-type") === "wnd") { if (element.getAttribute("data-type") === "wnd") {
@ -136,7 +136,7 @@ export const getWndByLayout: (layout: Layout) => Wnd = (layout: Layout) => {
const dockToJSON = (dock: Dock) => { const dockToJSON = (dock: Dock) => {
const json = []; const json = [];
const subDockToJSON = (index: number) => { const subDockToJSON = (index: number) => {
const data: IDockTab[] = []; const data: Config.IUILayoutDockTab[] = [];
dock.element.querySelectorAll(`span[data-index="${index}"]`).forEach(item => { dock.element.querySelectorAll(`span[data-index="${index}"]`).forEach(item => {
data.push({ data.push({
type: item.getAttribute("data-type"), type: item.getAttribute("data-type"),
@ -169,7 +169,7 @@ const dockToJSON = (dock: Dock) => {
}; };
export const resetLayout = () => { export const resetLayout = () => {
fetchPost("/api/system/setUILayout", {layout: {}}, () => { fetchPost("/api/system/setUILayout", { layout: {} }, () => {
window.siyuan.storage[Constants.LOCAL_FILEPOSITION] = {}; window.siyuan.storage[Constants.LOCAL_FILEPOSITION] = {};
setStorageVal(Constants.LOCAL_FILEPOSITION, window.siyuan.storage[Constants.LOCAL_FILEPOSITION]); setStorageVal(Constants.LOCAL_FILEPOSITION, window.siyuan.storage[Constants.LOCAL_FILEPOSITION]);
window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION] = {}; window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION] = {};
@ -270,7 +270,7 @@ export const getAllLayout = () => {
return layoutJSON; return layoutJSON;
}; };
const initInternalDock = (dockItem: IDockTab[]) => { const initInternalDock = (dockItem: Config.IUILayoutDockTab[]) => {
dockItem.forEach((existSubItem) => { dockItem.forEach((existSubItem) => {
if (existSubItem.hotkeyLangId) { if (existSubItem.hotkeyLangId) {
existSubItem.title = window.siyuan.languages[existSubItem.hotkeyLangId]; existSubItem.title = window.siyuan.languages[existSubItem.hotkeyLangId];
@ -280,22 +280,26 @@ const initInternalDock = (dockItem: IDockTab[]) => {
}; };
const JSONToDock = (json: any, app: App) => { const JSONToDock = (json: any, app: App) => {
json.left.data.forEach((existItem: IDockTab[]) => { json.left.data.forEach((existItem: Config.IUILayoutDockTab[]) => {
initInternalDock(existItem); initInternalDock(existItem);
}); });
json.right.data.forEach((existItem: IDockTab[]) => { json.right.data.forEach((existItem: Config.IUILayoutDockTab[]) => {
initInternalDock(existItem); initInternalDock(existItem);
}); });
json.bottom.data.forEach((existItem: IDockTab[]) => { json.bottom.data.forEach((existItem: Config.IUILayoutDockTab[]) => {
initInternalDock(existItem); initInternalDock(existItem);
}); });
window.siyuan.layout.centerLayout = window.siyuan.layout.layout.children[0].children[1] as Layout; window.siyuan.layout.centerLayout = window.siyuan.layout.layout.children[0].children[1] as Layout;
window.siyuan.layout.leftDock = new Dock({position: "Left", data: json.left, app}); window.siyuan.layout.leftDock = new Dock({ position: "Left", data: json.left, app });
window.siyuan.layout.rightDock = new Dock({position: "Right", data: json.right, app}); window.siyuan.layout.rightDock = new Dock({ position: "Right", data: json.right, app });
window.siyuan.layout.bottomDock = new Dock({position: "Bottom", data: json.bottom, app}); window.siyuan.layout.bottomDock = new Dock({ position: "Bottom", data: json.bottom, app });
}; };
export const JSONToCenter = (app: App, json: ILayoutJSON, layout?: Layout | Wnd | Tab | Model) => { export const JSONToCenter = (
app: App,
json: Config.TUILayoutItem,
layout?: Layout | Wnd | Tab | Model,
) => {
let child: Layout | Wnd | Tab | Model; let child: Layout | Wnd | Tab | Model;
if (json.instance === "Layout") { if (json.instance === "Layout") {
if (!layout) { if (!layout) {
@ -408,7 +412,7 @@ export const JSONToCenter = (app: App, json: ILayoutJSON, layout?: Layout | Wnd
} }
(layout as Tab).headElement.setAttribute("data-initdata", JSON.stringify(json)); (layout as Tab).headElement.setAttribute("data-initdata", JSON.stringify(json));
} }
if (json.children) { if ("children" in json) {
if (Array.isArray(json.children)) { if (Array.isArray(json.children)) {
json.children.forEach((item: any) => { json.children.forEach((item: any) => {
JSONToCenter(app, item, layout ? child : window.siyuan.layout.layout); JSONToCenter(app, item, layout ? child : window.siyuan.layout.layout);

View file

@ -27,7 +27,7 @@ import {addClearButton} from "../../util/addClearButton";
import {checkFold} from "../../util/noRelyPCFunction"; import {checkFold} from "../../util/noRelyPCFunction";
import {getDefaultType} from "../../search/getDefault"; import {getDefaultType} from "../../search/getDefault";
const replace = (element: Element, config: ISearchOption, isAll: boolean) => { const replace = (element: Element, config: Config.IUILayoutTabSearchConfig, isAll: boolean) => {
if (config.method === 1 || config.method === 2) { if (config.method === 1 || config.method === 2) {
showMessage(window.siyuan.languages._kernel[132]); showMessage(window.siyuan.languages._kernel[132]);
return; return;
@ -106,7 +106,7 @@ const replace = (element: Element, config: ISearchOption, isAll: boolean) => {
}); });
}; };
const updateConfig = (element: Element, newConfig: ISearchOption, config: ISearchOption) => { const updateConfig = (element: Element, newConfig: Config.IUILayoutTabSearchConfig, config: Config.IUILayoutTabSearchConfig) => {
if (config.hasReplace !== newConfig.hasReplace) { if (config.hasReplace !== newConfig.hasReplace) {
if (newConfig.hasReplace) { if (newConfig.hasReplace) {
element.querySelector('[data-type="toggle-replace"]').classList.add("toolbar__icon--active"); element.querySelector('[data-type="toggle-replace"]').classList.add("toolbar__icon--active");
@ -162,7 +162,7 @@ const updateConfig = (element: Element, newConfig: ISearchOption, config: ISearc
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();
}; };
const onRecentBlocks = (data: IBlock[], config: ISearchOption, response?: IWebSocketData) => { const onRecentBlocks = (data: IBlock[], config: Config.IUILayoutTabSearchConfig, response?: IWebSocketData) => {
const listElement = document.querySelector("#searchList"); const listElement = document.querySelector("#searchList");
let resultHTML = ""; let resultHTML = "";
data.forEach((item: IBlock, index: number) => { data.forEach((item: IBlock, index: number) => {
@ -212,7 +212,7 @@ ${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)}
}; };
let toolbarSearchTimeout = 0; let toolbarSearchTimeout = 0;
export const updateSearchResult = (config: ISearchOption, element: Element, rmCurrentCriteria = false) => { export const updateSearchResult = (config: Config.IUILayoutTabSearchConfig, element: Element, rmCurrentCriteria = false) => {
clearTimeout(toolbarSearchTimeout); clearTimeout(toolbarSearchTimeout);
toolbarSearchTimeout = window.setTimeout(() => { toolbarSearchTimeout = window.setTimeout(() => {
if (rmCurrentCriteria) { if (rmCurrentCriteria) {
@ -260,7 +260,7 @@ export const updateSearchResult = (config: ISearchOption, element: Element, rmCu
}, Constants.TIMEOUT_INPUT); }, Constants.TIMEOUT_INPUT);
}; };
const initSearchEvent = (app: App, element: Element, config: ISearchOption) => { const initSearchEvent = (app: App, element: Element, config: Config.IUILayoutTabSearchConfig) => {
const searchInputElement = document.getElementById("toolbarSearch") as HTMLInputElement; const searchInputElement = document.getElementById("toolbarSearch") as HTMLInputElement;
searchInputElement.value = config.k || ""; searchInputElement.value = config.k || "";
searchInputElement.addEventListener("compositionend", (event: InputEvent) => { searchInputElement.addEventListener("compositionend", (event: InputEvent) => {
@ -298,7 +298,7 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
inputElement: replaceInputElement, inputElement: replaceInputElement,
className: "toolbar__icon", className: "toolbar__icon",
}); });
const criteriaData: ISearchOption[] = []; const criteriaData: Config.IUILayoutTabSearchConfig[] = [];
initCriteriaMenu(element.querySelector("#criteria"), criteriaData, config); initCriteriaMenu(element.querySelector("#criteria"), criteriaData, config);
const assetsElement = document.querySelector("#searchAssetsPanel"); const assetsElement = document.querySelector("#searchAssetsPanel");
@ -616,7 +616,7 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
}, false); }, false);
}; };
export const popSearch = (app: App, config = window.siyuan.storage[Constants.LOCAL_SEARCHDATA] as ISearchOption) => { export const popSearch = (app: App, config = window.siyuan.storage[Constants.LOCAL_SEARCHDATA] as Config.IUILayoutTabSearchConfig) => {
activeBlur(); activeBlur();
hideKeyboardToolbar(); hideKeyboardToolbar();
let includeChild = true; let includeChild = true;

View file

@ -62,7 +62,7 @@ openTab = (options: {
asset?: { asset?: {
path: string, path: string,
}, },
search?: ISearchOption search?: Config.IUILayoutTabSearchConfig
card?: { card?: {
type: TCardType, type: TCardType,
id?: string, // cardType 为 all 时不传,否则传文档或笔记本 id id?: string, // cardType 为 all 时不传,否则传文档或笔记本 id

View file

@ -86,9 +86,9 @@ export const loadPlugin = async (app: App, item: IPluginData) => {
}; };
const updateDock = (dockItem: IDockTab[], index: number, plugin: Plugin, type: string) => { const updateDock = (dockItem: Config.IUILayoutDockTab[], index: number, plugin: Plugin, type: string) => {
const dockKeys = Object.keys(plugin.docks); const dockKeys = Object.keys(plugin.docks);
dockItem.forEach((tabItem: IDockTab, tabIndex: number) => { dockItem.forEach((tabItem: Config.IUILayoutDockTab, tabIndex: number) => {
if (dockKeys.includes(tabItem.type)) { if (dockKeys.includes(tabItem.type)) {
if (type === "Left") { if (type === "Left") {
plugin.docks[tabItem.type].config.position = index === 0 ? "LeftTop" : "LeftBottom"; plugin.docks[tabItem.type].config.position = index === 0 ? "LeftTop" : "LeftBottom";
@ -214,13 +214,13 @@ export const afterLoadPlugin = (plugin: Plugin) => {
} }
/// #if !MOBILE /// #if !MOBILE
window.siyuan.config.uiLayout.left.data.forEach((dockItem: IDockTab[], index: number) => { window.siyuan.config.uiLayout.left.data.forEach((dockItem: Config.IUILayoutDockTab[], index: number) => {
updateDock(dockItem, index, plugin, "Left"); updateDock(dockItem, index, plugin, "Left");
}); });
window.siyuan.config.uiLayout.right.data.forEach((dockItem: IDockTab[], index: number) => { window.siyuan.config.uiLayout.right.data.forEach((dockItem: Config.IUILayoutDockTab[], index: number) => {
updateDock(dockItem, index, plugin, "Right"); updateDock(dockItem, index, plugin, "Right");
}); });
window.siyuan.config.uiLayout.bottom.data.forEach((dockItem: IDockTab[], index: number) => { window.siyuan.config.uiLayout.bottom.data.forEach((dockItem: Config.IUILayoutDockTab[], index: number) => {
updateDock(dockItem, index, plugin, "Bottom"); updateDock(dockItem, index, plugin, "Bottom");
}); });
Object.keys(plugin.docks).forEach(key => { Object.keys(plugin.docks).forEach(key => {

View file

@ -7,10 +7,10 @@ import {App} from "../index";
export class Search extends Model { export class Search extends Model {
public element: HTMLElement; public element: HTMLElement;
public config: ISearchOption; public config: Config.IUILayoutTabSearchConfig;
public editors: { edit: Protyle, unRefEdit: Protyle }; public editors: { edit: Protyle, unRefEdit: Protyle };
constructor(options: { tab: Tab, config: ISearchOption, app: App }) { constructor(options: { tab: Tab, config: Config.IUILayoutTabSearchConfig, app: App }) {
super({ super({
app: options.app, app: options.app,
id: options.tab.id, id: options.tab.id,

View file

@ -9,7 +9,7 @@ import {setStorageVal} from "../protyle/util/compatibility";
import {confirmDialog} from "../dialog/confirmDialog"; import {confirmDialog} from "../dialog/confirmDialog";
import {goUnRef, updateSearchResult} from "../mobile/menu/search"; import {goUnRef, updateSearchResult} from "../mobile/menu/search";
export const filterMenu = (config: ISearchOption, cb: () => void) => { export const filterMenu = (config: Config.IUILayoutTabSearchConfig, cb: () => void) => {
const filterDialog = new Dialog({ const filterDialog = new Dialog({
title: window.siyuan.languages.searchType, title: window.siyuan.languages.searchType,
content: `<div class="b3-dialog__content"> content: `<div class="b3-dialog__content">
@ -181,16 +181,16 @@ export const filterMenu = (config: ISearchOption, cb: () => void) => {
}); });
btnsElement[1].addEventListener("click", () => { btnsElement[1].addEventListener("click", () => {
filterDialog.element.querySelectorAll(".b3-switch").forEach((item: HTMLInputElement) => { filterDialog.element.querySelectorAll(".b3-switch").forEach((item: HTMLInputElement) => {
config.types[item.getAttribute("data-type") as TSearchFilter] = item.checked; config.types[item.getAttribute("data-type") as keyof (typeof config.types)] = item.checked;
}); });
cb(); cb();
filterDialog.destroy(); filterDialog.destroy();
}); });
}; };
export const replaceFilterMenu = (config: ISearchOption) => { export const replaceFilterMenu = (config: Config.IUILayoutTabSearchConfig) => {
let html = ""; let html = "";
Object.keys(Constants.SIYUAN_DEFAULT_REPLACETYPES).forEach((key) => { Object.keys(Constants.SIYUAN_DEFAULT_REPLACETYPES).forEach((key: keyof Config.IUILayoutTabSearchConfigReplaceTypes) => {
html += `<label class="fn__flex b3-label"> html += `<label class="fn__flex b3-label">
<span class="fn__space"></span> <span class="fn__space"></span>
<div class="fn__flex-1 fn__flex-center"> <div class="fn__flex-1 fn__flex-center">
@ -217,13 +217,13 @@ export const replaceFilterMenu = (config: ISearchOption) => {
}); });
btnsElement[1].addEventListener("click", () => { btnsElement[1].addEventListener("click", () => {
filterDialog.element.querySelectorAll(".b3-switch").forEach((item: HTMLInputElement) => { filterDialog.element.querySelectorAll(".b3-switch").forEach((item: HTMLInputElement) => {
config.replaceTypes[item.getAttribute("data-type") as TSearchFilter] = item.checked; config.replaceTypes[item.getAttribute("data-type") as keyof (typeof config.replaceTypes)] = item.checked;
}); });
filterDialog.destroy(); filterDialog.destroy();
}); });
}; };
export const queryMenu = (config: ISearchOption, cb: () => void) => { export const queryMenu = (config: Config.IUILayoutTabSearchConfig, cb: () => void) => {
if (!window.siyuan.menus.menu.element.classList.contains("fn__none") && if (!window.siyuan.menus.menu.element.classList.contains("fn__none") &&
window.siyuan.menus.menu.element.getAttribute("data-name") === "searchMethod") { window.siyuan.menus.menu.element.getAttribute("data-name") === "searchMethod") {
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();
@ -269,8 +269,8 @@ export const queryMenu = (config: ISearchOption, cb: () => void) => {
}).element); }).element);
}; };
const saveCriterionData = (config: ISearchOption, const saveCriterionData = (config: Config.IUILayoutTabSearchConfig,
criteriaData: ISearchOption[], criteriaData: Config.IUILayoutTabSearchConfig[],
element: Element, element: Element,
value: string, value: string,
saveDialog: Dialog) => { saveDialog: Dialog) => {
@ -289,8 +289,8 @@ const saveCriterionData = (config: ISearchOption,
}); });
}; };
export const saveCriterion = (config: ISearchOption, export const saveCriterion = (config: Config.IUILayoutTabSearchConfig,
criteriaData: ISearchOption[], criteriaData: Config.IUILayoutTabSearchConfig[],
element: Element) => { element: Element) => {
const saveDialog = new Dialog({ const saveDialog = new Dialog({
title: window.siyuan.languages.saveCriterion, title: window.siyuan.languages.saveCriterion,
@ -393,8 +393,8 @@ export const saveCriterion = (config: ISearchOption,
}); });
}; };
export const moreMenu = async (config: ISearchOption, export const moreMenu = async (config: Config.IUILayoutTabSearchConfig,
criteriaData: ISearchOption[], criteriaData: Config.IUILayoutTabSearchConfig[],
element: Element, element: Element,
cb: () => void, cb: () => void,
removeCriterion: () => void, removeCriterion: () => void,
@ -605,7 +605,7 @@ export const moreMenu = async (config: ISearchOption,
}).element); }).element);
}; };
const configIsSame = (config: ISearchOption, config2: ISearchOption) => { const configIsSame = (config: Config.IUILayoutTabSearchConfig, config2: Config.IUILayoutTabSearchConfig) => {
if (config2.group === config.group && config2.hPath === config.hPath && config2.hasReplace === config.hasReplace && if (config2.group === config.group && config2.hPath === config.hPath && config2.hasReplace === config.hasReplace &&
config2.k === config.k && config2.method === config.method && config2.r === config.r && config2.k === config.k && config2.method === config.method && config2.r === config.r &&
config2.sort === config.sort && objEquals(config2.types, config.types) && config2.sort === config.sort && objEquals(config2.types, config.types) &&
@ -615,10 +615,10 @@ const configIsSame = (config: ISearchOption, config2: ISearchOption) => {
return false; return false;
}; };
export const initCriteriaMenu = (element: HTMLElement, data: ISearchOption[], config: ISearchOption) => { export const initCriteriaMenu = (element: HTMLElement, data: Config.IUILayoutTabSearchConfig[], config: Config.IUILayoutTabSearchConfig) => {
fetchPost("/api/storage/getCriteria", {}, (response) => { fetchPost("/api/storage/getCriteria", {}, (response) => {
let html = ""; let html = "";
response.data.forEach((item: ISearchOption, index: number) => { response.data.forEach((item: Config.IUILayoutTabSearchConfig, index: number) => {
data.push(item); data.push(item);
let isSame = false; let isSame = false;
if (configIsSame(item, config)) { if (configIsSame(item, config)) {

View file

@ -120,7 +120,7 @@ export const toggleReplaceHistory = (searchElement: Element) => {
}); });
}; };
export const toggleSearchHistory = (searchElement: Element, config: ISearchOption, edit: Protyle) => { export const toggleSearchHistory = (searchElement: Element, config: Config.IUILayoutTabSearchConfig, edit: Protyle) => {
const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]; const list = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS];
if (!list.keys || list.keys.length === 0) { if (!list.keys || list.keys.length === 0) {
return; return;
@ -234,7 +234,7 @@ export const openGlobalSearch = (app: App, text: string, replace: boolean) => {
}; };
// closeCB 不存在为页签搜索 // closeCB 不存在为页签搜索
export const genSearch = (app: App, config: ISearchOption, element: Element, closeCB?: () => void) => { export const genSearch = (app: App, config: Config.IUILayoutTabSearchConfig, element: Element, closeCB?: () => void) => {
let methodText = window.siyuan.languages.keyword; let methodText = window.siyuan.languages.keyword;
if (config.method === 1) { if (config.method === 1) {
methodText = window.siyuan.languages.querySyntax; methodText = window.siyuan.languages.querySyntax;
@ -395,7 +395,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo
</div> </div>
<div class="fn__loading fn__loading--top"><img width="120px" src="/stage/loading-pure.svg"></div>`; <div class="fn__loading fn__loading--top"><img width="120px" src="/stage/loading-pure.svg"></div>`;
const criteriaData: ISearchOption[] = []; const criteriaData: Config.IUILayoutTabSearchConfig[] = [];
initCriteriaMenu(element.querySelector("#criteria"), criteriaData, config); initCriteriaMenu(element.querySelector("#criteria"), criteriaData, config);
const searchPanelElement = element.querySelector("#searchList"); const searchPanelElement = element.querySelector("#searchList");
const searchInputElement = element.querySelector("#searchInput") as HTMLInputElement; const searchInputElement = element.querySelector("#searchInput") as HTMLInputElement;
@ -1072,7 +1072,7 @@ export const getQueryTip = (method: number) => {
return methodTip; return methodTip;
}; };
const updateConfig = (element: Element, item: ISearchOption, config: ISearchOption, edit: Protyle) => { const updateConfig = (element: Element, item: Config.IUILayoutTabSearchConfig, config: Config.IUILayoutTabSearchConfig, edit: Protyle) => {
const dialogElement = hasClosestByClassName(element, "b3-dialog--open"); const dialogElement = hasClosestByClassName(element, "b3-dialog--open");
if (dialogElement && dialogElement.getAttribute("data-key") === Constants.DIALOG_SEARCH) { if (dialogElement && dialogElement.getAttribute("data-key") === Constants.DIALOG_SEARCH) {
// https://github.com/siyuan-note/siyuan/issues/6828 // https://github.com/siyuan-note/siyuan/issues/6828
@ -1159,7 +1159,7 @@ const renderNextSearchMark = (options: {
export const getArticle = (options: { export const getArticle = (options: {
id: string, id: string,
config?: ISearchOption, config?: Config.IUILayoutTabSearchConfig,
edit: Protyle edit: Protyle
value?: string, value?: string,
}) => { }) => {
@ -1196,7 +1196,7 @@ export const getArticle = (options: {
}); });
}; };
export const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: boolean) => { export const replace = (element: Element, config: Config.IUILayoutTabSearchConfig, edit: Protyle, isAll: boolean) => {
if (config.method === 1 || config.method === 2) { if (config.method === 1 || config.method === 2) {
showMessage(window.siyuan.languages._kernel[132]); showMessage(window.siyuan.languages._kernel[132]);
return; return;
@ -1282,7 +1282,7 @@ export const replace = (element: Element, config: ISearchOption, edit: Protyle,
}); });
}; };
export const inputEvent = (element: Element, config: ISearchOption, edit: Protyle, rmCurrentCriteria = false) => { export const inputEvent = (element: Element, config: Config.IUILayoutTabSearchConfig, edit: Protyle, rmCurrentCriteria = false) => {
let inputTimeout = parseInt(element.getAttribute("data-timeout") || "0"); let inputTimeout = parseInt(element.getAttribute("data-timeout") || "0");
clearTimeout(inputTimeout); clearTimeout(inputTimeout);
inputTimeout = window.setTimeout(() => { inputTimeout = window.setTimeout(() => {
@ -1360,7 +1360,7 @@ export const getAttr = (block: IBlock) => {
return attrHTML; return attrHTML;
}; };
const onSearch = (data: IBlock[], edit: Protyle, element: Element, config: ISearchOption) => { const onSearch = (data: IBlock[], edit: Protyle, element: Element, config: Config.IUILayoutTabSearchConfig) => {
let resultHTML = ""; let resultHTML = "";
data.forEach((item, index) => { data.forEach((item, index) => {
const title = getNotebookName(item.box) + getDisplayName(item.hPath, false); const title = getNotebookName(item.box) + getDisplayName(item.hPath, false);

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,3 @@
type TLayout = "normal" | "bottom" | "left" | "right" | "center"
type TSearchFilter = "mathBlock" | "table" | "blockquote" | "superBlock" | "paragraph" | "document" | "heading"
| "list" | "listItem" | "codeBlock" | "htmlBlock"
type TDirection = "lr" | "tb"
type TPluginDockPosition = "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight" type TPluginDockPosition = "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight"
type TDockPosition = "Left" | "Right" | "Bottom" type TDockPosition = "Left" | "Right" | "Bottom"
type TWS = "main" | "filetree" | "protyle" type TWS = "main" | "filetree" | "protyle"
@ -507,23 +503,10 @@ interface ILayoutJSON extends ILayoutOptions {
isPreview?: boolean isPreview?: boolean
customModelData?: any customModelData?: any
customModelType?: string customModelType?: string
config?: ISearchOption config?: Config.IUILayoutTabSearchConfig
children?: ILayoutJSON[] | ILayoutJSON children?: ILayoutJSON[] | ILayoutJSON
} }
interface IDockTab {
type: string;
size: {
width: number,
height: number
}
show: boolean
icon: string
title: string
hotkey?: string
hotkeyLangId?: string // 常量中无法存变量
}
interface ICommand { interface ICommand {
langKey: string, // 用于区分不同快捷键的 key, 同时作为 i18n 的字段名 langKey: string, // 用于区分不同快捷键的 key, 同时作为 i18n 的字段名
langText?: string, // 显示的文本, 指定后不再使用 langKey 对应的 i18n 文本 langText?: string, // 显示的文本, 指定后不再使用 langKey 对应的 i18n 文本
@ -564,7 +547,7 @@ interface IExportOptions {
interface IOpenFileOptions { interface IOpenFileOptions {
app: import("../index").App, app: import("../index").App,
searchData?: ISearchOption, // 搜索必填 searchData?: Config.IUILayoutTabSearchConfig, // 搜索必填
// card 和自定义页签 必填 // card 和自定义页签 必填
custom?: { custom?: {
title: string, title: string,
@ -592,10 +575,10 @@ interface IOpenFileOptions {
} }
interface ILayoutOptions { interface ILayoutOptions {
direction?: TDirection; direction?: Config.TUILayoutDirection
size?: string size?: string
resize?: TDirection resize?: Config.TUILayoutDirection
type?: TLayout type?: Config.TUILayoutType
element?: HTMLElement element?: HTMLElement
} }