|
1 |
| -export const importScript = () => { |
| 1 | +export const importInjectScript = () => { |
2 | 2 | const fn = window[process.env.INJECT_FILE as unknown as number] as unknown as () => void;
|
3 | 3 | // #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) { |
7 | 5 | const script = document.createElementNS("http://www.w3.org/1999/xhtml", "script");
|
8 | 6 | script.setAttribute("type", "text/javascript");
|
9 | 7 | // 这里的内容需要跟 WrapperCodePlugin 的 HASH 计算保持一致
|
10 |
| - script.innerText = `;(${fn.toString()})();`; |
| 8 | + const code = `;(${fn.toString()})();`; |
| 9 | + script.innerText = code; |
11 | 10 | document.documentElement.appendChild(script);
|
12 | 11 | // 在这里仅移除 script 标签, 但不会删除 window 上的属性
|
13 | 12 | // 保证注入重试, inject 幂等且 content 处于隔离环境不会受到影响
|
14 | 13 | 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 | + } |
15 | 32 | }
|
16 | 33 | // #ENDIF
|
17 | 34 | };
|
0 commit comments