-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent-script.ts
More file actions
53 lines (48 loc) · 2.08 KB
/
Copy pathcontent-script.ts
File metadata and controls
53 lines (48 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* content-script.ts — runs in the inspected page's **isolated world**. It is the
* bridge between the page (which it cannot read directly) and the extension. Two
* jobs:
*
* 1. Inject `page-script.js` into the page's MAIN world so it can reach the
* real `QueryClient` (content scripts are sandboxed away from page globals).
* 2. Relay messages both ways:
* page --window.postMessage--> content --chrome.runtime--> background
* background --chrome.runtime--> content --window.postMessage--> page
*
* This file intentionally has NO top-level `import`/`export`: a declared MV3
* content script is loaded as a classic script, so it must compile to one. The
* message shape is declared locally (mirrors `Envelope` in `types.ts`).
*/
// Local, non-exported mirror of the shared Envelope — keeps this file a script.
interface CsEnvelope {
source: "qci-page" | "qci-content" | "qci-panel" | "qci-background";
kind: string;
}
// 1. Inject the MAIN-world page script as a module so it can `import` snapshot.js.
function inject(): void {
const script = document.createElement("script");
script.type = "module";
script.src = chrome.runtime.getURL("js/page-script.js");
script.dataset.qci = "page-script";
(document.head || document.documentElement).appendChild(script);
// Leave it in the DOM; removing an already-executed module script is harmless
// but keeping it makes the injection observable when debugging.
}
// 2a. Page -> background.
window.addEventListener("message", (event: MessageEvent<CsEnvelope>) => {
if (event.source !== window) return;
const data = event.data;
if (!data || data.source !== "qci-page") return;
try {
chrome.runtime.sendMessage(data);
} catch {
/* extension context may be gone during reloads; ignore */
}
});
// 2b. Background -> page (e.g. a refresh ping originating in the panel).
chrome.runtime.onMessage.addListener((message: CsEnvelope) => {
if (message?.source === "qci-background" && message.kind === "ping") {
window.postMessage({ source: "qci-content", kind: "ping" }, "*");
}
});
inject();