diff --git a/add-on/manifest.firefox.json b/add-on/manifest.firefox.json index 0865fb696..30d74bb1d 100644 --- a/add-on/manifest.firefox.json +++ b/add-on/manifest.firefox.json @@ -18,6 +18,7 @@ "default_title": "__MSG_pageAction_titleNonIpfs__", "default_popup": "dist/popup/page-action/index.html" }, + "content_scripts": null, "protocol_handlers": [ { "protocol": "web+dweb", diff --git a/add-on/src/lib/ipfs-companion.js b/add-on/src/lib/ipfs-companion.js index 64b04d769..bd30dffd7 100644 --- a/add-on/src/lib/ipfs-companion.js +++ b/add-on/src/lib/ipfs-companion.js @@ -30,6 +30,7 @@ module.exports = async function init () { var contextMenus var apiStatusUpdateInterval var ipfsProxy + var ipfsProxyContentScript const idleInSecs = 5 * 60 const browserActionPortName = 'browser-action-port' @@ -60,6 +61,7 @@ module.exports = async function init () { }) modifyRequest = createRequestModifier(getState, dnsLink, ipfsPathValidator, runtime) ipfsProxy = createIpfsProxy(() => ipfs, getState) + ipfsProxyContentScript = await registerIpfsProxyContentScript() registerListeners() await setApiStatusUpdateInterval(options.ipfsApiPollMs) await storeMissingOptions( @@ -95,6 +97,33 @@ module.exports = async function init () { } } + // Register Content Script responsible for loading window.ipfs (ipfsProxy) + // + // The key difference between tabs.executeScript and contentScripts API + // is the latter provides guarantee to execute before anything else. + // https://github.com/ipfs-shipyard/ipfs-companion/issues/451#issuecomment-382669093 + async function registerIpfsProxyContentScript (previousHandle) { + previousHandle = previousHandle || ipfsProxyContentScript + if (previousHandle) { + previousHandle.unregister() + } + if (!state.ipfsProxy || !browser.contentScripts) { + // no-op if window.ipfs is disabled in Preferences + // or if runtime has no contentScript API + // (Chrome loads content script via manifest) + return + } + const newHandle = await browser.contentScripts.register({ + matches: [''], + js: [ + {file: '/dist/contentScripts/ipfs-proxy/content.js'} + ], + allFrames: true, + runAt: 'document_start' + }) + return newHandle + } + // HTTP Request Hooks // =================================================================== @@ -544,13 +573,16 @@ module.exports = async function init () { case 'useCustomGateway': state.redirect = change.newValue break + case 'ipfsProxy': + state[key] = change.newValue + ipfsProxyContentScript = await registerIpfsProxyContentScript() + break case 'linkify': case 'catchUnhandledProtocols': case 'displayNotifications': case 'automaticMode': case 'dnslink': case 'preloadAtPublicGateway': - case 'ipfsProxy': state[key] = change.newValue break } @@ -616,6 +648,10 @@ module.exports = async function init () { contextMenus = null ipfsProxy.destroy() ipfsProxy = null + if (ipfsProxyContentScript) { + ipfsProxyContentScript.unregister() + ipfsProxyContentScript = null + } await destroyIpfsClient() } }