@@ -38,7 +39,7 @@ export class MobileBookmarks {
}
}
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
- openMobileFileById(id, foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_FOCUS, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML]);
+ openMobileFileById(app, id, foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_FOCUS, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML]);
});
},
blockExtHTML: '
',
diff --git a/app/src/mobile/dock/MobileFiles.ts b/app/src/mobile/dock/MobileFiles.ts
index 541be9dee..6291cd44b 100644
--- a/app/src/mobile/dock/MobileFiles.ts
+++ b/app/src/mobile/dock/MobileFiles.ts
@@ -13,14 +13,16 @@ import {mountHelp, newNotebook} from "../../util/mount";
import {confirmDialog} from "../../dialog/confirmDialog";
import {newFile} from "../../util/newFile";
import {MenuItem} from "../../menus/Menu";
+import {App} from "../../index";
export class MobileFiles extends Model {
public element: HTMLElement;
private actionsElement: HTMLElement;
private closeElement: HTMLElement;
- constructor() {
+ constructor(app: App) {
super({
+ app,
id: genUUID(),
type: "filetree",
msgCallback(data) {
@@ -177,15 +179,15 @@ export class MobileFiles extends Model {
const notebookId = ulElement.getAttribute("data-url");
if (!window.siyuan.config.readonly) {
if (type === "new") {
- newFile(notebookId, pathString);
+ newFile(app, notebookId, pathString);
} else if (type === "more-root") {
- initNavigationMenu(target.parentElement);
+ initNavigationMenu(app, target.parentElement);
window.siyuan.menus.menu.fullscreen("bottom");
window.siyuan.menus.menu.element.style.zIndex = "310";
}
}
if (type === "more-file") {
- initFileMenu(notebookId, pathString, target.parentElement);
+ initFileMenu(app, notebookId, pathString, target.parentElement);
window.siyuan.menus.menu.fullscreen("bottom");
window.siyuan.menus.menu.element.style.zIndex = "310";
}
@@ -196,7 +198,7 @@ export class MobileFiles extends Model {
} else if (target.tagName === "LI") {
this.setCurrent(target);
if (target.getAttribute("data-type") === "navigation-file") {
- openMobileFileById(target.getAttribute("data-node-id"));
+ openMobileFileById(app, target.getAttribute("data-node-id"));
} else if (target.getAttribute("data-type") === "navigation-root") {
const ulElement = hasTopClosestByTag(target, "UL");
if (ulElement) {
diff --git a/app/src/mobile/dock/MobileOutline.ts b/app/src/mobile/dock/MobileOutline.ts
index 3635ed512..a7fd55933 100644
--- a/app/src/mobile/dock/MobileOutline.ts
+++ b/app/src/mobile/dock/MobileOutline.ts
@@ -3,13 +3,14 @@ import {fetchPost} from "../../util/fetch";
import {openMobileFileById} from "../editor";
import {Constants} from "../../constants";
import {getEventName} from "../../protyle/util/compatibility";
+import {App} from "../../index";
export class MobileOutline {
private tree: Tree;
private openNodes: { [key: string]: string[] } = {};
private element: Element;
- constructor() {
+ constructor(app: App) {
this.element = document.querySelector('#sidebar [data-type="sidebar-outline"]');
this.element.innerHTML = `
@@ -28,7 +29,7 @@ export class MobileOutline {
click: (element: HTMLElement) => {
const id = element.getAttribute("data-node-id");
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
- openMobileFileById(id, foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_FOCUS, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML]);
+ openMobileFileById(app, id, foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_FOCUS, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML]);
});
}
});
diff --git a/app/src/mobile/dock/MobileTags.ts b/app/src/mobile/dock/MobileTags.ts
index 1548fb6c0..a70f0ad33 100644
--- a/app/src/mobile/dock/MobileTags.ts
+++ b/app/src/mobile/dock/MobileTags.ts
@@ -7,13 +7,14 @@ import {confirmDialog} from "../../dialog/confirmDialog";
import {escapeHtml} from "../../util/escape";
import {popSearch} from "../menu/search";
import {Constants} from "../../constants";
+import {App} from "../../index";
export class MobileTags {
public element: HTMLElement;
private tree: Tree;
private openNodes: string[];
- constructor() {
+ constructor(app: App) {
this.element = document.querySelector('#sidebar [data-type="sidebar-tag"]');
this.element.innerHTML = `
@@ -67,7 +68,7 @@ export class MobileTags {
}
} else {
const searchOption = window.siyuan.storage[Constants.LOCAL_SEARCHDATA];
- popSearch({
+ popSearch(app, {
removed: searchOption.removed,
sort: searchOption.sort,
group: searchOption.group,
diff --git a/app/src/mobile/editor.ts b/app/src/mobile/editor.ts
index 95c87f242..0337e133f 100644
--- a/app/src/mobile/editor.ts
+++ b/app/src/mobile/editor.ts
@@ -13,12 +13,13 @@ import {pushBack} from "./util/MobileBackFoward";
import {setStorageVal} from "../protyle/util/compatibility";
import {showMessage} from "../dialog/message";
import {saveScroll} from "../protyle/scroll/saveScroll";
+import {App} from "../index";
export const getCurrentEditor = () => {
return window.siyuan.mobile.popEditor || window.siyuan.mobile.editor;
};
-export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL]) => {
+export const openMobileFileById = (app: App, id: string, action = [Constants.CB_GET_HL]) => {
window.siyuan.storage[Constants.LOCAL_DOCINFO] = {id, action};
setStorageVal(Constants.LOCAL_DOCINFO, window.siyuan.storage[Constants.LOCAL_DOCINFO]);
if (window.siyuan.mobile.editor) {
@@ -62,7 +63,7 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL]) =
});
window.siyuan.mobile.editor.protyle.undo.clear();
} else {
- window.siyuan.mobile.editor = new Protyle(document.getElementById("editor"), {
+ window.siyuan.mobile.editor = new Protyle(app, document.getElementById("editor"), {
blockId: id,
action,
render: {
diff --git a/app/src/mobile/index.ts b/app/src/mobile/index.ts
index abb133184..40e8f9b62 100644
--- a/app/src/mobile/index.ts
+++ b/app/src/mobile/index.ts
@@ -42,13 +42,14 @@ class App {
blockPanels: [],
mobile: {},
ws: new Model({
+ app: this,
id: genUUID(),
type: "main",
- msgCallback: (data)=> {
+ msgCallback: (data) => {
this.plugins.forEach((plugin) => {
plugin.eventBus.emit("ws-main", data);
});
- onMessage(data);
+ onMessage(this, data);
}
})
};
@@ -64,7 +65,7 @@ class App {
getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
window.siyuan.languages = lauguages;
- window.siyuan.menus = new Menus(siyuanApp);
+ window.siyuan.menus = new Menus(this);
document.title = window.siyuan.languages.siyuanNote;
bootSync();
loadAssets(confResponse.data.conf.appearance);
@@ -74,9 +75,9 @@ class App {
window.siyuan.user = userResponse.data;
fetchPost("/api/system/getEmojiConf", {}, emojiResponse => {
window.siyuan.emojis = emojiResponse.data as IEmoji[];
- initFramework(siyuanApp);
- initRightMenu();
- loadPlugins(siyuanApp);
+ initFramework(this);
+ initRightMenu(this);
+ loadPlugins(this);
openChangelog();
});
});
@@ -85,7 +86,9 @@ class App {
});
document.addEventListener("touchstart", handleTouchStart, false);
document.addEventListener("touchmove", handleTouchMove, false);
- document.addEventListener("touchend", handleTouchEnd, false);
+ document.addEventListener("touchend", (event) => {
+ handleTouchEnd(this, event);
+ }, false);
});
setNoteBook();
promiseTransactions();
@@ -102,7 +105,7 @@ window.showKeyboardToolbar = (height) => {
window.hideKeyboardToolbar = hideKeyboardToolbar;
window.openFileByURL = (openURL) => {
if (openURL && isSYProtocol(openURL)) {
- openMobileFileById(getIdFromSYProtocol(openURL),
+ openMobileFileById(siyuanApp, getIdFromSYProtocol(openURL),
getSearch("focus", openURL) === "1" ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT]);
return true;
}
diff --git a/app/src/mobile/menu/getRecentDocs.ts b/app/src/mobile/menu/getRecentDocs.ts
index b876a5eaf..651e1e7d7 100644
--- a/app/src/mobile/menu/getRecentDocs.ts
+++ b/app/src/mobile/menu/getRecentDocs.ts
@@ -5,8 +5,9 @@ import {escapeHtml} from "../../util/escape";
import {hasClosestByClassName} from "../../protyle/util/hasClosest";
import {openModel} from "./model";
import {openMobileFileById} from "../editor";
+import {App} from "../../index";
-export const getRecentDocs = () => {
+export const getRecentDocs = (app: App) => {
fetchPost("/api/storage/getRecentDocs", {}, (response) => {
let html = "";
response.data.forEach((item: any, index: number) => {
@@ -23,7 +24,7 @@ ${unicode2Emoji(item.icon || Constants.SIYUAN_IMAGE_FILE, false, "b3-list-item__
element.firstElementChild.addEventListener("click", (event) => {
const liElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item");
if (liElement) {
- openMobileFileById(liElement.dataset.nodeId, [Constants.CB_GET_SCROLL]);
+ openMobileFileById(app, liElement.dataset.nodeId, [Constants.CB_GET_SCROLL]);
}
});
}
diff --git a/app/src/mobile/menu/index.ts b/app/src/mobile/menu/index.ts
index b7278b7a9..2fab5b1d5 100644
--- a/app/src/mobile/menu/index.ts
+++ b/app/src/mobile/menu/index.ts
@@ -15,6 +15,7 @@ import {openModel} from "./model";
import {initAbout} from "../settings/about";
import {getRecentDocs} from "./getRecentDocs";
import {initEditor} from "../settings/editor";
+import {App} from "../../index";
export const popMenu = () => {
activeBlur();
@@ -22,7 +23,7 @@ export const popMenu = () => {
document.getElementById("menu").style.transform = "translateX(0px)";
};
-export const initRightMenu = () => {
+export const initRightMenu = (app: App) => {
const menuElement = document.getElementById("menu");
let accountHTML = "";
if (window.siyuan.user && !window.siyuan.config.readonly) {
@@ -118,12 +119,12 @@ export const initRightMenu = () => {
event.stopPropagation();
break;
} else if (target.id === "menuSearch") {
- popSearch();
+ popSearch(app);
event.preventDefault();
event.stopPropagation();
break;
} else if (target.id === "menuRecent") {
- getRecentDocs();
+ getRecentDocs(app);
event.preventDefault();
event.stopPropagation();
break;
@@ -164,7 +165,7 @@ export const initRightMenu = () => {
event.stopPropagation();
break;
} else if (target.id === "menuCard") {
- openCard();
+ openCard(app);
closePanel();
event.preventDefault();
event.stopPropagation();
@@ -204,7 +205,7 @@ export const initRightMenu = () => {
event.stopPropagation();
break;
} else if (target.id === "menuHistory") {
- openHistory();
+ openHistory(app);
event.preventDefault();
event.stopPropagation();
break;
diff --git a/app/src/mobile/menu/search.ts b/app/src/mobile/menu/search.ts
index e5300565c..1d947b1d0 100644
--- a/app/src/mobile/menu/search.ts
+++ b/app/src/mobile/menu/search.ts
@@ -14,6 +14,7 @@ import {newFileByName} from "../../util/newFile";
import {showMessage} from "../../dialog/message";
import {reloadProtyle} from "../../protyle/util/reload";
import {activeBlur, hideKeyboardToolbar} from "../util/keyboardToolbar";
+import {App} from "../../index";
const replace = (element: Element, config: ISearchOption, isAll: boolean) => {
if (config.method === 1 || config.method === 2) {
@@ -245,7 +246,7 @@ const updateSearchResult = (config: ISearchOption, element: Element) => {
}, Constants.TIMEOUT_INPUT);
};
-const initSearchEvent = (element: Element, config: ISearchOption) => {
+const initSearchEvent = (app: App, element: Element, config: ISearchOption) => {
const searchInputElement = document.getElementById("toolbarSearch") as HTMLInputElement;
searchInputElement.value = config.k || "";
searchInputElement.addEventListener("compositionend", (event: InputEvent) => {
@@ -494,14 +495,14 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
break;
} else if (target.classList.contains("b3-list-item")) {
if (target.getAttribute("data-type") === "search-new") {
- newFileByName(searchInputElement.value);
+ newFileByName(app, searchInputElement.value);
} else if (target.getAttribute("data-type") === "search-item") {
const id = target.getAttribute("data-node-id");
if (window.siyuan.mobile.editor.protyle) {
preventScroll(window.siyuan.mobile.editor.protyle);
}
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
- openMobileFileById(id, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(app, id, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
});
closePanel();
} else if (target.querySelector(".b3-list-item__toggle")) {
@@ -517,7 +518,7 @@ const initSearchEvent = (element: Element, config: ISearchOption) => {
}, false);
};
-export const popSearch = (config = window.siyuan.storage[Constants.LOCAL_SEARCHDATA] as ISearchOption) => {
+export const popSearch = (app: App, config = window.siyuan.storage[Constants.LOCAL_SEARCHDATA] as ISearchOption) => {
activeBlur();
hideKeyboardToolbar();
let includeChild = true;
@@ -575,7 +576,7 @@ export const popSearch = (config = window.siyuan.storage[Constants.LOCAL_SEARCHD

`,
bindEvent(element) {
- initSearchEvent(element.firstElementChild, config);
+ initSearchEvent(app, element.firstElementChild, config);
updateSearchResult(config, element);
}
});
diff --git a/app/src/mobile/util/initFramework.ts b/app/src/mobile/util/initFramework.ts
index fa099bba5..b16aee4b5 100644
--- a/app/src/mobile/util/initFramework.ts
+++ b/app/src/mobile/util/initFramework.ts
@@ -52,30 +52,30 @@ export const initFramework = (app: App) => {
if (itemType === type) {
if (type === "sidebar-outline-tab") {
if (!outline) {
- outline = new MobileOutline();
+ outline = new MobileOutline(app);
} else {
outline.update();
}
} else if (type === "sidebar-backlink-tab") {
if (!backlink) {
- backlink = new MobileBacklinks();
+ backlink = new MobileBacklinks(app);
} else {
backlink.update();
}
} else if (type === "sidebar-bookmark-tab") {
if (!bookmark) {
- bookmark = new MobileBookmarks();
+ bookmark = new MobileBookmarks(app);
} else {
backlink.update();
}
} else if (type === "sidebar-tag-tab") {
if (!tag) {
- tag = new MobileTags();
+ tag = new MobileTags(app);
} else {
tag.update();
}
} else if (type === "sidebar-inbox-tab" && !inbox) {
- inbox = new Inbox(document.querySelector('#sidebar [data-type="sidebar-inbox"]'));
+ inbox = new Inbox(app, document.querySelector('#sidebar [data-type="sidebar-inbox"]'));
}
svgElement.classList.add("toolbar__icon--active");
sidebarElement.lastElementChild.querySelector(`[data-type="${itemType.replace("-tab", "")}"]`).classList.remove("fn__none");
@@ -85,7 +85,7 @@ export const initFramework = (app: App) => {
}
});
});
- window.siyuan.mobile.files = new MobileFiles();
+ window.siyuan.mobile.files = new MobileFiles(app);
document.getElementById("toolbarFile").addEventListener("click", () => {
hideKeyboardToolbar();
activeBlur();
@@ -144,27 +144,27 @@ export const initFramework = (app: App) => {
}
const idZoomIn = getIdZoomInByPath();
if (idZoomIn.id) {
- openMobileFileById(idZoomIn.id,
+ openMobileFileById(app, idZoomIn.id,
idZoomIn.isZoomIn ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT]);
return;
}
const localDoc = window.siyuan.storage[Constants.LOCAL_DOCINFO];
fetchPost("/api/block/checkBlockExist", {id: localDoc.id}, existResponse => {
if (existResponse.data) {
- openMobileFileById(localDoc.id, localDoc.action);
+ openMobileFileById(app, localDoc.id, localDoc.action);
} else {
fetchPost("/api/block/getRecentUpdatedBlocks", {}, (response) => {
if (response.data.length !== 0) {
- openMobileFileById(response.data[0].id, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(app, response.data[0].id, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
} else {
- setEmpty();
+ setEmpty(app);
}
});
}
});
return;
}
- setEmpty();
+ setEmpty(app);
};
const initEditorName = () => {
diff --git a/app/src/mobile/util/onMessage.ts b/app/src/mobile/util/onMessage.ts
index 54e62ff56..1b7ea53f1 100644
--- a/app/src/mobile/util/onMessage.ts
+++ b/app/src/mobile/util/onMessage.ts
@@ -1,6 +1,7 @@
import {openMobileFileById} from "../editor";
import {processSync, progressLoading, progressStatus, reloadSync, transactionError} from "../../dialog/processSystem";
import {Constants} from "../../constants";
+import {App} from "../../index";
const processReadonly = () => {
const inputElement = document.getElementById("toolbarName") as HTMLInputElement;
@@ -14,11 +15,11 @@ const processReadonly = () => {
}
};
-export const onMessage = (data: IWebSocketData) => {
+export const onMessage = (app: App, data: IWebSocketData) => {
if (data) {
switch (data.cmd) {
case "syncMergeResult":
- reloadSync(data.data);
+ reloadSync(app, data.data);
break;
case "readonly":
window.siyuan.config.editor.readOnly = data.data;
@@ -34,10 +35,10 @@ export const onMessage = (data: IWebSocketData) => {
}
break;
case "createdailynote":
- openMobileFileById(data.data.id);
+ openMobileFileById(app, data.data.id);
break;
case "openFileById":
- openMobileFileById(data.data.id, [Constants.CB_GET_FOCUS]);
+ openMobileFileById(app, data.data.id, [Constants.CB_GET_FOCUS]);
break;
case"txerr":
transactionError();
diff --git a/app/src/mobile/util/setEmpty.ts b/app/src/mobile/util/setEmpty.ts
index 625359cf0..80fd7b7bd 100644
--- a/app/src/mobile/util/setEmpty.ts
+++ b/app/src/mobile/util/setEmpty.ts
@@ -4,8 +4,9 @@ import {getOpenNotebookCount} from "../../util/pathName";
import {popSearch} from "../menu/search";
import {getRecentDocs} from "../menu/getRecentDocs";
import {openHistory} from "../../history/history";
+import {App} from "../../index";
-export const setEmpty = () => {
+export const setEmpty = (app: App) => {
document.getElementById("toolbarName").classList.add("fn__hidden");
document.getElementById("toolbarEdit").classList.add("fn__hidden");
document.getElementById("editor").classList.add("fn__none");
@@ -37,27 +38,27 @@ export const setEmpty = () => {
let target = event.target as HTMLElement;
while (target && !target.isEqualNode(emptyElement)) {
if (target.id === "emptySearch") {
- popSearch();
+ popSearch(app);
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "emptyRecent") {
- getRecentDocs();
+ getRecentDocs(app);
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "emptyHistory") {
- openHistory();
+ openHistory(app);
event.stopPropagation();
event.preventDefault();
break;
} else if (target.id === "emptyNewFile") {
if (window.siyuan.mobile.editor) {
- newFile(window.siyuan.mobile.editor.protyle.notebookId, window.siyuan.mobile.editor.protyle.path, undefined, true);
+ newFile(app, window.siyuan.mobile.editor.protyle.notebookId, window.siyuan.mobile.editor.protyle.path, undefined, true);
} else {
window.siyuan.notebooks.find(item => {
if (!item.closed) {
- newFile(item.id, "/", undefined, true);
+ newFile(app, item.id, "/", undefined, true);
return true;
}
});
diff --git a/app/src/mobile/util/touch.ts b/app/src/mobile/util/touch.ts
index 86c009720..d2efa5a5c 100644
--- a/app/src/mobile/util/touch.ts
+++ b/app/src/mobile/util/touch.ts
@@ -4,6 +4,7 @@ import {popMenu} from "../menu";
import {activeBlur, hideKeyboardToolbar} from "./keyboardToolbar";
import {getCurrentEditor} from "../editor";
import {linkMenu, refMenu, tagMenu} from "../../menus/protyle";
+import {App} from "../../index";
let clientX: number;
let clientY: number;
@@ -23,7 +24,7 @@ const popSide = (render = true) => {
}
};
-export const handleTouchEnd = (event: TouchEvent) => {
+export const handleTouchEnd = (app: App, event: TouchEvent) => {
const editor = getCurrentEditor();
if (editor) {
document.querySelectorAll(".protyle-breadcrumb__bar--hide").forEach(item => {
@@ -44,13 +45,13 @@ export const handleTouchEnd = (event: TouchEvent) => {
return;
}
if (types.includes("block-ref")) {
- refMenu(editor.protyle, target);
+ refMenu(app, editor.protyle, target);
} else if (types.includes("file-annotation-ref")) {
editor.protyle.toolbar.showFileAnnotationRef(editor.protyle, target);
} else if (types.includes("tag")) {
- tagMenu(editor.protyle, target);
+ tagMenu(app, editor.protyle, target);
} else if (types.includes("a")) {
- linkMenu(editor.protyle, target);
+ linkMenu(app, editor.protyle, target);
}
return;
}
diff --git a/app/src/plugin/index.ts b/app/src/plugin/index.ts
index 5c462c771..67a4cc67e 100644
--- a/app/src/plugin/index.ts
+++ b/app/src/plugin/index.ts
@@ -10,6 +10,7 @@ import {getDockByType, setPanelFocus} from "../layout/util";
import {hasClosestByAttribute} from "../protyle/util/hasClosest";
export class Plugin {
+ private app: App;
public i18n: IObject;
public eventBus: EventBus;
public data: any = {};
@@ -34,6 +35,7 @@ export class Plugin {
name: string,
i18n: IObject
}) {
+ this.app = options.app;
this.i18n = options.i18n;
this.name = options.name;
this.eventBus = new EventBus(options.name);
@@ -141,6 +143,7 @@ export class Plugin {
const type2 = this.name + options.type;
this.models[type2] = (arg: { data: any, tab: Tab }) => {
const customObj = new Custom({
+ app: this.app,
tab: arg.tab,
type: type2,
data: arg.data,
@@ -173,6 +176,7 @@ export class Plugin {
config: options.config,
model: (arg: { tab: Tab }) => {
const customObj = new Custom({
+ app: this.app,
tab: arg.tab,
type: type2,
data: options.data,
diff --git a/app/src/protyle/breadcrumb/index.ts b/app/src/protyle/breadcrumb/index.ts
index 17dae65a1..b442646a2 100644
--- a/app/src/protyle/breadcrumb/index.ts
+++ b/app/src/protyle/breadcrumb/index.ts
@@ -25,6 +25,7 @@ import {hideElements} from "../ui/hideElements";
import {confirmDialog} from "../../dialog/confirmDialog";
import {reloadProtyle} from "../util/reload";
import {deleteFile} from "../../editor/deleteFile";
+import {App} from "../../index";
export class Breadcrumb {
public element: HTMLElement;
@@ -32,7 +33,7 @@ export class Breadcrumb {
private id: string;
private messageId: string;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
const element = document.createElement("div");
element.className = "protyle-breadcrumb";
const isFocus = protyle.options.action.includes(Constants.CB_GET_ALL) && !isMobile();
@@ -50,6 +51,7 @@ export class Breadcrumb {
if (protyle.options.render.breadcrumbDocName && window.siyuan.ctrlIsPressed) {
/// #if !MOBILE
openFileById({
+ app,
id,
action: id === protyle.block.rootID ? [Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL]
});
diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts
index 07a910468..6020217f0 100644
--- a/app/src/protyle/gutter/index.ts
+++ b/app/src/protyle/gutter/index.ts
@@ -38,11 +38,14 @@ import {isMobile} from "../../util/functions";
import {AIActions} from "../../ai/actions";
import {activeBlur} from "../../mobile/util/keyboardToolbar";
import {hideTooltip} from "../../dialog/tooltip";
+import {App} from "../../index";
export class Gutter {
public element: HTMLElement;
+ private app: App;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
+ this.app = app;
this.element = document.createElement("div");
this.element.className = "protyle-gutters";
if (/Mac/.test(navigator.platform) || navigator.platform === "iPhone") {
@@ -701,7 +704,7 @@ export class Gutter {
}
ids.push(item.getAttribute("data-node-id"));
});
- makeCard(ids);
+ makeCard(this.app, ids);
}
}).element);
}
@@ -1202,7 +1205,7 @@ export class Gutter {
type: "submenu",
icon: type === "NodeVideo" ? "iconVideo" : "iconRecord",
label: window.siyuan.languages.assets,
- submenu: videoMenu(protyle, nodeElement, type)
+ submenu: videoMenu(this.app, protyle, nodeElement, type)
}).element);
} else if (type === "NodeIFrame" && !protyle.disabled) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
@@ -1211,7 +1214,7 @@ export class Gutter {
type: "submenu",
icon: "iconLanguage",
label: window.siyuan.languages.assets,
- submenu: iframeMenu(protyle, nodeElement)
+ submenu: iframeMenu(this.app, protyle, nodeElement)
}).element);
} else if (type === "NodeHTMLBlock" && !protyle.disabled) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
@@ -1369,14 +1372,15 @@ export class Gutter {
window.siyuan.menus.menu.append(new MenuItem({
accelerator: window.siyuan.config.keymap.general.enterBack.custom,
label: window.siyuan.languages.enterBack,
- click() {
+ click: () => {
if (!protyle.block.showAll) {
const ids = protyle.path.split("/");
if (ids.length > 2) {
/// #if MOBILE
- openMobileFileById(ids[ids.length - 2], [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]);
+ openMobileFileById(this.app, ids[ids.length - 2], [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]);
/// #else
openFileById({
+ app: this.app,
id: ids[ids.length - 2],
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
});
@@ -1482,7 +1486,7 @@ export class Gutter {
label: window.siyuan.languages.addToDeck,
icon: "iconRiffCard",
click() {
- makeCard([nodeElement.getAttribute("data-node-id")]);
+ makeCard(this.app, [nodeElement.getAttribute("data-node-id")]);
}
}).element);
}
@@ -1497,6 +1501,9 @@ export class Gutter {
type: "readonly",
label: `${updateHTML}${window.siyuan.languages.createdAt} ${dayjs(id.substr(0, 14)).format("YYYY-MM-DD HH:mm:ss")}`,
}).element);
+ this.app.plugins.forEach((plugin) => {
+ plugin.eventBus.emit("click-blockicon", [nodeElement]);
+ });
return window.siyuan.menus.menu;
}
diff --git a/app/src/protyle/header/Background.ts b/app/src/protyle/header/Background.ts
index 121a78bcc..e8660fef6 100644
--- a/app/src/protyle/header/Background.ts
+++ b/app/src/protyle/header/Background.ts
@@ -13,6 +13,7 @@ import {popSearch} from "../../mobile/menu/search";
import {getEventName} from "../util/compatibility";
import {Dialog} from "../../dialog";
import {Constants} from "../../constants";
+import {App} from "../../index";
export class Background {
public element: HTMLElement;
@@ -22,7 +23,7 @@ export class Background {
private tagsElement: HTMLElement;
private transparentData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
this.element = document.createElement("div");
this.element.className = "protyle-background";
this.element.innerHTML = `
@@ -331,10 +332,10 @@ export class Background {
break;
} else if (type === "open-search") {
/// #if !MOBILE
- openGlobalSearch(`#${target.textContent}#`, !window.siyuan.ctrlIsPressed);
+ openGlobalSearch(app, `#${target.textContent}#`, !window.siyuan.ctrlIsPressed);
/// #else
const searchOption = window.siyuan.storage[Constants.LOCAL_SEARCHDATA];
- popSearch({
+ popSearch(app, {
removed: searchOption.removed,
sort: searchOption.sort,
group: searchOption.group,
diff --git a/app/src/protyle/header/Title.ts b/app/src/protyle/header/Title.ts
index 598dd5f79..ec9ebc00c 100644
--- a/app/src/protyle/header/Title.ts
+++ b/app/src/protyle/header/Title.ts
@@ -36,13 +36,16 @@ import {makeCard, quickMakeCard} from "../../card/makeCard";
import {viewCards} from "../../card/viewCards";
import {getNotebookName, pathPosix} from "../../util/pathName";
import {commonClick} from "../wysiwyg/commonClick";
+import {App} from "../../index";
export class Title {
public element: HTMLElement;
public editElement: HTMLElement;
private timeout: number;
+ private app: App;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
+ this.app = app;
this.element = document.createElement("div");
this.element.className = "protyle-title";
if (window.siyuan.config.editor.displayBookmarkIcon) {
@@ -90,13 +93,14 @@ export class Title {
return;
}
- if (commonHotkey(protyle, event)) {
+ if (commonHotkey(app, protyle, event)) {
return true;
}
if (matchHotKey(window.siyuan.config.keymap.general.enterBack.custom, event)) {
const ids = protyle.path.split("/");
if (ids.length > 2) {
openFileById({
+ app,
id: ids[ids.length - 2],
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
});
@@ -264,7 +268,7 @@ export class Title {
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
}, (response) => {
- commonClick(event, protyle, response.data.ial);
+ commonClick(app, event, protyle, response.data.ial);
});
});
}
@@ -330,7 +334,7 @@ export class Title {
label: window.siyuan.languages.outline,
accelerator: window.siyuan.config.keymap.editor.general.outline.custom,
click: () => {
- openOutline(protyle);
+ openOutline(this.app, protyle);
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
@@ -338,7 +342,7 @@ export class Title {
label: window.siyuan.languages.backlinks,
accelerator: window.siyuan.config.keymap.editor.general.backlinks.custom,
click: () => {
- openBacklink(protyle);
+ openBacklink(this.app, protyle);
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
@@ -346,7 +350,7 @@ export class Title {
label: window.siyuan.languages.graphView,
accelerator: window.siyuan.config.keymap.editor.general.graphView.custom,
click: () => {
- openGraph(protyle);
+ openGraph(this.app, protyle);
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
@@ -363,7 +367,7 @@ export class Title {
accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
click: () => {
fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => {
- openCardByData(response.data, "doc", protyle.block.rootID, this.editElement.textContent);
+ openCardByData(this.app, response.data, "doc", protyle.block.rootID, this.editElement.textContent);
});
}
}, {
@@ -373,7 +377,7 @@ export class Title {
fetchPost("/api/filetree/getHPathByID", {
id: protyle.block.rootID
}, (response) => {
- viewCards(protyle.block.rootID, pathPosix().join(getNotebookName(protyle.notebookId), (response.data)), "Tree");
+ viewCards(this.app, protyle.block.rootID, pathPosix().join(getNotebookName(protyle.notebookId), (response.data)), "Tree");
});
}
}, {
@@ -389,7 +393,7 @@ export class Title {
iconHTML: Constants.ZWSP,
label: window.siyuan.languages.addToDeck,
click: () => {
- makeCard([protyle.block.rootID]);
+ makeCard(this.app, [protyle.block.rootID]);
}
});
}
diff --git a/app/src/protyle/hint/index.ts b/app/src/protyle/hint/index.ts
index cfc57560c..19a5bb21f 100644
--- a/app/src/protyle/hint/index.ts
+++ b/app/src/protyle/hint/index.ts
@@ -32,17 +32,20 @@ import {processRender} from "../util/processCode";
import {AIChat} from "../../ai/chat";
import {isMobile} from "../../util/functions";
import {isCtrl} from "../util/compatibility";
+import {App} from "../../index";
export class Hint {
public timeId: number;
public element: HTMLDivElement;
public enableSlash = true;
private enableEmoji = true;
+ private app: App;
public enableExtend = false;
public splitChar = "";
public lastIndex = -1;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
+ this.app = app;
this.element = document.createElement("div");
this.element.setAttribute("data-close", "false");
// height 402 根据 .emojis max-height+8 得来
@@ -577,9 +580,10 @@ ${unicode2Emoji(emoji.unicode, true)}`;
}, () => {
insertHTML(`Untitled`, protyle);
/// #if MOBILE
- openMobileFileById(newSubDocId, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(this.app, newSubDocId, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
/// #else
openFileById({
+ app: this.app,
id: newSubDocId,
action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]
});
@@ -645,7 +649,7 @@ ${unicode2Emoji(emoji.unicode, true)}`;
});
}
const rect = imgElement.getBoundingClientRect();
- imgMenu(protyle, range, imgElement, {
+ imgMenu(this.app, protyle, range, imgElement, {
clientX: rect.left,
clientY: rect.top
});
diff --git a/app/src/protyle/index.ts b/app/src/protyle/index.ts
index ac781cabd..7be99ac99 100644
--- a/app/src/protyle/index.ts
+++ b/app/src/protyle/index.ts
@@ -28,17 +28,20 @@ import {renderBacklink} from "./wysiwyg/renderBacklink";
import {setEmpty} from "../mobile/util/setEmpty";
import {resize} from "./util/resize";
import {getDocByScroll} from "./scroll/saveScroll";
+import {App} from "../index";
export class Protyle {
public readonly version: string;
public protyle: IProtyle;
+ private app: App;
/**
* @param id 要挂载 Protyle 的元素或者元素 ID。
* @param options Protyle 参数
*/
- constructor(id: HTMLElement, options?: IOptions) {
+ constructor(app: App, id: HTMLElement, options?: IOptions) {
+ this.app = app;
this.version = Constants.SIYUAN_VERSION;
const getOptions = new Options(options);
const mergedOptions = getOptions.merge();
@@ -53,17 +56,17 @@ export class Protyle {
block: {},
};
- this.protyle.hint = new Hint(this.protyle);
+ this.protyle.hint = new Hint(app, this.protyle);
if (mergedOptions.render.breadcrumb) {
- this.protyle.breadcrumb = new Breadcrumb(this.protyle);
+ this.protyle.breadcrumb = new Breadcrumb(app, this.protyle);
}
/// #if !MOBILE
if (mergedOptions.render.title) {
- this.protyle.title = new Title(this.protyle);
+ this.protyle.title = new Title(app, this.protyle);
}
/// #endif
if (mergedOptions.render.background) {
- this.protyle.background = new Background(this.protyle);
+ this.protyle.background = new Background(app, this.protyle);
}
this.protyle.element.innerHTML = "";
@@ -72,11 +75,11 @@ export class Protyle {
this.protyle.element.appendChild(this.protyle.breadcrumb.element.parentElement);
}
this.protyle.undo = new Undo();
- this.protyle.wysiwyg = new WYSIWYG(this.protyle);
- this.protyle.toolbar = new Toolbar(this.protyle);
+ this.protyle.wysiwyg = new WYSIWYG(app, this.protyle);
+ this.protyle.toolbar = new Toolbar(app, this.protyle);
this.protyle.scroll = new Scroll(this.protyle); // 不能使用 render.scroll 来判读是否初始化,除非重构后面用到的相关变量
if (this.protyle.options.render.gutter) {
- this.protyle.gutter = new Gutter(this.protyle);
+ this.protyle.gutter = new Gutter(app, this.protyle);
}
if (mergedOptions.upload.url || mergedOptions.upload.handler) {
this.protyle.upload = new Upload();
@@ -85,6 +88,7 @@ export class Protyle {
this.init();
if (!mergedOptions.action.includes(Constants.CB_GET_HISTORY)) {
this.protyle.ws = new Model({
+ app,
id: this.protyle.id,
type: "protyle",
msgCallback: (data) => {
@@ -170,7 +174,7 @@ export class Protyle {
case "unmount":
if (this.protyle.notebookId === data.data.box) {
/// #if MOBILE
- setEmpty();
+ setEmpty(app);
/// #else
if (this.protyle.model) {
this.protyle.model.parent.parent.removeTab(this.protyle.model.parent.id, false, false);
@@ -181,7 +185,7 @@ export class Protyle {
case "removeDoc":
if (data.data.ids.includes(this.protyle.block.rootID)) {
/// #if MOBILE
- setEmpty();
+ setEmpty(app);
/// #else
if (this.protyle.model) {
this.protyle.model.parent.parent.removeTab(this.protyle.model.parent.id, false, false);
@@ -325,7 +329,7 @@ export class Protyle {
sanitize: this.protyle.options.preview.markdown.sanitize,
});
- this.protyle.preview = new Preview(this.protyle);
+ this.protyle.preview = new Preview(this.app, this.protyle);
initUI(this.protyle);
}
diff --git a/app/src/protyle/preview/index.ts b/app/src/protyle/preview/index.ts
index 076f0e1d5..ef3813978 100644
--- a/app/src/protyle/preview/index.ts
+++ b/app/src/protyle/preview/index.ts
@@ -17,13 +17,14 @@ import {fetchPost} from "../../util/fetch";
import {processRender} from "../util/processCode";
import {highlightRender} from "../markdown/highlightRender";
import {speechRender} from "../markdown/speechRender";
+import {App} from "../../index";
export class Preview {
public element: HTMLElement;
public previewElement: HTMLElement;
private mdTimeoutId: number;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
this.element = document.createElement("div");
this.element.className = "protyle-preview fn__none";
@@ -55,7 +56,7 @@ export class Preview {
if (isLocalPath(linkAddress)) {
/// #if !MOBILE
if (Constants.SIYUAN_ASSETS_EXTS.includes(pathPosix().extname((linkAddress.split("?page")[0])))) {
- openAsset(linkAddress.split("?page")[0], parseInt(getSearch("page", linkAddress)));
+ openAsset(app, linkAddress.split("?page")[0], parseInt(getSearch("page", linkAddress)));
} else {
/// #if !BROWSER
openBy(linkAddress, "folder");
diff --git a/app/src/protyle/toolbar/Link.ts b/app/src/protyle/toolbar/Link.ts
index 063c4bb69..4de95126a 100644
--- a/app/src/protyle/toolbar/Link.ts
+++ b/app/src/protyle/toolbar/Link.ts
@@ -4,11 +4,12 @@ import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
import {focusByRange, focusByWbr} from "../util/selection";
import {readText} from "../util/compatibility";
import {Constants} from "../../constants";
+import {App} from "../../index";
export class Link extends ToolbarItem {
public element: HTMLElement;
- constructor(protyle: IProtyle, menuItem: IMenuItem) {
+ constructor(app: App, protyle: IProtyle, menuItem: IMenuItem) {
super(protyle, menuItem);
// 不能用 getEventName,否则会导致光标位置变动到点击的文档中
this.element.addEventListener("click", async (event: MouseEvent & { changedTouches: MouseEvent[] }) => {
@@ -22,7 +23,7 @@ export class Link extends ToolbarItem {
}
const aElement = hasClosestByAttribute(range.startContainer, "data-type", "a");
if (aElement) {
- linkMenu(protyle, aElement);
+ linkMenu(app, protyle, aElement);
return;
}
diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts
index 6fda70775..b7b3c02ab 100644
--- a/app/src/protyle/toolbar/index.ts
+++ b/app/src/protyle/toolbar/index.ts
@@ -42,6 +42,7 @@ import {mathRender} from "../markdown/mathRender";
import {linkMenu} from "../../menus/protyle";
import {addScript} from "../util/addScript";
import {confirmDialog} from "../../dialog/confirmDialog";
+import {App} from "../../index";
export class Toolbar {
public element: HTMLElement;
@@ -49,10 +50,11 @@ export class Toolbar {
public subElementCloseCB: () => void;
public range: Range;
private toolbarHeight: number;
+ private app: App;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
const options = protyle.options;
-
+ this.app = app;
const element = document.createElement("div");
element.className = "protyle-toolbar fn__none";
this.element = element;
@@ -224,7 +226,7 @@ export class Toolbar {
menuItemObj = new Font(protyle, menuItem);
break;
case "a":
- menuItemObj = new Link(protyle, menuItem);
+ menuItemObj = new Link(this.app, protyle, menuItem);
break;
}
if (!menuItemObj) {
@@ -500,23 +502,23 @@ export class Toolbar {
} else if (type === "block-ref" && (types.includes("a") || types.includes("file-annotation-ref"))) {
// 虚拟引用和链接/标注不能同时存在
types.find((item, index) => {
- if (item === "a"||item === "file-annotation-ref") {
+ if (item === "a" || item === "file-annotation-ref") {
types.splice(index, 1);
return true;
}
});
- } else if (type === "a" && (types.includes("block-ref")|| types.includes("file-annotation-ref"))) {
+ } else if (type === "a" && (types.includes("block-ref") || types.includes("file-annotation-ref"))) {
// 链接和引用/标注不能同时存在
types.find((item, index) => {
- if (item === "block-ref"||item === "file-annotation-ref") {
+ if (item === "block-ref" || item === "file-annotation-ref") {
types.splice(index, 1);
return true;
}
});
- } else if (type === "file-annotation-ref" && (types.includes("block-ref")|| types.includes("a"))) {
+ } else if (type === "file-annotation-ref" && (types.includes("block-ref") || types.includes("a"))) {
// 引用和链接/标注不能同时存在
types.find((item, index) => {
- if (item === "block-ref"||item === "a") {
+ if (item === "block-ref" || item === "a") {
types.splice(index, 1);
return true;
}
@@ -728,7 +730,7 @@ export class Toolbar {
const aElement = newNodes[0] as HTMLElement;
if (aElement.textContent.replace(Constants.ZWSP, "") === "" || !aElement.getAttribute("data-href")) {
needFocus = false;
- linkMenu(protyle, aElement, aElement.getAttribute("data-href") ? true : false);
+ linkMenu(this.app, protyle, aElement, aElement.getAttribute("data-href") ? true : false);
} else {
this.range.collapse(false);
}
diff --git a/app/src/protyle/wysiwyg/commonClick.ts b/app/src/protyle/wysiwyg/commonClick.ts
index f54b6289a..b2849111e 100644
--- a/app/src/protyle/wysiwyg/commonClick.ts
+++ b/app/src/protyle/wysiwyg/commonClick.ts
@@ -4,8 +4,9 @@ import {openAttr, openFileAttr} from "../../menus/commonMenuItem";
import {openGlobalSearch} from "../../search/util";
/// #endif
import {isMobile} from "../../util/functions";
+import {App} from "../../index";
-export const commonClick = (event: MouseEvent & {
+export const commonClick = (app: App, event: MouseEvent & {
target: HTMLElement
}, protyle: IProtyle, data?:IObject) => {
const isM = isMobile();
@@ -13,7 +14,7 @@ export const commonClick = (event: MouseEvent & {
if (attrBookmarkElement) {
if (!isM && (event.ctrlKey || event.metaKey)) {
/// #if !MOBILE
- openGlobalSearch(attrBookmarkElement.textContent.trim(), true);
+ openGlobalSearch(app, attrBookmarkElement.textContent.trim(), true);
/// #endif
} else {
if (data) {
@@ -30,7 +31,7 @@ export const commonClick = (event: MouseEvent & {
if (attrNameElement) {
if (!isM && (event.ctrlKey || event.metaKey)) {
/// #if !MOBILE
- openGlobalSearch(attrNameElement.textContent.trim(), true);
+ openGlobalSearch(app, attrNameElement.textContent.trim(), true);
/// #endif
} else {
if (data ) {
@@ -47,7 +48,7 @@ export const commonClick = (event: MouseEvent & {
if (attrAliasElement) {
if (!isM && (event.ctrlKey || event.metaKey)) {
/// #if !MOBILE
- openGlobalSearch(attrAliasElement.textContent.trim(), true);
+ openGlobalSearch(app, attrAliasElement.textContent.trim(), true);
/// #endif
} else {
if (data) {
@@ -64,7 +65,7 @@ export const commonClick = (event: MouseEvent & {
if (attrMemoElement) {
if (!isM && (event.ctrlKey || event.metaKey)) {
/// #if !MOBILE
- openGlobalSearch(attrMemoElement.getAttribute("aria-label").trim(), true);
+ openGlobalSearch(app, attrMemoElement.getAttribute("aria-label").trim(), true);
/// #endif
} else {
if (data) {
diff --git a/app/src/protyle/wysiwyg/commonHotkey.ts b/app/src/protyle/wysiwyg/commonHotkey.ts
index d538fd561..bef602c33 100644
--- a/app/src/protyle/wysiwyg/commonHotkey.ts
+++ b/app/src/protyle/wysiwyg/commonHotkey.ts
@@ -20,8 +20,9 @@ import {transaction, updateTransaction} from "./transaction";
import {onGet} from "../util/onGet";
import {Constants} from "../../constants";
import * as dayjs from "dayjs";
+import {App} from "../../index";
-export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
+export const commonHotkey = (app: App, protyle: IProtyle, event: KeyboardEvent) => {
const target = event.target as HTMLElement;
if (matchHotKey(window.siyuan.config.keymap.editor.general.copyHPath.custom, event)) {
fetchPost("/api/filetree/getHPathByID", {
@@ -51,20 +52,20 @@ export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
if (matchHotKey(window.siyuan.config.keymap.editor.general.backlinks.custom, event)) {
event.preventDefault();
event.stopPropagation();
- openBacklink(protyle);
+ openBacklink(app, protyle);
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.general.graphView.custom, event)) {
event.preventDefault();
event.stopPropagation();
- openGraph(protyle);
+ openGraph(app, protyle);
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.general.outline.custom, event)) {
event.preventDefault();
event.stopPropagation();
const offset = getSelectionOffset(target);
- openOutline(protyle);
+ openOutline(app, protyle);
// switchWnd 后,range会被清空,需要重新设置
focusByOffset(target, offset.start, offset.end);
return true;
diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts
index 1941300d3..84856d774 100644
--- a/app/src/protyle/wysiwyg/index.ts
+++ b/app/src/protyle/wysiwyg/index.ts
@@ -66,14 +66,17 @@ import {getBacklinkHeadingMore, loadBreadcrumb} from "./renderBacklink";
import {removeSearchMark} from "../toolbar/util";
import {activeBlur, hideKeyboardToolbar} from "../../mobile/util/keyboardToolbar";
import {commonClick} from "./commonClick";
+import {App} from "../../index";
export class WYSIWYG {
public lastHTMLs: { [key: string]: string } = {};
public element: HTMLDivElement;
public preventKeyup: boolean;
+ private app: App;
- constructor(protyle: IProtyle) {
+ constructor(app: App, protyle: IProtyle) {
+ this.app = app;
this.element = document.createElement("div");
this.element.className = "protyle-wysiwyg";
this.element.setAttribute("spellcheck", "false");
@@ -91,7 +94,7 @@ export class WYSIWYG {
return;
}
this.bindEvent(protyle);
- keydown(protyle, this.element);
+ keydown(app, protyle, this.element);
dropEvent(protyle, this.element);
}
@@ -1216,7 +1219,7 @@ export class WYSIWYG {
removeSearchMark(target);
}
if (types.includes("block-ref") && !protyle.disabled) {
- refMenu(protyle, target);
+ refMenu(this.app, protyle, target);
// 阻止 popover
target.setAttribute("prevent-popover", "true");
setTimeout(() => {
@@ -1227,13 +1230,13 @@ export class WYSIWYG {
protyle.toolbar.showFileAnnotationRef(protyle, target);
return false;
} else if (types.includes("tag") && !protyle.disabled) {
- tagMenu(protyle, target);
+ tagMenu(this.app, protyle, target);
return false;
} else if (types.includes("inline-memo")) {
protyle.toolbar.showRender(protyle, target);
return false;
} else if (types.includes("a") && !protyle.disabled) {
- linkMenu(protyle, target);
+ linkMenu(this.app, protyle, target);
if (window.siyuan.config.editor.floatWindowMode === 0 &&
target.getAttribute("data-href")?.startsWith("siyuan://blocks")) {
// 阻止 popover
@@ -1246,7 +1249,7 @@ export class WYSIWYG {
}
}
if (!protyle.disabled && target.tagName === "IMG" && hasClosestByClassName(target, "img")) {
- imgMenu(protyle, protyle.toolbar.range, target.parentElement.parentElement, {
+ imgMenu(this.app, protyle, protyle.toolbar.range, target.parentElement.parentElement, {
clientX: x + 4,
clientY: y
});
@@ -1509,6 +1512,7 @@ export class WYSIWYG {
if (ctrlIsPressed) {
fetchPost("/api/block/checkBlockFold", {id: breadcrumbId}, (foldResponse) => {
openFileById({
+ app: this.app,
id: breadcrumbId,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
zoomIn: foldResponse.data
@@ -1567,7 +1571,7 @@ export class WYSIWYG {
fetchPost("/api/block/checkBlockFold", {id: refBlockId}, (foldResponse) => {
/// #if MOBILE
- openMobileFileById(refBlockId, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(this.app, refBlockId, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
activeBlur();
hideKeyboardToolbar();
/// #else
@@ -1577,6 +1581,7 @@ export class WYSIWYG {
}
if (event.shiftKey) {
openFileById({
+ app: this.app,
id: refBlockId,
position: "bottom",
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
@@ -1584,6 +1589,7 @@ export class WYSIWYG {
});
} else if (event.altKey) {
openFileById({
+ app: this.app,
id: refBlockId,
position: "right",
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
@@ -1591,6 +1597,7 @@ export class WYSIWYG {
});
} else if (ctrlIsPressed) {
openFileById({
+ app: this.app,
id: refBlockId,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT],
keepCursor: true,
@@ -1598,6 +1605,7 @@ export class WYSIWYG {
});
} else {
openFileById({
+ app: this.app,
id: refBlockId,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
zoomIn: foldResponse.data
@@ -1636,7 +1644,7 @@ export class WYSIWYG {
} else if (event.shiftKey) {
openBy(linkAddress, "app");
} else {
- openAsset(linkAddress, fileIds[2], "right");
+ openAsset(this.app, linkAddress, fileIds[2], "right");
}
/// #endif
return;
@@ -1660,7 +1668,7 @@ export class WYSIWYG {
} else if (event.shiftKey) {
openBy(linkAddress, "app");
} else {
- openAsset(linkPathname, parseInt(getSearch("page", linkAddress)), "right");
+ openAsset(this.app, linkPathname, parseInt(getSearch("page", linkAddress)), "right");
}
} else {
/// #if !BROWSER
@@ -1689,11 +1697,11 @@ export class WYSIWYG {
const tagElement = hasClosestByAttribute(event.target, "data-type", "tag");
if (tagElement && !event.altKey) {
/// #if !MOBILE
- openGlobalSearch(`#${tagElement.textContent}#`, !ctrlIsPressed);
+ openGlobalSearch(this.app, `#${tagElement.textContent}#`, !ctrlIsPressed);
hideElements(["dialog"]);
/// #else
const searchOption = window.siyuan.storage[Constants.LOCAL_SEARCHDATA];
- popSearch({
+ popSearch(this.app, {
removed: searchOption.removed,
sort: searchOption.sort,
group: searchOption.group,
@@ -1714,12 +1722,13 @@ export class WYSIWYG {
if (embedItemElement) {
const embedId = embedItemElement.getAttribute("data-id");
/// #if MOBILE
- openMobileFileById(embedId, [Constants.CB_GET_ALL]);
+ openMobileFileById(this.app, embedId, [Constants.CB_GET_ALL]);
activeBlur();
hideKeyboardToolbar();
/// #else
if (event.shiftKey) {
openFileById({
+ app: this.app,
id: embedId,
position: "bottom",
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL],
@@ -1727,6 +1736,7 @@ export class WYSIWYG {
});
} else if (event.altKey) {
openFileById({
+ app: this.app,
id: embedId,
position: "right",
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL],
@@ -1734,6 +1744,7 @@ export class WYSIWYG {
});
} else if (ctrlIsPressed) {
openFileById({
+ app: this.app,
id: embedId,
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL],
keepCursor: true,
@@ -1741,6 +1752,7 @@ export class WYSIWYG {
});
} else if (!protyle.disabled) {
window.siyuan.blockPanels.push(new BlockPanel({
+ app: this.app,
targetElement: embedItemElement,
nodeIds: [embedId],
}));
@@ -1750,7 +1762,7 @@ export class WYSIWYG {
return;
}
- if (commonClick(event, protyle)) {
+ if (commonClick(this.app, event, protyle)) {
return;
}
@@ -1815,7 +1827,7 @@ export class WYSIWYG {
if (actionElement) {
const type = actionElement.parentElement.parentElement.getAttribute("data-type");
if (type === "img" && !protyle.disabled) {
- imgMenu(protyle, range, actionElement.parentElement.parentElement, {
+ imgMenu(this.app, protyle, range, actionElement.parentElement.parentElement, {
clientX: event.clientX + 4,
clientY: event.clientY
});
diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts
index 04c7b6d15..d280bfb42 100644
--- a/app/src/protyle/wysiwyg/keydown.ts
+++ b/app/src/protyle/wysiwyg/keydown.ts
@@ -71,8 +71,9 @@ import {escapeHtml} from "../../util/escape";
import {insertHTML} from "../util/insertHTML";
import {quickMakeCard} from "../../card/makeCard";
import {removeSearchMark} from "../toolbar/util";
+import {App} from "../../index";
-export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
+export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) => {
editorElement.addEventListener("keydown", (event: KeyboardEvent & { target: HTMLElement }) => {
if (event.target.localName === "protyle-html") {
event.stopPropagation();
@@ -441,6 +442,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
const ids = protyle.path.split("/");
if (ids.length > 2) {
openFileById({
+ app,
id: ids[ids.length - 2],
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
});
@@ -530,7 +532,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
removeSearchMark(inlineElement);
}
if (types.includes("block-ref")) {
- refMenu(protyle, inlineElement);
+ refMenu(app, protyle, inlineElement);
return;
} else if (types.includes("inline-memo")) {
protyle.toolbar.showRender(protyle, inlineElement);
@@ -539,10 +541,10 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
protyle.toolbar.showFileAnnotationRef(protyle, inlineElement);
return;
} else if (types.includes("a")) {
- linkMenu(protyle, inlineElement);
+ linkMenu(app, protyle, inlineElement);
return;
} else if (types.includes("tag")) {
- tagMenu(protyle, inlineElement);
+ tagMenu(app, protyle, inlineElement);
return;
}
}
@@ -952,7 +954,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
return true;
}
/// #if !MOBILE
- if (commonHotkey(protyle, event)) {
+ if (commonHotkey(app, protyle, event)) {
return true;
}
/// #endif
@@ -1588,6 +1590,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
if (matchHotKey(window.siyuan.config.keymap.editor.general.openBy.custom, event)) {
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
zoomIn: foldResponse.data
@@ -1600,6 +1603,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
// 打开块引和编辑器中引用、反链、书签中点击事件需保持一致,都加载上下文
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT],
keepCursor: true,
@@ -1612,6 +1616,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
} else if (matchHotKey(window.siyuan.config.keymap.editor.general.insertRight.custom, event)) {
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
position: "right",
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
@@ -1624,6 +1629,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
} else if (matchHotKey(window.siyuan.config.keymap.editor.general.insertBottom.custom, event)) {
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
position: "bottom",
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
@@ -1636,6 +1642,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
} else if (matchHotKey(window.siyuan.config.keymap.editor.general.refPopover.custom, event)) {
// open popover
window.siyuan.blockPanels.push(new BlockPanel({
+ app,
targetElement: refElement,
nodeIds: [id],
}));
diff --git a/app/src/search/index.ts b/app/src/search/index.ts
index dae84db03..f63d682f2 100644
--- a/app/src/search/index.ts
+++ b/app/src/search/index.ts
@@ -3,19 +3,21 @@ import {Tab} from "../layout/Tab";
import {Protyle} from "../protyle";
import {genSearch} from "./util";
import {setPanelFocus} from "../layout/util";
+import {App} from "../index";
export class Search extends Model {
private element: HTMLElement;
public config: ISearchOption;
public edit: Protyle;
- constructor(options: { tab: Tab, config: ISearchOption }) {
+ constructor(options: { tab: Tab, config: ISearchOption, app: App }) {
super({
+ app: options.app,
id: options.tab.id,
});
this.element = options.tab.panelElement as HTMLElement;
this.config = options.config;
- this.edit = genSearch(this.config, this.element);
+ this.edit = genSearch(options.app, this.config, this.element);
this.element.addEventListener("click", () => {
setPanelFocus(this.element.parentElement.parentElement);
});
diff --git a/app/src/search/spread.ts b/app/src/search/spread.ts
index 67371e848..bb069bbee 100644
--- a/app/src/search/spread.ts
+++ b/app/src/search/spread.ts
@@ -4,35 +4,42 @@ import {Dialog} from "../dialog";
import {fetchSyncPost} from "../util/fetch";
import {focusByRange} from "../protyle/util/selection";
import {genSearch} from "./util";
+import {App} from "../index";
-export const openSearch = async (hotkey: string, key?: string, notebookId?: string, searchPath?: string) => {
+export const openSearch = async (options: {
+ app: App,
+ hotkey: string,
+ key?: string,
+ notebookId?: string,
+ searchPath?: string
+}) => {
const exitDialog = window.siyuan.dialogs.find((item) => {
if (item.element.querySelector("#searchList")) {
const lastKey = item.element.getAttribute("data-key");
const replaceHeaderElement = item.element.querySelectorAll(".search__header")[1];
- if (lastKey !== hotkey && hotkey === window.siyuan.config.keymap.general.replace.custom && replaceHeaderElement.classList.contains("fn__none")) {
+ if (lastKey !== options.hotkey && options.hotkey === window.siyuan.config.keymap.general.replace.custom && replaceHeaderElement.classList.contains("fn__none")) {
replaceHeaderElement.classList.remove("fn__none");
- item.element.setAttribute("data-key", hotkey);
+ item.element.setAttribute("data-key", options.hotkey);
return true;
}
const searchPathElement = item.element.querySelector("#searchPathInput");
- if (lastKey !== hotkey && hotkey === window.siyuan.config.keymap.general.globalSearch.custom) {
+ if (lastKey !== options.hotkey && options.hotkey === window.siyuan.config.keymap.general.globalSearch.custom) {
if (searchPathElement.textContent !== "") {
item.destroy();
return false;
} else if (!replaceHeaderElement.classList.contains("fn__none")) {
replaceHeaderElement.classList.add("fn__none");
- item.element.setAttribute("data-key", hotkey);
+ item.element.setAttribute("data-key", options.hotkey);
return true;
}
}
- if (lastKey !== hotkey && hotkey === window.siyuan.config.keymap.general.search.custom) {
+ if (lastKey !== options.hotkey && options.hotkey === window.siyuan.config.keymap.general.search.custom) {
if (searchPathElement.textContent === "") {
item.destroy();
return false;
} else if (!replaceHeaderElement.classList.contains("fn__none")) {
replaceHeaderElement.classList.add("fn__none");
- item.element.setAttribute("data-key", hotkey);
+ item.element.setAttribute("data-key", options.hotkey);
return true;
}
}
@@ -47,18 +54,18 @@ export const openSearch = async (hotkey: string, key?: string, notebookId?: stri
const localData = window.siyuan.storage[Constants.LOCAL_SEARCHDATA];
let hPath = "";
let idPath: string[] = [];
- if (notebookId) {
- hPath = getNotebookName(notebookId);
- idPath.push(notebookId);
- if (searchPath && searchPath !== "/") {
+ if (options.notebookId) {
+ hPath = getNotebookName(options.notebookId);
+ idPath.push(options.notebookId);
+ if (options.searchPath && options.searchPath !== "/") {
const response = await fetchSyncPost("/api/filetree/getHPathByPath", {
- notebook: notebookId,
- path: searchPath.endsWith(".sy") ? searchPath : searchPath + ".sy"
+ notebook: options.notebookId,
+ path: options.searchPath.endsWith(".sy") ? options.searchPath : options.searchPath + ".sy"
});
hPath = pathPosix().join(hPath, response.data);
- idPath[0] = pathPosix().join(idPath[0], searchPath);
+ idPath[0] = pathPosix().join(idPath[0], options.searchPath);
}
- } else if (window.siyuan.config.keymap.general.globalSearch.custom === hotkey) {
+ } else if (window.siyuan.config.keymap.general.globalSearch.custom === options.hotkey) {
hPath = localData.hPath;
idPath = localData.idPath;
// 历史原因,2.5.2 之前为 string https://github.com/siyuan-note/siyuan/issues/6902
@@ -84,19 +91,19 @@ export const openSearch = async (hotkey: string, key?: string, notebookId?: stri
}
}
});
- dialog.element.setAttribute("data-key", hotkey);
- const edit = genSearch({
+ dialog.element.setAttribute("data-key", options.hotkey);
+ const edit = genSearch( options.app, {
removed: localData.removed,
- k: key || localData.k,
+ k: options.key || localData.k,
r: localData.r,
- hasReplace: hotkey === window.siyuan.config.keymap.general.replace.custom,
+ hasReplace: options.hotkey === window.siyuan.config.keymap.general.replace.custom,
method: localData.method,
hPath,
idPath,
group: localData.group,
sort: localData.sort,
types: Object.assign({}, localData.types),
- page: key ? 1 : localData.page
+ page: options.key ? 1 : localData.page
}, dialog.element.querySelector(".b3-dialog__container").lastElementChild, () => {
dialog.destroy({focus: "false"});
});
diff --git a/app/src/search/util.ts b/app/src/search/util.ts
index fc2ccb8ae..9a56259b2 100644
--- a/app/src/search/util.ts
+++ b/app/src/search/util.ts
@@ -17,6 +17,7 @@ import {setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility";
import {newFileByName} from "../util/newFile";
import {matchHotKey} from "../protyle/util/hotKey";
import {filterMenu, getKeyByLiElement, initCriteriaMenu, moreMenu, queryMenu} from "./menu";
+import {App} from "../index";
const saveKeyList = (type: "keys" | "replaceKeys", value: string) => {
let list: string[] = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS][type];
@@ -30,7 +31,7 @@ const saveKeyList = (type: "keys" | "replaceKeys", value: string) => {
setStorageVal(Constants.LOCAL_SEARCHKEYS, window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]);
};
-export const openGlobalSearch = (text: string, replace: boolean) => {
+export const openGlobalSearch = (app: App, text: string, replace: boolean) => {
text = text.trim();
const searchModel = getAllModels().search.find((item) => {
item.parent.parent.switchTab(item.parent.headElement);
@@ -42,6 +43,7 @@ export const openGlobalSearch = (text: string, replace: boolean) => {
}
const localData = window.siyuan.storage[Constants.LOCAL_SEARCHDATA];
openFile({
+ app,
searchData: {
k: text,
r: "",
@@ -60,7 +62,7 @@ export const openGlobalSearch = (text: string, replace: boolean) => {
};
// closeCB 不存在为页签搜索
-export const genSearch = (config: ISearchOption, element: Element, closeCB?: () => void) => {
+export const genSearch = (app: App, config: ISearchOption, element: Element, closeCB?: () => void) => {
let methodText = window.siyuan.languages.keyword;
if (config.method === 1) {
methodText = window.siyuan.languages.querySyntax;
@@ -181,7 +183,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
const historyElement = element.querySelector("#searchHistoryList");
const lineHeight = 30;
- const edit = new Protyle(element.querySelector("#searchPreview") as HTMLElement, {
+ const edit = new Protyle(app, element.querySelector("#searchPreview") as HTMLElement, {
blockId: "",
render: {
gutter: true,
@@ -409,7 +411,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
} else if (target.id === "searchOpen") {
config.k = searchInputElement.value;
config.r = replaceInputElement.value;
- openFile({searchData: config, position: "right"});
+ openFile({app, searchData: config, position: "right"});
if (closeCB) {
closeCB();
}
@@ -599,7 +601,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
replaceInputElement.value = target.textContent;
replaceHistoryElement.classList.add("fn__none");
} else if (type === "search-new") {
- newFileByName(searchInputElement.value);
+ newFileByName(app, searchInputElement.value);
} else if (type === "search-item") {
if (event.detail === 1) {
clickTimeout = window.setTimeout(() => {
@@ -607,6 +609,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
const id = target.getAttribute("data-node-id");
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
zoomIn: foldResponse.data,
@@ -639,6 +642,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
const id = target.getAttribute("data-node-id");
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
zoomIn: foldResponse.data
@@ -685,7 +689,7 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
return;
}
if (searchInputElement.value && matchHotKey(window.siyuan.config.keymap.general.newFile.custom, event)) {
- newFileByName(searchInputElement.value);
+ newFileByName(app, searchInputElement.value);
event.preventDefault();
event.stopPropagation();
return;
@@ -693,11 +697,12 @@ export const genSearch = (config: ISearchOption, element: Element, closeCB?: ()
const focusIsNew = currentList.getAttribute("data-type") === "search-new";
if (event.key === "Enter") {
if (focusIsNew) {
- newFileByName(searchInputElement.value);
+ newFileByName(app, searchInputElement.value);
} else {
const id = currentList.getAttribute("data-node-id");
fetchPost("/api/block/checkBlockFold", {id}, (foldResponse) => {
openFileById({
+ app,
id,
action: foldResponse.data ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
zoomIn: foldResponse.data
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index e4c620b08..034895281 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -22,7 +22,7 @@ type TOperation =
| "removeFlashcards"
type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins"
type TCardType = "doc" | "notebook" | "all"
-type TEventBus = "ws-main"
+type TEventBus = "ws-main" | "click-blockicon"
declare module "blueimp-md5"
@@ -316,6 +316,7 @@ declare interface IPluginDockTab {
}
declare interface IOpenFileOptions {
+ app: import("../index").App,
searchData?: ISearchOption, // 搜索必填
// card 和自定义页签 必填
custom?: {
diff --git a/app/src/util/backForward.ts b/app/src/util/backForward.ts
index 282027ad5..f65d14187 100644
--- a/app/src/util/backForward.ts
+++ b/app/src/util/backForward.ts
@@ -13,11 +13,12 @@ import {zoomOut} from "../menus/protyle";
import {showMessage} from "../dialog/message";
import {saveScroll} from "../protyle/scroll/saveScroll";
import {getAllModels} from "../layout/getAll";
+import {App} from "../index";
let forwardStack: IBackStack[] = [];
let previousIsBack = false;
-const focusStack = async (stack: IBackStack) => {
+const focusStack = async (app: App, stack: IBackStack) => {
hideElements(["gutter", "toolbar", "hint", "util", "dialog"], stack.protyle);
let blockElement: HTMLElement;
if (!document.contains(stack.protyle.element)) {
@@ -52,6 +53,7 @@ const focusStack = async (stack: IBackStack) => {
scrollAttr.focusStart = stack.position.start;
scrollAttr.focusEnd = stack.position.end;
const editor = new Editor({
+ app: app,
tab,
scrollAttr,
blockId: stack.zoomId || stack.protyle.block.rootID,
@@ -172,10 +174,10 @@ const focusStack = async (stack: IBackStack) => {
}
};
-export const goBack = async () => {
+export const goBack = async (app: App) => {
if (window.siyuan.backStack.length === 0) {
if (forwardStack.length > 0) {
- await focusStack(forwardStack[forwardStack.length - 1]);
+ await focusStack(app, forwardStack[forwardStack.length - 1]);
}
return;
}
@@ -187,7 +189,7 @@ export const goBack = async () => {
}
let stack = window.siyuan.backStack.pop();
while (stack) {
- const isFocus = await focusStack(stack);
+ const isFocus = await focusStack(app, stack);
if (isFocus) {
forwardStack.push(stack);
break;
@@ -201,10 +203,10 @@ export const goBack = async () => {
}
};
-export const goForward = async () => {
+export const goForward = async (app: App) => {
if (forwardStack.length === 0) {
if (window.siyuan.backStack.length > 0) {
- await focusStack(window.siyuan.backStack[window.siyuan.backStack.length - 1]);
+ await focusStack(app, window.siyuan.backStack[window.siyuan.backStack.length - 1]);
}
return;
}
@@ -215,7 +217,7 @@ export const goForward = async () => {
let stack = forwardStack.pop();
while (stack) {
- const isFocus = await focusStack(stack);
+ const isFocus = await focusStack(app, stack);
if (isFocus) {
window.siyuan.backStack.push(stack);
break;
diff --git a/app/src/util/newFile.ts b/app/src/util/newFile.ts
index c5280a757..99fd11969 100644
--- a/app/src/util/newFile.ts
+++ b/app/src/util/newFile.ts
@@ -12,6 +12,7 @@ import {Constants} from "../constants";
import {replaceFileName, validateName} from "../editor/rename";
import {hideElements} from "../protyle/ui/hideElements";
import {openMobileFileById} from "../mobile/editor";
+import {App} from "../index";
export const getNewFilePath = (useSavePath: boolean) => {
let notebookId = "";
@@ -62,7 +63,7 @@ export const getNewFilePath = (useSavePath: boolean) => {
return {notebookId, currentPath};
};
-export const newFile = (notebookId?: string, currentPath?: string, paths?: string[], useSavePath = false) => {
+export const newFile = (app: App, notebookId?: string, currentPath?: string, paths?: string[], useSavePath = false) => {
if (getOpenNotebookCount() === 0) {
showMessage(window.siyuan.languages.newFileTip);
return;
@@ -81,9 +82,9 @@ export const newFile = (notebookId?: string, currentPath?: string, paths?: strin
markdown: ""
}, response => {
/// #if !MOBILE
- openFileById({id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
+ openFileById({app, id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
/// #else
- openMobileFileById(response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(app, response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
/// #endif
});
} else {
@@ -97,9 +98,9 @@ export const newFile = (notebookId?: string, currentPath?: string, paths?: strin
markdown: ""
}, response => {
/// #if !MOBILE
- openFileById({id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
+ openFileById({app, id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
/// #else
- openMobileFileById(response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(app, response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
/// #endif
});
});
@@ -123,9 +124,9 @@ export const newFile = (notebookId?: string, currentPath?: string, paths?: strin
sorts: paths
}, () => {
/// #if !MOBILE
- openFileById({id, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
+ openFileById({app, id, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
/// #else
- openMobileFileById(id, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(app, id, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
/// #endif
});
}
@@ -158,7 +159,7 @@ export const getSavePath = (pathString: string, notebookId: string, cb: (p: stri
});
};
-export const newFileByName = (value: string) => {
+export const newFileByName = (app: App, value: string) => {
const newData = getNewFilePath(true);
fetchPost("/api/filetree/getHPathByPath", {
notebook: newData.notebookId,
@@ -171,9 +172,9 @@ export const newFileByName = (value: string) => {
}, response => {
hideElements(["dialog"]);
/// #if MOBILE
- openMobileFileById(response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
+ openMobileFileById(app, response.data, [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]);
/// #else
- openFileById({id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
+ openFileById({app, id: response.data, action: [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT]});
/// #endif
});
});
diff --git a/app/src/window/index.ts b/app/src/window/index.ts
index 76123bcfd..11118a4c0 100644
--- a/app/src/window/index.ts
+++ b/app/src/window/index.ts
@@ -40,6 +40,7 @@ class App {
ctrlIsPressed: false,
altIsPressed: false,
ws: new Model({
+ app: this,
id: genUUID(),
type: "main",
msgCallback: (data) => {
@@ -49,7 +50,7 @@ class App {
if (data) {
switch (data.cmd) {
case "syncMergeResult":
- reloadSync(data.data);
+ reloadSync(this, data.data);
break;
case "progress":
progressLoading(data);
@@ -116,10 +117,10 @@ class App {
}
break;
case "createdailynote":
- openFileById({id: data.data.id, action: [Constants.CB_GET_FOCUS]});
+ openFileById({app: this, id: data.data.id, action: [Constants.CB_GET_FOCUS]});
break;
case "openFileById":
- openFileById({id: data.data.id, action: [Constants.CB_GET_FOCUS]});
+ openFileById({app: this, id: data.data.id, action: [Constants.CB_GET_FOCUS]});
break;
}
}
@@ -131,11 +132,11 @@ class App {
getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
window.siyuan.languages = lauguages;
- window.siyuan.menus = new Menus(siyuanApp);
+ window.siyuan.menus = new Menus(this);
fetchPost("/api/setting/getCloudUser", {}, userResponse => {
window.siyuan.user = userResponse.data;
- loadPlugins(siyuanApp);
- init(siyuanApp);
+ loadPlugins(this);
+ init(this);
setTitle(window.siyuan.languages.siyuanNote);
initMessage();
});
@@ -143,12 +144,12 @@ class App {
});
});
setNoteBook();
- initBlockPopover();
+ initBlockPopover(this);
promiseTransactions();
}
}
-const siyuanApp = new App();
+new App();
// 再次点击新窗口已打开的 PDF 时,需进行定位
window.newWindow = {
diff --git a/app/src/window/init.ts b/app/src/window/init.ts
index 611dc4747..af4483d6d 100644
--- a/app/src/window/init.ts
+++ b/app/src/window/init.ts
@@ -39,7 +39,7 @@ export const init = (app: App) => {
window.siyuan.layout.centerLayout = window.siyuan.layout.layout;
});
initStatus(true);
- initWindow();
+ initWindow(app);
appearance.onSetappearance(window.siyuan.config.appearance);
initAssets();
renderSnippet();