diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index e882b1862d..4626270a87 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -1,4 +1,4 @@ -const {app, protocol, BrowserWindow} = require('electron') +const {app, protocol, webContents, BrowserWindow} = require('electron') const fs = require('fs') const path = require('path') const url = require('url') @@ -28,24 +28,43 @@ let manifestMap = {} const getManifestFromPath = function (srcDirectory) { let manifest = JSON.parse(fs.readFileSync(path.join(srcDirectory, 'manifest.json'))) if (!manifestMap[manifest.name]) { + const hostname = generateHostForPath(srcDirectory) manifestMap[manifest.name] = manifest - // We can not use 'file://' directly because all resources in the extension - // will be treated as relative to the root in Chrome. - manifest.startPage = url.format({ - protocol: 'chrome-extension', - slashes: true, - hostname: generateHostForPath(srcDirectory), - pathname: manifest.devtools_page + Object.assign(manifest, { + srcDirectory: srcDirectory, + hostname: hostname, + // We can not use 'file://' directly because all resources in the extension + // will be treated as relative to the root in Chrome. + startPage: url.format({ + protocol: 'chrome-extension', + slashes: true, + hostname: hostname, + pathname: manifest.devtools_page + }) }) - manifest.srcDirectory = srcDirectory return manifest } } -// Load the extensions for the window. -const loadDevToolsExtensions = function (win, extensionInfoArray) { - if (!win.devToolsWebContents) return - win.devToolsWebContents.executeJavaScript(`DevToolsAPI.addExtensions(${JSON.stringify(extensionInfoArray)})`) +// Manage the background pages. +let backgroundPages = {} + +const startBackgroundPages = function (manifest) { + if (backgroundPages[manifest.hostname] || !manifest.background) return + + const scripts = manifest.background.scripts.map((name) => { + return `` + }).join('') + const html = new Buffer(`${scripts}`) + + const contents = webContents.create({}) + backgroundPages[manifest.hostname] = { html: html, contents: contents } + contents.loadURL(url.format({ + protocol: 'chrome-extension', + slashes: true, + hostname: manifest.hostname, + pathname: '_generated_background_page.html' + })) } // Transfer the |manifest| to a format that can be recognized by the @@ -59,6 +78,17 @@ const manifestToExtensionInfo = function (manifest) { } } +// Load the extensions for the window. +const loadDevToolsExtensions = function (win, manifests) { + if (!win.devToolsWebContents) return + + for (let manifest of manifests) { + startBackgroundPages(manifest) + } + const extensionInfoArray = manifests.map(manifestToExtensionInfo) + win.devToolsWebContents.executeJavaScript(`DevToolsAPI.addExtensions(${JSON.stringify(extensionInfoArray)})`) +} + // The persistent path of "DevTools Extensions" preference file. let loadedExtensionsPath = null @@ -107,9 +137,22 @@ app.once('ready', function () { let directory = getPathForHost(parsed.hostname) if (!directory) return callback() - callback(path.join(directory, parsed.path)) + if (parsed.path === '/_generated_background_page.html' && + backgroundPages[parsed.hostname]) { + return callback({ + mimeType: 'text/html', + data: backgroundPages[parsed.hostname].html + }) + } + + fs.readFile(path.join(directory, parsed.path), function (err, content) { + if (err) + callback(-6) // FILE_NOT_FOUND + else + return callback({mimeType: 'text/html', data: content}) + }) } - protocol.registerFileProtocol('chrome-extension', chromeExtensionHandler, function (error) { + protocol.registerBufferProtocol('chrome-extension', chromeExtensionHandler, function (error) { if (error) { console.error(`Unable to register chrome-extension protocol: ${error}`) } @@ -118,9 +161,8 @@ app.once('ready', function () { BrowserWindow.addDevToolsExtension = function (srcDirectory) { const manifest = getManifestFromPath(srcDirectory) if (manifest) { - const extensionInfo = manifestToExtensionInfo(manifest) for (let win of BrowserWindow.getAllWindows()) { - loadDevToolsExtensions(win, [extensionInfo]) + loadDevToolsExtensions(win, [manifest]) } return manifest.name } @@ -134,7 +176,7 @@ app.once('ready', function () { BrowserWindow.prototype._init = function () { init.call(this) this.webContents.on('devtools-opened', () => { - loadDevToolsExtensions(this, objectValues(manifestMap).map(manifestToExtensionInfo)) + loadDevToolsExtensions(this, objectValues(manifestMap)) }) } })