From f570e47e27a02cd4a6a16d0a5af589c4545bf4ef Mon Sep 17 00:00:00 2001 From: StroepWafel Date: Mon, 22 Jun 2026 18:02:24 +0930 Subject: [PATCH] fix(sidebar): hide Analytics via toggle --- lib/extensionChunkUrls.ts | 29 ++++ src/background.ts | 1 + src/css/injected.scss | 48 ++++++ .../built-in/gradeAnalytics/core/index.ts | 23 ++- src/plugins/built-in/gradeAnalytics/lazy.ts | 2 +- src/plugins/monofile.ts | 69 ++++---- src/seqta/ui/AddBetterSEQTAElements.ts | 32 +++- src/seqta/utils/Openers/OpenMenuOptions.ts | 163 ++++++++++-------- src/seqta/utils/SendNewsPage.ts | 18 +- src/seqta/utils/defaultSettings.ts | 1 + src/seqta/utils/listeners/StorageChanges.ts | 8 + src/seqta/utils/menuItemVisibility.ts | 45 +++++ src/types/storage.ts | 2 + vite.config.ts | 2 + 14 files changed, 334 insertions(+), 109 deletions(-) create mode 100644 lib/extensionChunkUrls.ts create mode 100644 src/seqta/utils/menuItemVisibility.ts diff --git a/lib/extensionChunkUrls.ts b/lib/extensionChunkUrls.ts new file mode 100644 index 00000000..6dff51bb --- /dev/null +++ b/lib/extensionChunkUrls.ts @@ -0,0 +1,29 @@ +import type { Plugin } from "vite"; + +/** + * Vite's default base (`/`) emits absolute chunk paths like `/assets/chunk.js`. + * In content scripts those resolve against the SEQTA page origin on Firefox, + * not the extension — causing MIME type / NS_ERROR_CORRUPTED_CONTENT failures. + * + * Use relative base plus `chrome.runtime.getURL` for dynamic import targets. + */ +export function extensionChunkUrls(): Plugin { + return { + name: "extension-chunk-urls", + config() { + return { + base: "./", + experimental: { + renderBuiltUrl(filename, { hostType, type }) { + if (type === "chunk" && hostType === "js") { + const path = filename.replace(/^\//, ""); + return { + runtime: `chrome.runtime.getURL(${JSON.stringify(path)})`, + }; + } + }, + }, + }; + }, + }; +} diff --git a/src/background.ts b/src/background.ts index c1248182..6a6b5970 100644 --- a/src/background.ts +++ b/src/background.ts @@ -626,6 +626,7 @@ browser.runtime.onInstalled.addListener(function (event) { void migrateGlobalSearchDefaultsFor365Upgrade(event.previousVersion); void resetThemeOfTheMonthDisabledFor366Upgrade(event.previousVersion); void resetThemeOfTheMonthDismissalFor370Upgrade(event.previousVersion); + reloadSeqtaPages(); } }); diff --git a/src/css/injected.scss b/src/css/injected.scss index d0537c87..dea7df9a 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -512,6 +512,54 @@ ul.magicDelete > li.deleting { #menu:has(> ul > li.hasChildren.active) > ul > li:not(.hasChildren.active) { pointer-events: none !important; } + +/* Edit Sidebar: every row + toggle must stay clickable (drill stack disables siblings). */ +#menu.bsplus-sidebar-edit-mode li.item, +#menu.bsplus-sidebar-edit-mode section.item, +#menu.bsplus-sidebar-edit-mode .bsplus-sidebar-offscreen, +#menu.bsplus-sidebar-edit-mode .bsplus-sidebar-offscreen * { + pointer-events: auto !important; + user-select: auto !important; +} + +#menu.bsplus-sidebar-edit-mode:has(> ul > li.hasChildren.active) + > ul + > li:not(.hasChildren.active) { + pointer-events: auto !important; +} + +#menu.bsplus-sidebar-edit-mode > ul > .bsplus-sidebar-offscreen:not(.hasChildren.active), +#menu.bsplus-sidebar-edit-mode .sub .bsplus-sidebar-offscreen:not(.hasChildren.active) { + position: relative !important; + left: auto !important; + width: auto !important; + height: auto !important; + margin: inherit !important; + padding: inherit !important; + overflow: visible !important; + clip: auto !important; + opacity: 1 !important; + visibility: visible !important; +} + +#menu.bsplus-sidebar-edit-mode .item.draggable { + display: flex !important; + align-items: center; + gap: 0.5rem; +} + +#menu.bsplus-sidebar-edit-mode .item.draggable > label { + flex: 1; + min-width: 0; +} + +#menu.bsplus-sidebar-edit-mode .onoffswitch { + pointer-events: auto !important; + flex-shrink: 0; + position: relative; + z-index: 2; +} + #menu section > label { align-items: center; box-sizing: border-box; diff --git a/src/plugins/built-in/gradeAnalytics/core/index.ts b/src/plugins/built-in/gradeAnalytics/core/index.ts index 16d36394..43313b88 100644 --- a/src/plugins/built-in/gradeAnalytics/core/index.ts +++ b/src/plugins/built-in/gradeAnalytics/core/index.ts @@ -3,6 +3,11 @@ import MenuitemSVGKey from "@/seqta/content/MenuItemSVGKey.json"; import { waitForElm } from "@/seqta/utils/waitForElm"; import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage"; import { processMenuItemNode } from "@/seqta/utils/sidebarMenuIcons"; +import { MenuOptionsOpen } from "@/seqta/utils/Openers/OpenMenuOptions"; +import { + applyMenuItemVisibility, + isMenuItemHidden, +} from "@/seqta/utils/menuItemVisibility"; import { loadAnalyticsPage } from "../loadAnalyticsPage"; import styles from "../styles.css?inline"; @@ -17,7 +22,7 @@ const gradeAnalyticsPlugin: Plugin<{}> = { "Adds an analytics page with grade trends, distribution charts, and assessment history", version: "1.0.0", settings: {}, - disableToggle: false, + disableToggle: true, styles, run: async () => { @@ -25,6 +30,10 @@ const gradeAnalyticsPlugin: Plugin<{}> = { return () => {}; } + if (isMenuItemHidden("analytics")) { + return () => {}; + } + const menuList = (await waitForElm("#menu > ul, #menu ul", true, 100, 60)) as HTMLElement; const analyticsItem = document.createElement("li"); @@ -44,8 +53,11 @@ const gradeAnalyticsPlugin: Plugin<{}> = { } processMenuItemNode(analyticsItem); + applyMenuItemVisibility(); const menuObserver = new MutationObserver(() => { + if (MenuOptionsOpen) return; + if (isMenuItemHidden("analytics")) return; if (!menuList.contains(analyticsItem)) { if (homeButton?.parentElement === menuList) { homeButton.insertAdjacentElement("afterend", analyticsItem); @@ -53,11 +65,20 @@ const gradeAnalyticsPlugin: Plugin<{}> = { menuList.insertBefore(analyticsItem, menuList.firstChild); } processMenuItemNode(analyticsItem); + applyMenuItemVisibility(); } }); menuObserver.observe(menuList, { childList: true }); const onClick = (e: Event) => { + const target = e.target as HTMLElement; + if ( + MenuOptionsOpen || + analyticsItem.classList.contains("draggable") || + target.closest(".onoffswitch, .editmenuoption-container") + ) { + return; + } e.preventDefault(); window.history.pushState({}, "", "/#?page=/analytics"); void loadAnalyticsPage(); diff --git a/src/plugins/built-in/gradeAnalytics/lazy.ts b/src/plugins/built-in/gradeAnalytics/lazy.ts index 9b0c84e6..125db7d5 100644 --- a/src/plugins/built-in/gradeAnalytics/lazy.ts +++ b/src/plugins/built-in/gradeAnalytics/lazy.ts @@ -20,7 +20,7 @@ const gradeAnalyticsPluginLazy = defineLazyPlugin({ "Grade trends, distribution charts, and assessment history synced from SEQTA", version: "1.0.0", settings, - disableToggle: false, + disableToggle: true, defaultEnabled: true, styles, loader: () => import("./core/index"), diff --git a/src/plugins/monofile.ts b/src/plugins/monofile.ts index 0783c539..da224f48 100644 --- a/src/plugins/monofile.ts +++ b/src/plugins/monofile.ts @@ -40,29 +40,7 @@ import IconFamily from "@/resources/fonts/IconFamily.woff"; // Stylesheets import iframeCSS from "@/css/iframe.scss?raw"; -function SetDisplayNone(ElementName: string) { - return `li[data-key=${ElementName}]{display:var(--menuHidden) !important; transition: 1s;}`; -} - -async function HideMenuItems(): Promise { - try { - let stylesheetInnerText: string = ""; - for (const [menuItem, { toggle }] of Object.entries( - settingsState.menuitems, - )) { - if (!toggle) { - stylesheetInnerText += SetDisplayNone(menuItem); - console.info(`[BetterSEQTA+] Hiding ${menuItem} menu item`); - } - } - - const menuItemStyle: HTMLStyleElement = document.createElement("style"); - menuItemStyle.innerText = stylesheetInnerText; - document.head.appendChild(menuItemStyle); - } catch (error) { - console.error("[BetterSEQTA+] An error occurred:", error); - } -} +import { applyMenuItemVisibility } from "@/seqta/utils/menuItemVisibility"; export function hideSideBar() { const sidebar = document.getElementById("menu"); // The sidebar element to be closed @@ -368,11 +346,18 @@ async function handleSublink(sublink: string | undefined): Promise { } async function handleNewsPage(): Promise { - console.info("[BetterSEQTA+] Started Init"); - if (settingsState.onoff) { - SendNewsPage(); + if (!settingsState.onoff) { finishLoad(); + return; } + + console.info("[BetterSEQTA+] Started Init"); + try { + await SendNewsPage(); + } catch (error) { + console.error("[BetterSEQTA+] Failed to load news page:", error); + } + finishLoad(); } async function handleDefault(): Promise { @@ -674,8 +659,24 @@ export function showConflictPopup() { } export function init() { + const tryMountDisabledUi = async () => { + if (document.getElementById("AddedSettings")) return; + + try { + await waitForElm("#content"); + } catch { + try { + await waitForElm("#container"); + } catch { + await waitForElm("body"); + } + } + + AppendElementsToDisabledPage(); + }; + const handleDisabled = () => { - waitForElm(".code", true, 50).then(AppendElementsToDisabledPage); + void tryMountDisabledUi(); }; if (settingsState.onoff) { @@ -705,7 +706,7 @@ export function init() { }); loading(); InjectCustomIcons(); - HideMenuItems(); + applyMenuItemVisibility(); tryLoad(); // Auto-focus WISP direct online submission editor when pane opens @@ -787,7 +788,7 @@ export function init() { } else { handleDisabled(); InjectCustomIcons(); - window.addEventListener("load", handleDisabled); + window.addEventListener("load", handleDisabled, { once: true }); } } @@ -807,6 +808,8 @@ function InjectCustomIcons() { } export function AppendElementsToDisabledPage() { + if (document.getElementById("AddedSettings")) return; + console.info("[BetterSEQTA+] Appending elements to disabled page"); AddBetterSEQTAElements(); @@ -822,7 +825,13 @@ export function AppendElementsToDisabledPage() { border-radius: 50%; margin: 7px !important; cursor: pointer; - color: white !important; + color: #38373d !important; + background: rgba(0, 0, 0, 0.08); + display: flex !important; + align-items: center; + justify-content: center; + visibility: visible !important; + z-index: 1000; } .addedButton svg { margin: 6px; diff --git a/src/seqta/ui/AddBetterSEQTAElements.ts b/src/seqta/ui/AddBetterSEQTAElements.ts index 62007031..ca01d6da 100644 --- a/src/seqta/ui/AddBetterSEQTAElements.ts +++ b/src/seqta/ui/AddBetterSEQTAElements.ts @@ -278,7 +278,13 @@ function setupEventListeners() { } async function createSettingsButton(parent?: Element) { - const target = parent ?? document.getElementById("content")!; + if (document.getElementById("AddedSettings")) return; + + const target = + parent ?? + document.getElementById("content") ?? + document.getElementById("container") ?? + document.body; target.append( stringToHTML(/* html */ `