Skip to content

Commit 0a82180

Browse files
committed
feat: content script blob src
1 parent 89d961c commit 0a82180

File tree

6 files changed

+30
-10
lines changed

6 files changed

+30
-10
lines changed

.github/ISSUE_TEMPLATE.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- [ ] Force Copy
1414
- [ ] Copy Currency
1515
- [ ] Site Director
16+
- [ ] Water Mark
1617
- [ ] Captcha
1718
- [ ] Expansion
1819
- [ ] Completion

packages/force-copy/src/content/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import { onPopupMessage } from "./channel/popup";
44
import { LOG_LEVEL, logger } from "@/utils/logger";
55
import { initializeWorker } from "./runtime/initialize";
66
import { isInIframe } from "@/utils/is";
7-
import { importScript } from "./runtime/script";
7+
import { importInjectScript } from "./runtime/script";
88

99
(() => {
1010
if (__DEV__) {
1111
!isInIframe && onReceiveReloadMsg();
1212
logger.setLevel(LOG_LEVEL.INFO);
1313
}
1414
logger.info("Content Script Loaded");
15-
importScript();
15+
importInjectScript();
1616
!isInIframe && initializeWorker();
1717
PCBridge.onPopupMessage(onPopupMessage);
1818
})();
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
1-
export const importScript = () => {
1+
export const importInjectScript = () => {
22
const fn = window[process.env.INJECT_FILE as unknown as number] as unknown as () => void;
33
// #IFDEF GECKO
4-
if (fn) {
5-
// FIX: FireFox 的 XML 阅读页面会嵌入 script 标签
6-
if (document instanceof XMLDocument) return void 0;
4+
if (fn && document instanceof XMLDocument === false) {
75
const script = document.createElementNS("http://www.w3.org/1999/xhtml", "script");
86
script.setAttribute("type", "text/javascript");
97
// 这里的内容需要跟 WrapperCodePlugin 的 HASH 计算保持一致
10-
script.innerText = `;(${fn.toString()})();`;
8+
const code = `;(${fn.toString()})();`;
9+
script.innerText = code;
1110
document.documentElement.appendChild(script);
1211
// 在这里仅移除 script 标签, 但不会删除 window 上的属性
1312
// 保证注入重试, inject 幂等且 content 处于隔离环境不会受到影响
1413
script.remove();
14+
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts
15+
const unsafeWindow = window.wrappedJSObject;
16+
const signal = process.env.EVENT_TYPE;
17+
// 此时说明页面中的脚本没有被注入 尝试以 blob 的形式注入
18+
if (unsafeWindow && !unsafeWindow[signal]) {
19+
const blob = new Blob([code], { type: "application/javascript" });
20+
const url = URL.createObjectURL(blob);
21+
const script = document.createElementNS("http://www.w3.org/1999/xhtml", "script");
22+
script.setAttribute("type", "text/javascript");
23+
// 实际上这里是异步的引入 不能完全保证 document_start 的时机
24+
(<HTMLScriptElement>script).src = url;
25+
document.documentElement.appendChild(script);
26+
script.onload = () => {
27+
script.remove();
28+
// 如果仍然不存在 尝试在 Content Script 中执行
29+
!unsafeWindow[signal] && fn();
30+
};
31+
}
1532
}
1633
// #ENDIF
1734
};
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
declare interface Window {
33
pad?: any;
4+
wrappedJSObject?: any;
45
SpreadsheetApp?: any;
56
}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { LOG_LEVEL, logger } from "@/utils/logger";
2-
import { importScript } from "./runtime/script";
2+
import { importWorkerScript } from "./runtime/script";
33
import { CWBridge } from "@/bridge/content-worker";
44
import { onContentMessage } from "./channel/content";
55
import { initializeEvents } from "./runtime/initialize";
@@ -8,7 +8,7 @@ import { initializeEvents } from "./runtime/initialize";
88
if (__DEV__) {
99
logger.setLevel(LOG_LEVEL.INFO);
1010
}
11-
importScript();
1211
initializeEvents();
12+
importWorkerScript();
1313
CWBridge.onContentMessage(onContentMessage);
1414
})();

packages/force-copy/src/worker/runtime/script.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { cross } from "@/utils/global";
33
import { logger } from "@/utils/logger";
44
import { CODE_PREFIX, CODE_SUFFIX } from "../utils/constant";
55

6-
export const importScript = () => {
6+
export const importWorkerScript = () => {
77
// #IFDEF CHROMIUM
88
// https://bugs.chromium.org/p/chromium/issues/detail?id=634381
99
// https://stackoverflow.com/questions/75495191/chrome-extension-manifest-v3-how-to-use-window-addeventlistener
@@ -52,6 +52,7 @@ export const importScript = () => {
5252
// 使用 cross.tabs.executeScript 得到的 window 是 content window
5353
// 此时就必须要使用 inject script 的方式才能正常注入脚本
5454
// 然而这种方式就会受到 content security policy 策略的限制
55+
// https://github.com/violentmonkey/violentmonkey/issues/1001
5556
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onHeadersReceived
5657
chrome.webRequest.onHeadersReceived.addListener(
5758
res => {

0 commit comments

Comments
 (0)