schoolbox web extension :)
at main 3.1 kB view raw
1import { browser, defineContentScript } from "#imports"; 2import { 3 hasChanged, 4 injectCatppuccin, 5 injectLogo, 6 injectStylesheet, 7 injectUserSnippet, 8 onSchoolboxPage, 9 sendMessage, 10 uninjectCatppuccin, 11 uninjectStylesheet, 12 uninjectUserSnippet, 13} from "@/utils"; 14import { EXCLUDE_MATCHES, LOGO_INFO } from "@/utils/constants"; 15import type { LogoId, Settings } from "@/utils/storage"; 16import { globalSettings } from "@/utils/storage"; 17import type { WatchCallback } from "wxt/utils/storage"; 18import cssUrl from "./catppuccin.css?url"; 19 20export default defineContentScript({ 21 matches: ["<all_urls>"], 22 cssInjectionMode: "manual", 23 runAt: "document_start", 24 excludeMatches: EXCLUDE_MATCHES, 25 async main() { 26 // if not on Schoolbox page 27 if (!(await onSchoolboxPage())) return; 28 29 const updateThemes: WatchCallback<Settings> = async (newValue, oldValue) => { 30 // if global or themes was changed 31 if (hasChanged(newValue, oldValue, ["global", "themes", "themeFlavour", "themeAccent"])) { 32 if (newValue.global && newValue.themes) { 33 injectThemes(); 34 injectCatppuccin(); 35 } else { 36 uninjectThemes(); 37 uninjectCatppuccin(); 38 } 39 } 40 }; 41 42 const updateUserSnippets: WatchCallback<Settings> = async (newValue, oldValue) => { 43 // if global or userSnippets were changed 44 if (hasChanged(newValue, oldValue, ["global", "userSnippets"])) { 45 // uninject removed snippets 46 if (oldValue) { 47 for (const id of Object.keys(oldValue.userSnippets)) { 48 if (!newValue.userSnippets[id]) { 49 uninjectUserSnippet(id); 50 } 51 } 52 } 53 54 // inject/uninject current snippets 55 for (const [id, userSnippet] of Object.entries(newValue.userSnippets)) { 56 if (newValue.global && newValue.snippets && userSnippet.toggle) { 57 injectUserSnippet(id); 58 } else { 59 uninjectUserSnippet(id); 60 } 61 } 62 } 63 }; 64 65 // @ts-expect-error unlisted CSS not a PublicPath 66 const injectThemes = () => injectStylesheet(browser.runtime.getURL(cssUrl), "themes"); 67 const uninjectThemes = () => uninjectStylesheet("themes"); 68 69 // storage listeners for hot reload 70 globalSettings.watch((newValue, oldValue) => { 71 updateThemes(newValue, oldValue); 72 updateUserSnippets(newValue, oldValue); 73 }); 74 75 const settings = await globalSettings.get(); 76 if (settings.global && (await onSchoolboxPage())) { 77 // inject themes 78 if (settings.themes) { 79 injectThemes(); 80 injectCatppuccin(); 81 } 82 83 // inject logo 84 injectLogo(LOGO_INFO[settings.themeLogo as LogoId], settings.themeLogoAsFavicon); 85 86 // inject user snippets 87 if (settings.snippets) { 88 const userSnippets = (await globalSettings.get()).userSnippets; 89 for (const [id, snippet] of Object.entries(userSnippets)) { 90 if (snippet.toggle) { 91 injectUserSnippet(id); 92 } 93 } 94 } 95 96 // update icon 97 sendMessage({ type: "updateIcon" }); 98 } 99 }, 100});