diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index 7a1d267cd045..26734ca809e8 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -3,31 +3,34 @@ const fs = require('fs') const path = require('path') const url = require('url') -// Mapping between hostname and file path. -var hostPathMap = {} -var hostPathMapNextKey = 0 +// Remove this when we have Object.values(). +const objectValues = function (object) { + return Object.keys(object).map(function (key) { return object[key] }) +} -var generateHostForPath = function (path) { - var key - key = 'extension-' + (++hostPathMapNextKey) +// Mapping between hostname and file path. +let hostPathMap = {} +let hostPathMapNextKey = 0 + +const generateHostForPath = function (path) { + let key = `extension-${++hostPathMapNextKey}` hostPathMap[key] = path return key } -var getPathForHost = function (host) { +const getPathForHost = function (host) { return hostPathMap[host] } // Cache extensionInfo. -var extensionInfoMap = {} +let extensionInfoMap = {} -var getExtensionInfoFromPath = function (srcDirectory) { - var manifest, page - manifest = JSON.parse(fs.readFileSync(path.join(srcDirectory, 'manifest.json'))) +const getExtensionInfoFromPath = function (srcDirectory) { + let manifest = JSON.parse(fs.readFileSync(path.join(srcDirectory, 'manifest.json'))) if (extensionInfoMap[manifest.name] == null) { // We can not use 'file://' directly because all resources in the extension // will be treated as relative to the root in Chrome. - page = url.format({ + let page = url.format({ protocol: 'chrome-extension', slashes: true, hostname: generateHostForPath(srcDirectory), @@ -43,13 +46,18 @@ var getExtensionInfoFromPath = function (srcDirectory) { } } -// The loaded extensions cache and its persistent path. -var loadedExtensions = null -var loadedExtensionsPath = null +// Load the extensions for the window. +const loadDevToolsExtensions = function (win, extensionInfoArray) { + if (!win.devToolsWebContents) return + win.devToolsWebContents.executeJavaScript(`DevToolsAPI.addExtensions(${JSON.stringify(extensionInfoArray)})`) +} + +// The persistent path of "DevTools Extensions" preference file. +let loadedExtensionsPath = null app.on('will-quit', function () { try { - loadedExtensions = Object.keys(extensionInfoMap).map(function (key) { + let loadedExtensions = Object.keys(extensionInfoMap).map(function (key) { return extensionInfoMap[key].srcDirectory }) if (loadedExtensions.length > 0) { @@ -69,74 +77,56 @@ app.on('will-quit', function () { // We can not use protocol or BrowserWindow until app is ready. app.once('ready', function () { - var chromeExtensionHandler, i, init, len, srcDirectory - // Load persisted extensions. loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions') try { - loadedExtensions = JSON.parse(fs.readFileSync(loadedExtensionsPath)) - if (!Array.isArray(loadedExtensions)) { - loadedExtensions = [] - } - - // Preheat the extensionInfo cache. - for (i = 0, len = loadedExtensions.length; i < len; i++) { - srcDirectory = loadedExtensions[i] - getExtensionInfoFromPath(srcDirectory) + let loadedExtensions = JSON.parse(fs.readFileSync(loadedExtensionsPath)) + if (Array.isArray(loadedExtensions)) { + // Preheat the extensionInfo cache. + for (let srcDirectory of loadedExtensions) { + getExtensionInfoFromPath(srcDirectory) + } } } catch (error) { // Ignore error } // The chrome-extension: can map a extension URL request to real file path. - chromeExtensionHandler = function (request, callback) { - var directory, parsed - parsed = url.parse(request.url) - if (!(parsed.hostname && (parsed.path != null))) { - return callback() - } - if (!/extension-\d+/.test(parsed.hostname)) { - return callback() - } - directory = getPathForHost(parsed.hostname) - if (directory == null) { - return callback() - } - return callback(path.join(directory, parsed.path)) + const chromeExtensionHandler = function (request, callback) { + let parsed = url.parse(request.url) + if (!parsed.hostname || !parsed.path) return callback() + if (!/extension-\d+/.test(parsed.hostname)) return callback() + + let directory = getPathForHost(parsed.hostname) + if (!directory) return callback() + + callback(path.join(directory, parsed.path)) } protocol.registerFileProtocol('chrome-extension', chromeExtensionHandler, function (error) { if (error) { - return console.error('Unable to register chrome-extension protocol') + console.error(`Unable to register chrome-extension protocol: ${error}`) } }) - BrowserWindow.prototype._loadDevToolsExtensions = function (extensionInfoArray) { - var ref - return (ref = this.devToolsWebContents) != null ? ref.executeJavaScript('DevToolsAPI.addExtensions(' + (JSON.stringify(extensionInfoArray)) + ');') : void 0 - } + BrowserWindow.addDevToolsExtension = function (srcDirectory) { - var extensionInfo, j, len1, ref, window - extensionInfo = getExtensionInfoFromPath(srcDirectory) + let extensionInfo = getExtensionInfoFromPath(srcDirectory) if (extensionInfo) { - ref = BrowserWindow.getAllWindows() - for (j = 0, len1 = ref.length; j < len1; j++) { - window = ref[j] - window._loadDevToolsExtensions([extensionInfo]) + for (let win of BrowserWindow.getAllWindows()) { + loadDevToolsExtensions(win, [extensionInfo]) } return extensionInfo.name } } BrowserWindow.removeDevToolsExtension = function (name) { - return delete extensionInfoMap[name] + delete extensionInfoMap[name] } // Load persisted extensions when devtools is opened. - init = BrowserWindow.prototype._init + let init = BrowserWindow.prototype._init BrowserWindow.prototype._init = function () { init.call(this) - return this.webContents.on('devtools-opened', () => { - return this._loadDevToolsExtensions(Object.keys(extensionInfoMap).map(function (key) { - return extensionInfoMap[key] - })) + this.webContents.on('devtools-opened', () => { + loadDevToolsExtensions(this, objectValues(extensionInfoMap)) }) } })