diff --git a/src/elements/workspace.ts b/src/elements/workspace.ts index 235b02e..5d81228 100644 --- a/src/elements/workspace.ts +++ b/src/elements/workspace.ts @@ -85,32 +85,30 @@ export class Workspace extends PluginCEBase { } async updateEditor() { - const editorElem = this._queryID("editor-main") as EditorElement; - await waitUtilAsync(() => Boolean(editorElem._initialized)); - if (!editorElem._initialized) { + await waitUtilAsync(() => Boolean(this._editorElement._initialized)); + if (!this._editorElement._initialized) { throw new Error("initNoteEditor: waiting initialization failed"); } - editorElem.mode = "edit"; - editorElem.viewMode = "library"; - editorElem.parent = this.item?.parentItem; - editorElem.item = this.item; - await waitUtilAsync(() => Boolean(editorElem._editorInstance)); - await editorElem._editorInstance._initPromise; + this._editorElement.mode = "edit"; + this._editorElement.viewMode = "library"; + this._editorElement.parent = this.item?.parentItem; + this._editorElement.item = this.item; + await waitUtilAsync(() => Boolean(this._editorElement._editorInstance)); + await this._editorElement._editorInstance._initPromise; // Hide BN toolbar - editorElem._editorInstance._iframeWindow.document.body.setAttribute( + this._editorElement._editorInstance._iframeWindow.document.body.setAttribute( "no-bn-toolbar", "true", ); - // TODO: implement jump to - // if (typeof options.lineIndex === "number") { - // addon.api.editor.scroll(editorElem._editorInstance, options.lineIndex); - // } - // if (typeof options.sectionName === "string") { - // addon.api.editor.scrollToSection( - // editorElem._editorInstance, - // options.sectionName, - // ); - // } return; } + + scrollEditorTo(options: { lineIndex?: number; sectionName?: string } = {}) { + if (typeof options.lineIndex === "number") { + this._addon.api.editor.scroll(this.editor, options.lineIndex); + } + if (typeof options.sectionName === "string") { + this._addon.api.editor.scrollToSection(this.editor, options.sectionName); + } + } } diff --git a/src/hooks.ts b/src/hooks.ts index 0bf1a5a..c9ee249 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -33,7 +33,6 @@ import { createNoteFromTemplate, createNoteFromMD } from "./modules/createNote"; import { createZToolkit } from "./utils/ztoolkit"; import { waitUtilAsync } from "./utils/wait"; import { initSyncList } from "./modules/sync/api"; -import { getPref } from "./utils/prefs"; import { patchViewItems } from "./modules/viewItems"; import { onUpdateRelated } from "./modules/relatedNotes"; @@ -146,7 +145,7 @@ async function onPrefsEvent(type: string, data: { [key: string]: any }) { function onOpenNote( noteId: number, - mode: "auto" | "preview" | "workspace" | "standalone" | "window" = "auto", + mode: "auto" | "preview" | "tab" | "window" | "builtin" = "auto", options: { lineIndex?: number; sectionName?: string; @@ -158,19 +157,19 @@ function onOpenNote( return; } if (mode === "auto") { - mode = "workspace"; + mode = "tab"; } switch (mode) { case "preview": // addon.hooks.onSetWorkspaceNote(noteId, "preview", options); break; - case "workspace": - addon.hooks.onOpenWorkspace(noteItem, "tab"); + case "tab": + openWorkspaceTab(noteItem, options); break; case "window": - addon.hooks.onOpenWorkspace(noteItem, "window"); + openWorkspaceWindow(noteItem, options); break; - case "standalone": + case "builtin": ZoteroPane.openNoteWindow(noteId); break; default: @@ -178,39 +177,8 @@ function onOpenNote( } } -function onOpenWorkspace(item: Zotero.Item, type: "tab" | "window" = "tab") { - if (type === "window") { - openWorkspaceWindow(item); - return; - } - if (type === "tab") { - openWorkspaceTab(item); - return; - } -} - const onInitWorkspace = initWorkspace; -function onToggleWorkspacePane( - type: "outline" | "preview" | "notes", - visibility?: boolean, - container?: XUL.Box, -) { - // switch (type) { - // case "outline": - // toggleOutlinePane(visibility, container); - // break; - // case "preview": - // togglePreviewPane(visibility, container); - // break; - // case "notes": - // toggleNotesPane(visibility); - // break; - // default: - // break; - // } -} - const onSyncing = callSyncing; const onShowTemplatePicker = showTemplatePicker; @@ -248,8 +216,6 @@ export default { onPrefsEvent, onOpenNote, onInitWorkspace, - onOpenWorkspace, - onToggleWorkspacePane, onSyncing, onUpdateRelated, onShowTemplatePicker, diff --git a/src/modules/editor/popup.ts b/src/modules/editor/popup.ts index 81be7ab..605f842 100644 --- a/src/modules/editor/popup.ts +++ b/src/modules/editor/popup.ts @@ -137,7 +137,7 @@ async function updateEditorLinkPopup(editor: Zotero.EditorInstance) { { type: "click", listener: async (e) => { - ZoteroPane.openNoteWindow(linkNote.id); + addon.hooks.onOpenNote(linkNote.id, "window", linkParams); }, }, ], diff --git a/src/modules/editor/toolbar.ts b/src/modules/editor/toolbar.ts index 7f4115e..3d92c8c 100644 --- a/src/modules/editor/toolbar.ts +++ b/src/modules/editor/toolbar.ts @@ -70,14 +70,14 @@ async function getMenuData(editor: Zotero.EditorInstance) { id: makeId("settings-openAsTab"), text: getString("editor.toolbar.settings.openAsTab"), callback: (e) => { - addon.hooks.onOpenWorkspace(noteItem, "tab"); + addon.hooks.onOpenNote(noteItem.id, "tab"); }, }, { id: makeId("settings-openAsWindow"), text: getString("editor.toolbar.settings.openAsWindow"), callback: (e) => { - addon.hooks.onOpenWorkspace(noteItem, "window"); + addon.hooks.onOpenNote(noteItem.id, "window"); }, }, { diff --git a/src/modules/reader.ts b/src/modules/reader.ts index 6dbf695..3c459c7 100644 --- a/src/modules/reader.ts +++ b/src/modules/reader.ts @@ -23,7 +23,7 @@ export function registerReaderAnnotationButton() { createNoteFromAnnotation( reader._item.libraryID, annotationData.id, - (e as MouseEvent).shiftKey ? "standalone" : "auto", + (e as MouseEvent).shiftKey ? "builtin" : "auto", ); e.preventDefault(); }, @@ -54,7 +54,7 @@ export function registerReaderAnnotationButton() { async function createNoteFromAnnotation( libraryID: number, itemKey: string, - openMode: "standalone" | "auto" = "auto", + openMode: "builtin" | "auto" = "auto", ) { const annotationItem = Zotero.Items.getByLibraryAndKey( libraryID, diff --git a/src/modules/sync/infoWindow.ts b/src/modules/sync/infoWindow.ts index c384a84..51b5252 100644 --- a/src/modules/sync/infoWindow.ts +++ b/src/modules/sync/infoWindow.ts @@ -44,11 +44,12 @@ export async function showSyncInfo(noteId: number) { }) .addButton(getString("syncInfo.unSync"), "unSync", { callback: async (ev) => { - const allNoteIds = await addon.api.note.getRelatedNoteIds(noteId); - for (const itemId of allNoteIds) { + const { detectedIDSet } = + await addon.api.note.getRelatedNoteIds(noteId); + for (const itemId of Array.from(detectedIDSet)) { addon.api.sync.removeSyncNote(itemId); } - showHint(`Cancel sync of ${allNoteIds.length} notes.`); + showHint(`Cancel sync of ${detectedIDSet.size} notes.`); }, }) .addButton(getString("syncInfo.reveal"), "reveal", { diff --git a/src/modules/sync/managerWindow.ts b/src/modules/sync/managerWindow.ts index 4bfa6c2..bc33069 100644 --- a/src/modules/sync/managerWindow.ts +++ b/src/modules/sync/managerWindow.ts @@ -91,7 +91,7 @@ export async function showSyncManager() { .setProp("onActivate", (ev) => { const noteIds = getSelectedNoteIds(); noteIds.forEach((noteId) => - addon.hooks.onOpenNote(noteId, "standalone"), + addon.hooks.onOpenNote(noteId, "builtin"), ); return true; }) diff --git a/src/modules/viewItems.ts b/src/modules/viewItems.ts index 43e76f1..e2c4ea8 100644 --- a/src/modules/viewItems.ts +++ b/src/modules/viewItems.ts @@ -15,7 +15,7 @@ export function patchViewItems(win: Window) { const otherItems = []; for (const item of items) { if (item.isNote()) { - addon.hooks.onOpenWorkspace(item, "tab"); + addon.hooks.onOpenNote(item.id, "tab"); continue; } otherItems.push(item); diff --git a/src/modules/workspace/content.ts b/src/modules/workspace/content.ts index 8e39937..7d1a3d9 100644 --- a/src/modules/workspace/content.ts +++ b/src/modules/workspace/content.ts @@ -1,4 +1,4 @@ -export function initWorkspace(container: XUL.Box, item: Zotero.Item) { +export async function initWorkspace(container: XUL.Box, item: Zotero.Item) { if (!container) { return; } @@ -14,5 +14,6 @@ export function initWorkspace(container: XUL.Box, item: Zotero.Item) { container.append(workspace); workspace.item = item; workspace.containerType = "tab"; - workspace.render(); + await workspace.render(); + return workspace; } diff --git a/src/modules/workspace/tab.ts b/src/modules/workspace/tab.ts index 5f7f66f..35437d5 100644 --- a/src/modules/workspace/tab.ts +++ b/src/modules/workspace/tab.ts @@ -1,34 +1,37 @@ -import { config } from "../../../package.json"; import { initWorkspace } from "./content"; export const TAB_TYPE = "note"; export async function openWorkspaceTab( item: Zotero.Item, - options: { select?: boolean; index?: number } = { + options: { select?: boolean; lineIndex?: number; sectionName?: string } = { select: true, }, ) { - const { select, index } = options; + const { select, lineIndex, sectionName } = options; if (!item) return; const currentTab = Zotero_Tabs._tabs.find( (tab) => tab.data?.itemID == item.id, ); if (currentTab) { - if (select) Zotero_Tabs.select(currentTab.id); + if (select ?? true) Zotero_Tabs.select(currentTab.id); + onScrollTabEditorTo(item, options); return; } const { id, container } = Zotero_Tabs.add({ type: TAB_TYPE, title: item.getNoteTitle(), - index, data: { itemID: item.id, }, - select, + select: select ?? true, onClose: () => {}, }); - initWorkspace(container, item); + const workspace = await initWorkspace(container, item); + workspace.scrollEditorTo({ + lineIndex, + sectionName, + }); } let contextPaneOpen: boolean | undefined = undefined; @@ -57,7 +60,6 @@ export function restoreNoteTabs() { if (tab.type !== TAB_TYPE) continue; openWorkspaceTab(Zotero.Items.get(tab.data.itemID), { select: tab.selected, - index: Number(i), }); } } @@ -75,3 +77,18 @@ export function onUpdateNoteTabsTitle(noteItems: Zotero.Item[]) { } } } + +function onScrollTabEditorTo( + item: Zotero.Item, + options: { + lineIndex?: number; + sectionName?: string; + } = {}, +) { + const tab = Zotero_Tabs._tabs.find((tab) => tab.data?.itemID == item.id); + if (!tab || tab.type !== TAB_TYPE) return; + const workspace = document.querySelector(`#${tab.id} > bn-workspace`); + if (!workspace) return; + // @ts-ignore + workspace.scrollEditorTo(options); +} diff --git a/src/modules/workspace/window.ts b/src/modules/workspace/window.ts index 982009e..d7226c7 100644 --- a/src/modules/workspace/window.ts +++ b/src/modules/workspace/window.ts @@ -1,6 +1,9 @@ import { config } from "../../../package.json"; -export async function openWorkspaceWindow(item: Zotero.Item) { +export async function openWorkspaceWindow( + item: Zotero.Item, + options: { lineIndex?: number; sectionName?: string } = {}, +) { const windowArgs = { _initPromise: Zotero.Promise.defer(), }; @@ -15,9 +18,11 @@ export async function openWorkspaceWindow(item: Zotero.Item) { const container = win.document.querySelector( "#workspace-container", ) as XUL.Box; - addon.hooks.onInitWorkspace(container, item); + const workspace = await addon.hooks.onInitWorkspace(container, item); + workspace.scrollEditorTo(options); win.focus(); // @ts-ignore win.updateTitle(); + return workspace; }