|
| 1 | +/* global chrome */ |
| 2 | + |
| 3 | +import {IS_FIREFOX} from '../utils'; |
| 4 | + |
| 5 | +async function dynamicallyInjectContentScripts() { |
| 6 | + const contentScriptsToInject = [ |
| 7 | + { |
| 8 | + id: '@react-devtools/hook', |
| 9 | + js: ['build/installHook.js'], |
| 10 | + matches: ['<all_urls>'], |
| 11 | + persistAcrossSessions: true, |
| 12 | + runAt: 'document_start', |
| 13 | + world: chrome.scripting.ExecutionWorld.MAIN, |
| 14 | + }, |
| 15 | + { |
| 16 | + id: '@react-devtools/renderer', |
| 17 | + js: ['build/renderer.js'], |
| 18 | + matches: ['<all_urls>'], |
| 19 | + persistAcrossSessions: true, |
| 20 | + runAt: 'document_start', |
| 21 | + world: chrome.scripting.ExecutionWorld.MAIN, |
| 22 | + }, |
| 23 | + ]; |
| 24 | + |
| 25 | + try { |
| 26 | + const alreadyRegisteredContentScripts = |
| 27 | + await chrome.scripting.getRegisteredContentScripts(); |
| 28 | + |
| 29 | + const scriptsToInjectNow = contentScriptsToInject.filter( |
| 30 | + scriptToInject => |
| 31 | + !alreadyRegisteredContentScripts.some( |
| 32 | + registeredScript => registeredScript.id === scriptToInject.id, |
| 33 | + ), |
| 34 | + ); |
| 35 | + |
| 36 | + if (scriptsToInjectNow.length) { |
| 37 | + // equivalent logic for Firefox is in prepareInjection.js |
| 38 | + // Manifest V3 method of injecting content script |
| 39 | + // TODO(hoxyq): migrate Firefox to V3 manifests |
| 40 | + // Note: the "world" option in registerContentScripts is only available in Chrome v102+ |
| 41 | + // It's critical since it allows us to directly run scripts on the "main" world on the page |
| 42 | + // "document_start" allows it to run before the page's scripts |
| 43 | + // so the hook can be detected by react reconciler |
| 44 | + await chrome.scripting.registerContentScripts(scriptsToInjectNow); |
| 45 | + } |
| 46 | + } catch (error) { |
| 47 | + console.error(error); |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +if (!IS_FIREFOX) { |
| 52 | + dynamicallyInjectContentScripts(); |
| 53 | +} |
0 commit comments