mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-08-28 17:21:05 +00:00
feat: cleanup and improve detection delay on kitten plugin
This commit is contained in:
+49
-47
@@ -53,9 +53,8 @@ if (document.childNodes[1]) {
|
||||
init();
|
||||
}
|
||||
|
||||
// The 404 page is a bare document with no second childNode, so it must be
|
||||
// booted unconditionally (outside the gate above). It self-guards on title.
|
||||
bootErrorPage();
|
||||
// Standalone 404 documents never pass the SEQTA SPA gate above.
|
||||
void bootErrorPage();
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
window.addEventListener("unhandledrejection", (event) => {
|
||||
@@ -142,65 +141,68 @@ async function init() {
|
||||
}
|
||||
}
|
||||
|
||||
// The 404 page is a standalone document that never passes the SPA gate above,
|
||||
// so the normal plugin path never boots there; start just the classic kitten
|
||||
// 404 plugin so it renders without any SPA work.
|
||||
function shouldBootKitten404(): boolean {
|
||||
if (IsSEQTAPage || document.getElementById("container")) return false;
|
||||
return /404|not found/i.test(document.title);
|
||||
}
|
||||
|
||||
/** Hide the rebranded 404 before the kitten card mounts (removed after boot). */
|
||||
function inject404FlashHide(): void {
|
||||
if (document.getElementById("bsplus-404-flash-hide")) return;
|
||||
const style = document.createElement("style");
|
||||
style.id = "bsplus-404-flash-hide";
|
||||
style.textContent =
|
||||
"html,body{background:#333!important}.message{display:none!important}";
|
||||
(document.head ?? document.documentElement).appendChild(style);
|
||||
}
|
||||
|
||||
async function bootErrorPage() {
|
||||
if (IsSEQTAPage) return;
|
||||
|
||||
// Runs at document_start, so <title> and body are not available yet; wait
|
||||
// for the DOM before testing the 404 title.
|
||||
await new Promise<void>((resolve) => {
|
||||
if (document.readyState !== "loading") {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", () => resolve(), {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
|
||||
const is404Page =
|
||||
/404/.test(document.title) || /not found/i.test(document.title);
|
||||
if (!is404Page) return;
|
||||
|
||||
const stored = await browser.storage.local.get([
|
||||
const storagePromise = browser.storage.local.get([
|
||||
"onoff",
|
||||
"plugin.error-page-kitten.settings",
|
||||
]);
|
||||
if ((stored.onoff ?? true) === false) return;
|
||||
const kittenEnabled = (
|
||||
stored["plugin.error-page-kitten.settings"] as
|
||||
| { enabled?: boolean }
|
||||
| undefined
|
||||
)?.enabled;
|
||||
if (kittenEnabled === false) return;
|
||||
|
||||
hideRebranded404();
|
||||
const watchTitle = () => {
|
||||
if (shouldBootKitten404()) inject404FlashHide();
|
||||
};
|
||||
watchTitle();
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("readystatechange", watchTitle);
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
await new Promise<void>((resolve) => {
|
||||
document.addEventListener("DOMContentLoaded", () => resolve(), { once: true });
|
||||
});
|
||||
}
|
||||
document.removeEventListener("readystatechange", watchTitle);
|
||||
|
||||
if (!shouldBootKitten404()) return;
|
||||
|
||||
const stored = await storagePromise;
|
||||
if ((stored.onoff ?? true) === false) return;
|
||||
const kittenSettings = stored["plugin.error-page-kitten.settings"] as
|
||||
| { enabled?: boolean }
|
||||
| undefined;
|
||||
if (kittenSettings?.enabled === false) return;
|
||||
|
||||
try {
|
||||
const { pluginManager } = await import("@/plugins/index");
|
||||
await pluginManager.startPlugin("error-page-kitten");
|
||||
const { mountErrorPageKitten } = await import(
|
||||
"@/plugins/built-in/errorPageKitten"
|
||||
);
|
||||
mountErrorPageKitten();
|
||||
document.getElementById("bsplus-404-flash-hide")?.remove();
|
||||
} catch (error) {
|
||||
// Restore the rebranded page so the user is not left with a blank document.
|
||||
document.getElementById("bsplus-404-flash-hide")?.remove();
|
||||
document
|
||||
.querySelectorAll<HTMLElement>(".bsplus-kitten-404-hidden")
|
||||
.forEach((el) => {
|
||||
el.classList.remove("bsplus-kitten-404-hidden");
|
||||
el.style.display = "";
|
||||
});
|
||||
.querySelectorAll(".bsplus-kitten-404-hidden")
|
||||
.forEach((el) => el.classList.remove("bsplus-kitten-404-hidden"));
|
||||
console.error("[BetterSEQTA+] Failed to boot 404 page:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function hideRebranded404() {
|
||||
const message = document.querySelector<HTMLElement>(".message");
|
||||
if (message) {
|
||||
message.classList.add("bsplus-kitten-404-hidden");
|
||||
message.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function replaceIcons() {
|
||||
document
|
||||
.querySelectorAll<HTMLLinkElement>('link[rel*="icon"]')
|
||||
|
||||
@@ -3,65 +3,33 @@
|
||||
*/
|
||||
/// <reference types="jest" />
|
||||
import type { PluginAPI } from "@/plugins/core/types";
|
||||
import errorPageKittenPlugin from "./index";
|
||||
|
||||
jest.mock("@/lib/extensionAssetUrl", () => ({
|
||||
resolveExtensionAssetUrl: (url: string) =>
|
||||
`chrome-extension://test/${String(url).replace(/^\/+/, "")}`,
|
||||
}));
|
||||
jest.mock("@/resources/error-page/kitten.png", () => ({
|
||||
__esModule: true,
|
||||
default: "/resources/error-page/kitten.png",
|
||||
}));
|
||||
jest.mock("./styles.css?inline", () => ({
|
||||
__esModule: true,
|
||||
default: "/* test */",
|
||||
}));
|
||||
|
||||
import { mountErrorPageKitten } from "./index";
|
||||
|
||||
const REBRANDED_404_BODY = `
|
||||
<div class="message">
|
||||
<h1>Page not found</h1>
|
||||
<p>We can't find the page you're looking for.</p>
|
||||
<p>It may have been moved, deleted or the link might be out of date.</p>
|
||||
<p class="error-ref">Ref: 404</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const api = {
|
||||
settings: { loaded: Promise.resolve() },
|
||||
} as unknown as PluginAPI<{}>;
|
||||
|
||||
async function startPlugin(): Promise<() => void> {
|
||||
const cleanup = (await errorPageKittenPlugin.run(api)) ?? (() => {});
|
||||
return cleanup;
|
||||
}
|
||||
|
||||
function getCard(): HTMLElement | null {
|
||||
// The card container shares its class with <html>, so scope to body.
|
||||
return document.body.querySelector<HTMLElement>(".bsplus-kitten-404");
|
||||
}
|
||||
|
||||
function expectKittenRendered(): void {
|
||||
const card = getCard();
|
||||
expect(card).not.toBeNull();
|
||||
expect(document.documentElement.classList).toContain("bsplus-kitten-404");
|
||||
expect(card?.querySelector("h1")?.textContent).toBe("404 Not Found");
|
||||
// The original document's title.
|
||||
expect(document.title).toBe("404 Not Found");
|
||||
// The reference page's exact vendor-prefixed banner CSS is shipped at runtime.
|
||||
const stripeStyle = Array.from(
|
||||
document.head.querySelectorAll("style"),
|
||||
).find((s) => s.textContent?.includes("-webkit-repeating-linear-gradient"));
|
||||
expect(stripeStyle?.textContent).toContain(
|
||||
"repeating-linear-gradient(45deg",
|
||||
);
|
||||
const img = card?.querySelector(".kitten img") as HTMLImageElement | null;
|
||||
expect(img?.getAttribute("alt")).toBeNull();
|
||||
expect(img?.src).toContain("kitten");
|
||||
const flickrLink = card?.querySelector(
|
||||
".attrib a",
|
||||
) as HTMLAnchorElement | null;
|
||||
expect(flickrLink?.textContent).toBe("by storyvillegirl");
|
||||
expect(flickrLink?.href).toBe(
|
||||
"http://www.flickr.com/photos/bibbit/2756165489/",
|
||||
);
|
||||
const seqtaLink = card?.querySelector("a[href='http://www.seqta.com.au']");
|
||||
expect(seqtaLink?.textContent).toBe("SEQTA");
|
||||
// Original rebranded message is hidden.
|
||||
expect(
|
||||
document.querySelector(".message")?.classList.contains(
|
||||
"bsplus-kitten-404-hidden",
|
||||
),
|
||||
).toBe(true);
|
||||
}
|
||||
|
||||
describe("errorPageKitten", () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = "";
|
||||
@@ -69,47 +37,24 @@ describe("errorPageKitten", () => {
|
||||
document.documentElement.classList.remove("bsplus-kitten-404");
|
||||
});
|
||||
|
||||
it("renders the classic kitten 404 card over the rebranded page", async () => {
|
||||
it("mounts the classic kitten 404 card", () => {
|
||||
document.title = "Page not found";
|
||||
document.body.innerHTML = REBRANDED_404_BODY;
|
||||
|
||||
const cleanup = await startPlugin();
|
||||
const cleanup = mountErrorPageKitten();
|
||||
|
||||
expectKittenRendered();
|
||||
const card = getCard();
|
||||
expect(card).not.toBeNull();
|
||||
expect(document.documentElement.classList).toContain("bsplus-kitten-404");
|
||||
expect(card?.querySelector("h1")?.textContent).toBe("404 Not Found");
|
||||
expect(document.title).toBe("404 Not Found");
|
||||
expect(card?.querySelector(".kitten img")?.getAttribute("src")).toContain("kitten");
|
||||
expect(
|
||||
document.querySelector(".message")?.classList.contains("bsplus-kitten-404-hidden"),
|
||||
).toBe(true);
|
||||
|
||||
cleanup();
|
||||
expect(getCard()).toBeNull();
|
||||
expect(document.title).toBe("Page not found");
|
||||
expect(
|
||||
Array.from(document.head.querySelectorAll("style")).some((s) =>
|
||||
s.textContent?.includes("-webkit-repeating-linear-gradient"),
|
||||
),
|
||||
).toBe(false);
|
||||
expect(
|
||||
document.documentElement.classList.contains("bsplus-kitten-404"),
|
||||
).toBe(false);
|
||||
expect(
|
||||
document
|
||||
.querySelector(".message")
|
||||
?.classList.contains("bsplus-kitten-404-hidden"),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("does not render inside the SPA (no .message, has #container)", async () => {
|
||||
document.title = "SEQTA";
|
||||
document.body.innerHTML = '<div id="container"></div>';
|
||||
|
||||
await startPlugin();
|
||||
|
||||
expect(getCard()).toBeNull();
|
||||
});
|
||||
|
||||
it("does not render on an unrelated page", async () => {
|
||||
document.title = "Home";
|
||||
document.body.innerHTML = '<div id="app"></div>';
|
||||
|
||||
await startPlugin();
|
||||
|
||||
expect(getCard()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,72 +4,43 @@ import kittenPng from "@/resources/error-page/kitten.png";
|
||||
import styles from "./styles.css?inline";
|
||||
|
||||
const KITTEN_IMG = resolveExtensionAssetUrl(kittenPng);
|
||||
const KITTEN_CLASS = "bsplus-kitten-404";
|
||||
const ROOT_CLASS = "bsplus-kitten-404";
|
||||
|
||||
// The reference page's exact h1 background declarations, in the original
|
||||
// order. Each engine keeps the last declaration it understands (-webkit in
|
||||
// Blink, -moz in Gecko, the legacy standard otherwise), so shipping them
|
||||
// byte-for-byte reproduces the reference banner on every engine. Lives in a
|
||||
// JS string because the CSS minifier drops vendor-prefixed declarations.
|
||||
const H1_STRIPE_CSS =
|
||||
"html.bsplus-kitten-404 .bsplus-kitten-404>h1{background-image:-moz-repeating-linear-gradient(135deg, rgba(0,0,0,0), rgba(0,0,0,0) 8px, rgba(0,0,0,0.05) 8px, rgba(0,0,0,0.05) 16px), -moz-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.1));background-image:-webkit-repeating-linear-gradient(135deg, rgba(0,0,0,0), rgba(0,0,0,0) 8px, rgba(0,0,0,0.05) 8px, rgba(0,0,0,0.05) 16px), -webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.1));background-image:-o-repeating-linear-gradient(135deg, rgba(0,0,0,0), rgba(0,0,0,0) 8px, rgba(0,0,0,0.05) 8px, rgba(0,0,0,0.05) 16px), -o-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.1));background-image:repeating-linear-gradient(45deg, rgba(0,0,0,0), rgba(0,0,0,0) 8px, rgba(0,0,0,0.05) 8px, rgba(0,0,0,0.05) 16px), linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.1))}";
|
||||
const CARD_HTML = `<h1>404 Not Found</h1>
|
||||
<p>Sorry — the resource you are looking for could not be found.</p>
|
||||
<p>If you believe you are seeing this message in error, please contact your IT department.</p>
|
||||
<div class="kitten">
|
||||
<p>I did find this picture of a kitten for you, though!</p>
|
||||
<img src="${KITTEN_IMG}" alt="">
|
||||
<div class="attrib">CC-BY-SA <a href="http://www.flickr.com/photos/bibbit/2756165489/">by storyvillegirl</a></div>
|
||||
</div>
|
||||
<a href="http://www.seqta.com.au">SEQTA</a>`;
|
||||
|
||||
// The 404 page (legacy and rebranded) is a standalone document built around a
|
||||
// single `.message` block; the real app mounts a `#container`. Require the
|
||||
// former and rule out the latter so the plugin never renders inside the app.
|
||||
function is404Page(): boolean {
|
||||
if (document.getElementById("container")) return false;
|
||||
const heading = document.querySelector(".message > h1");
|
||||
const text = heading?.textContent ?? document.title;
|
||||
return /not found/i.test(text) || /404/.test(document.title);
|
||||
}
|
||||
/** Boot path in SEQTA.ts gates when this runs; keep render-only here. */
|
||||
export function mountErrorPageKitten(): () => void {
|
||||
const styleEl = document.createElement("style");
|
||||
styleEl.textContent = styles;
|
||||
document.head.appendChild(styleEl);
|
||||
|
||||
const originalTitle = document.title;
|
||||
document.querySelector(".message")?.classList.add("bsplus-kitten-404-hidden");
|
||||
document.documentElement.classList.add(ROOT_CLASS);
|
||||
document.title = "404 Not Found";
|
||||
|
||||
function buildCard(): HTMLElement {
|
||||
const card = document.createElement("div");
|
||||
card.className = KITTEN_CLASS;
|
||||
card.className = ROOT_CLASS;
|
||||
card.innerHTML = CARD_HTML;
|
||||
document.body.appendChild(card);
|
||||
|
||||
const h1 = document.createElement("h1");
|
||||
h1.textContent = "404 Not Found";
|
||||
card.appendChild(h1);
|
||||
|
||||
const p1 = document.createElement("p");
|
||||
p1.textContent =
|
||||
"Sorry — the resource you are looking for could not be found.";
|
||||
card.appendChild(p1);
|
||||
|
||||
const p2 = document.createElement("p");
|
||||
p2.textContent =
|
||||
"If you believe you are seeing this message in error, please contact your IT department.";
|
||||
card.appendChild(p2);
|
||||
|
||||
const kitten = document.createElement("div");
|
||||
kitten.className = "kitten";
|
||||
|
||||
const kittenLine = document.createElement("p");
|
||||
kittenLine.textContent = "I did find this picture of a kitten for you, though!";
|
||||
kitten.appendChild(kittenLine);
|
||||
|
||||
const img = document.createElement("img");
|
||||
img.src = KITTEN_IMG;
|
||||
kitten.appendChild(img);
|
||||
|
||||
const attrib = document.createElement("div");
|
||||
attrib.className = "attrib";
|
||||
attrib.append("CC-BY-SA ");
|
||||
const link = document.createElement("a");
|
||||
link.href = "http://www.flickr.com/photos/bibbit/2756165489/";
|
||||
link.textContent = "by storyvillegirl";
|
||||
attrib.appendChild(link);
|
||||
kitten.appendChild(attrib);
|
||||
|
||||
card.appendChild(kitten);
|
||||
|
||||
const seqtaLink = document.createElement("a");
|
||||
seqtaLink.href = "http://www.seqta.com.au";
|
||||
seqtaLink.textContent = "SEQTA";
|
||||
card.appendChild(seqtaLink);
|
||||
|
||||
return card;
|
||||
return () => {
|
||||
styleEl.remove();
|
||||
document.documentElement.classList.remove(ROOT_CLASS);
|
||||
document
|
||||
.querySelectorAll(".bsplus-kitten-404-hidden")
|
||||
.forEach((el) => el.classList.remove("bsplus-kitten-404-hidden"));
|
||||
document.title = originalTitle;
|
||||
card.remove();
|
||||
};
|
||||
}
|
||||
|
||||
const errorPageKittenPlugin: Plugin = {
|
||||
@@ -81,52 +52,7 @@ const errorPageKittenPlugin: Plugin = {
|
||||
disableToggle: true,
|
||||
defaultEnabled: true,
|
||||
styles,
|
||||
|
||||
run: async (_api) => {
|
||||
let card: HTMLElement | null = null;
|
||||
let hasBuilt = false;
|
||||
let originalTitle = document.title;
|
||||
let stripeStyle: HTMLStyleElement | null = null;
|
||||
|
||||
const render = () => {
|
||||
if (!is404Page()) return;
|
||||
|
||||
document.querySelector(".message")?.classList.add("bsplus-kitten-404-hidden");
|
||||
|
||||
if (hasBuilt) return;
|
||||
const body = document.body;
|
||||
if (!body) return;
|
||||
|
||||
hasBuilt = true;
|
||||
document.documentElement.classList.add(KITTEN_CLASS);
|
||||
document.title = "404 Not Found";
|
||||
// Appended after the manager-injected styles so these same-specificity
|
||||
// declarations win over the compiled baseline.
|
||||
stripeStyle = document.createElement("style");
|
||||
stripeStyle.textContent = H1_STRIPE_CSS;
|
||||
document.head.appendChild(stripeStyle);
|
||||
card = buildCard();
|
||||
body.appendChild(card);
|
||||
};
|
||||
|
||||
// Body may not be parsed yet at document_start; render now and again on
|
||||
// DOM ready as a safety net.
|
||||
render();
|
||||
document.addEventListener("DOMContentLoaded", render, { once: true });
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("DOMContentLoaded", render);
|
||||
document.documentElement.classList.remove(KITTEN_CLASS);
|
||||
document
|
||||
.querySelectorAll(".bsplus-kitten-404-hidden")
|
||||
.forEach((el) => el.classList.remove("bsplus-kitten-404-hidden"));
|
||||
document.title = originalTitle;
|
||||
stripeStyle?.remove();
|
||||
stripeStyle = null;
|
||||
card?.remove();
|
||||
card = null;
|
||||
};
|
||||
},
|
||||
run: async () => mountErrorPageKitten(),
|
||||
};
|
||||
|
||||
export default errorPageKittenPlugin;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { defineLazyPlugin } from "../../core/dynamicLoader";
|
||||
import styles from "./styles.css?inline";
|
||||
|
||||
export default defineLazyPlugin({
|
||||
id: "error-page-kitten",
|
||||
name: "Classic 404 Page",
|
||||
description: "Brings back SEQTA's old kitten 404 page",
|
||||
version: "1.0.0",
|
||||
settings: {},
|
||||
disableToggle: true,
|
||||
defaultEnabled: true,
|
||||
styles,
|
||||
loader: () => import("./index"),
|
||||
});
|
||||
@@ -1,10 +1,5 @@
|
||||
/* Classic SEQTA 404 page, restored one-to-one over the rebranded document.
|
||||
Scoped under html.bsplus-kitten-404 so it can never leak into the SPA;
|
||||
the card element itself carries the .bsplus-kitten-404 class. */
|
||||
/* Classic SEQTA 404 page — scoped under html.bsplus-kitten-404 so it never leaks into the SPA. */
|
||||
|
||||
/* The rebranded page styles <body> (Arial / flex / 25vh top / line-height
|
||||
1.5 / letter-spacing). line-height and letter-spacing are reset because
|
||||
the rebranded body sets them and the classic page uses browser defaults. */
|
||||
html.bsplus-kitten-404 {
|
||||
background: #333;
|
||||
}
|
||||
@@ -20,7 +15,6 @@ html.bsplus-kitten-404 body {
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
/* Hide the rebranded page content while the classic card is shown. */
|
||||
html.bsplus-kitten-404 .bsplus-kitten-404-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -38,10 +32,6 @@ html.bsplus-kitten-404 .bsplus-kitten-404 {
|
||||
|
||||
html.bsplus-kitten-404 .bsplus-kitten-404 > h1 {
|
||||
background: #612;
|
||||
/* Valid modern baseline; the reference's exact vendor-prefixed declarations
|
||||
are injected at runtime (H1_STRIPE_CSS in index.ts), which win over this.
|
||||
The vendor-prefixed lines can't live in this file because the CSS
|
||||
minifier drops them. */
|
||||
background-image: repeating-linear-gradient(
|
||||
135deg,
|
||||
rgba(0, 0, 0, 0),
|
||||
|
||||
@@ -26,9 +26,6 @@ interface StorageChange<T = any> {
|
||||
|
||||
/** Phased plugin startup: critical UI first, light DOM next, heavy plugins last. */
|
||||
const PLUGIN_START_PHASES: readonly string[][] = [
|
||||
// 404 page boot is a tiny standalone path; start it first so the kitten
|
||||
// card renders before any SPA work. A no-op on normal SEQTA pages.
|
||||
["error-page-kitten"],
|
||||
["themes", "animated-background"],
|
||||
[
|
||||
"timetable",
|
||||
|
||||
@@ -16,7 +16,7 @@ import messageFoldersPluginLazy from "./built-in/messageFolders/lazy";
|
||||
import enhancedNavigationPluginLazy from "./built-in/enhancedNavigation/lazy";
|
||||
import globalSearchPluginLazy from "./built-in/globalSearch/lazy";
|
||||
import gradeAnalyticsPluginLazy from "./built-in/gradeAnalytics/lazy";
|
||||
import errorPageKittenPluginLazy from "./built-in/errorPageKitten/lazy";
|
||||
import errorPageKittenPlugin from "./built-in/errorPageKitten";
|
||||
|
||||
// Initialize plugin manager
|
||||
const pluginManager = PluginManager.getInstance();
|
||||
@@ -37,7 +37,7 @@ pluginManager.registerPlugin(messageFoldersPluginLazy);
|
||||
pluginManager.registerPlugin(enhancedNavigationPluginLazy);
|
||||
pluginManager.registerPlugin(globalSearchPluginLazy);
|
||||
pluginManager.registerPlugin(gradeAnalyticsPluginLazy);
|
||||
pluginManager.registerPlugin(errorPageKittenPluginLazy);
|
||||
pluginManager.registerPlugin(errorPageKittenPlugin);
|
||||
|
||||
export async function initializePlugins(): Promise<void> {
|
||||
await pluginManager.startAllPlugins();
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
// Jest stub for Vite asset imports (png, etc.): Vite returns a URL string.
|
||||
export default "/resources/error-page/kitten.png";
|
||||
@@ -1,2 +0,0 @@
|
||||
// Jest stub for Vite's `?inline` css imports: returns a CSS string.
|
||||
export default "/* test inline css */";
|
||||
@@ -32,9 +32,6 @@ export default {
|
||||
storage: { local, onChanged },
|
||||
runtime: {
|
||||
sendMessage: jest.fn(async () => undefined),
|
||||
getURL: jest.fn(
|
||||
(path: string) => `chrome-extension://test/${String(path).replace(/^\/+/, "")}`,
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user