From 0a8851328e1503b6dc7a6b8f6efd60d7016f6c01 Mon Sep 17 00:00:00 2001 From: windingwind <33902321+windingwind@users.noreply.github.com> Date: Sat, 24 Feb 2024 16:21:09 +0800 Subject: [PATCH] update: move workspace tab button to toolbar --- addon/chrome/content/icons/icon-linear-20.svg | 7 ++ src/hooks.ts | 27 ++---- src/modules/workspace/tab.ts | 86 +++++++++---------- src/modules/workspace/window.ts | 2 +- 4 files changed, 54 insertions(+), 68 deletions(-) create mode 100644 addon/chrome/content/icons/icon-linear-20.svg diff --git a/addon/chrome/content/icons/icon-linear-20.svg b/addon/chrome/content/icons/icon-linear-20.svg new file mode 100644 index 0000000..b6c2649 --- /dev/null +++ b/addon/chrome/content/icons/icon-linear-20.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/hooks.ts b/src/hooks.ts index 2a95899..a687c68 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -9,11 +9,8 @@ import { } from "./modules/template/controller"; import { registerMenus } from "./modules/menu"; import { - activateWorkspaceTab, - deActivateWorkspaceTab, registerWorkspaceTab, - TAB_TYPE, - unregisterWorkspaceTab, + openWorkspaceTab, } from "./modules/workspace/tab"; import { initWorkspace, @@ -24,7 +21,7 @@ import { updateOutline, } from "./modules/workspace/content"; import { registerNotify } from "./modules/notify"; -import { showWorkspaceWindow } from "./modules/workspace/window"; +import { openWorkspaceWindow } from "./modules/workspace/window"; import { registerReaderAnnotationButton } from "./modules/reader"; import { setSyncing, callSyncing } from "./modules/sync/hooks"; import { @@ -84,7 +81,7 @@ async function onMainWindowLoad(win: Window): Promise { registerMenus(); - registerWorkspaceTab(); + registerWorkspaceTab(win); initTemplates(); } @@ -97,7 +94,6 @@ function onShutdown(): void { ztoolkit.unregisterAll(); // Remove addon object addon.data.alive = false; - unregisterWorkspaceTab(); delete Zotero[config.addonInstance]; } @@ -114,14 +110,6 @@ function onNotify( if (extraData.skipBN) { return; } - // Workspace tab select/unselect callback - if (event === "select" && type === "tab") { - if (extraData[ids[0]].type == TAB_TYPE) { - activateWorkspaceTab(); - } else { - deActivateWorkspaceTab(); - } - } // Workspace main note update if (event === "modify" && type === "item") { if ((ids as number[]).includes(addon.data.workspace.mainId)) { @@ -257,16 +245,11 @@ function onSetWorkspaceNote( function onOpenWorkspace(type: "tab" | "window" = "tab") { if (type === "window") { - if (addon.data.workspace.window.active) { - addon.data.workspace.window.window?.focus(); - return; - } - showWorkspaceWindow(); + openWorkspaceWindow(); return; } if (type === "tab") { - // selecting tab will auto load the workspace content - Zotero_Tabs.select(addon.data.workspace.tab.id!); + openWorkspaceTab(); return; } } diff --git a/src/modules/workspace/tab.ts b/src/modules/workspace/tab.ts index cf33231..91320e2 100644 --- a/src/modules/workspace/tab.ts +++ b/src/modules/workspace/tab.ts @@ -5,37 +5,49 @@ import { getString } from "../../utils/locale"; import { getPref, setPref } from "../../utils/prefs"; import { waitUtilAsync } from "../../utils/wait"; // TODO: uncouple these imports -import {} from "./content"; import { messageHandler } from "./message"; export const TAB_TYPE = "betternotes"; -export function registerWorkspaceTab() { - const tabContainer = document.querySelector("#tab-bar-container"); - if (!tabContainer) { +export function registerWorkspaceTab(win: Window) { + const doc = win.document; + const spacer = doc.querySelector("#zotero-collections-toolbar > spacer"); + if (!spacer) { return; } - tabContainer.removeAttribute("hidden"); - const mut = new (ztoolkit.getGlobal("MutationObserver"))((muts) => { - tabContainer.removeAttribute("hidden"); - }); - mut.observe(tabContainer, { - attributes: true, - attributeFilter: ["hidden"], - }); - waitUtilAsync(() => - Boolean(ztoolkit.getGlobal("ZoteroContextPane")._notifierID), - ).then(() => { - addWorkspaceTab(); - }); - window.addEventListener("message", (e) => messageHandler(e), false); + ztoolkit.UI.insertElementBefore( + { + tag: "toolbarbutton", + classList: ["zotero-tb-button"], + styles: { + listStyleImage: `url("chrome://${config.addonRef}/content/icons/icon-linear-20.svg")`, + }, + attributes: { + tooltiptext: "Open workspace", + }, + listeners: [ + { + type: "command", + listener: (ev) => { + if ((ev as MouseEvent).shiftKey) { + addon.hooks.onOpenWorkspace("window"); + } else { + addon.hooks.onOpenWorkspace("tab"); + } + }, + }, + ], + }, + spacer, + ); + win.addEventListener("message", (e) => messageHandler(e), false); } -export function unregisterWorkspaceTab() { - addon.data.workspace.tab.id && Zotero_Tabs.close(addon.data.workspace.tab.id); -} - -async function addWorkspaceTab() { +export async function openWorkspaceTab() { + if (addon.data.workspace.tab.active) { + Zotero_Tabs.select(addon.data.workspace.tab.id!); + return; + } const { id, container } = Zotero_Tabs.add({ type: TAB_TYPE, title: getString("tab.name"), @@ -45,30 +57,15 @@ async function addWorkspaceTab() { }, select: false, onClose: () => { - setWorkspaceTabStatus(false); - if (addon.data.alive) { - addWorkspaceTab(); - } + deActivateWorkspaceTab(); }, }); - await waitUtilAsync(() => - Boolean(document.querySelector(`.tabs-wrapper .tab[data-id=${id}]`)), - ); - const tabElem = document.querySelector( - `.tabs-wrapper .tab[data-id=${id}]`, - ) as HTMLDivElement; - tabElem.style.width = "30px"; - tabElem.style.minWidth = "30px"; - tabElem.style.maxWidth = "30px"; - const content = tabElem.querySelector(".tab-name") as HTMLDivElement; - const close = tabElem.querySelector(".tab-close") as HTMLDivElement; - content.style.width = "20px"; - content.style.height = "20px"; - content.innerHTML = ""; - close.style.visibility = "hidden"; addon.data.workspace.tab.id = id; container.setAttribute("workspace-type", "tab"); addon.data.workspace.tab.container = container; + + await activateWorkspaceTab(); + Zotero_Tabs.select(id); } function hoverWorkspaceTab(hovered: boolean) { @@ -291,18 +288,17 @@ export async function activateWorkspaceTab() { initWorkspaceTabDragDrop(container, tabElem); addon.hooks.onInitWorkspace(container); registerWorkspaceTabPaneObserver(); + setWorkspaceTabStatus(true); } export function deActivateWorkspaceTab() { - if (!isContextPaneInitialized()) { - return; - } const tabToolbar = document.querySelector("#zotero-tab-toolbar") as XUL.Box; tabToolbar && tabToolbar.style.removeProperty("visibility"); const toolbar = document.querySelector( "#zotero-context-toolbar-extension", ) as XUL.Box; toolbar?.style.removeProperty("visibility"); + setWorkspaceTabStatus(false); } function setWorkspaceTabStatus(status: boolean) { diff --git a/src/modules/workspace/window.ts b/src/modules/workspace/window.ts index cd5bf21..855702b 100644 --- a/src/modules/workspace/window.ts +++ b/src/modules/workspace/window.ts @@ -2,7 +2,7 @@ import { config } from "../../../package.json"; import { isWindowAlive } from "../../utils/window"; import { messageHandler } from "./message"; -export async function showWorkspaceWindow() { +export async function openWorkspaceWindow() { if (isWindowAlive(addon.data.workspace.window.window)) { addon.data.workspace.window.window?.focus(); return;