From 8134585578a6b1424e14e7441ee663ee4d3e06ae Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 28 Aug 2014 14:58:15 +0800 Subject: [PATCH] Remember loaded extensions. --- atom/browser/api/lib/browser-window.coffee | 2 +- atom/browser/lib/chrome-extension.coffee | 69 ++++++++++++++++++++++++------ atom/browser/lib/init.coffee | 6 +-- 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index d76bfbf..8af84aa 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -36,7 +36,7 @@ BrowserWindow::openDevTools = -> @devToolsWebContents.once 'destroyed', => @devToolsWebContents = null # Emit devtools events. - @emit 'dev-tools-opened' + @devToolsWebContents.once 'did-finish-load', => @emit 'dev-tools-opened' @devToolsWebContents.once 'destroyed', => @emit 'dev-tools-closed' BrowserWindow::toggleDevTools = -> diff --git a/atom/browser/lib/chrome-extension.coffee b/atom/browser/lib/chrome-extension.coffee index 6ca1bc1..98b430f 100644 --- a/atom/browser/lib/chrome-extension.coffee +++ b/atom/browser/lib/chrome-extension.coffee @@ -15,29 +15,74 @@ getHostForPath = (path) -> getPathForHost = (host) -> hostPathMap[host] +# Cache extensionInfo. +extensionInfoMap = {} + +getExtensionInfoFromPath = (srcDirectory) -> + manifest = JSON.parse fs.readFileSync(path.join(srcDirectory, 'manifest.json')) + unless extensionInfoMap[manifest.name]? + # 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 + protocol: 'chrome-extension' + slashes: true + hostname: getHostForPath srcDirectory + pathname: manifest.devtools_page + extensionInfoMap[manifest.name] = + startPage: page + name: manifest.name + srcDirectory: srcDirectory + extensionInfoMap[manifest.name] + +# Load persistented extensions. +loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions' + +try + loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath) + loadedExtensions = [] unless Array.isArray loadedExtensions + # Preheat the extensionInfo cache. + getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions +catch e + +# Persistent loaded extensions. +app.on 'will-quit', -> + try + loadedExtensions = Object.keys(extensionInfoMap).map (key) -> extensionInfoMap[key].srcDirectory + try + fs.mkdirSync path.dirname(loadedExtensionsPath) + catch e + fs.writeFileSync loadedExtensionsPath, JSON.stringify(loadedExtensions) + catch e + +# We can not use protocol or BrowserWindow until app is ready. app.once 'ready', -> protocol = require 'protocol' BrowserWindow = require 'browser-window' + # The chrome-extension: can map a extension URL request to real file path. protocol.registerProtocol 'chrome-extension', (request) -> parsed = url.parse request.url return unless parsed.hostname and parsed.path? - return unless /extension-\d+/.test parsed.hostname directory = getPathForHost parsed.hostname + return unless directory? return new protocol.RequestFileJob(path.join(directory, parsed.path)) - BrowserWindow::loadDevToolsExtension = (srcDirectory) -> - manifest = JSON.parse fs.readFileSync(path.join(srcDirectory, 'manifest.json')) + BrowserWindow::_loadDevToolsExtensions = (extensionInfoArray) -> + @devToolsWebContents?.executeJavaScript "WebInspector.addExtensions(#{JSON.stringify(extensionInfoArray)});" - # 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 - protocol: 'chrome-extension' - slashes: true - hostname: getHostForPath srcDirectory - pathname: manifest.devtools_page + BrowserWindow.addDevToolsExtension = (srcDirectory) -> + extensionInfo = getExtensionInfoFromPath srcDirectory + window._loadDevToolsExtensions [extensionInfo] for window in BrowserWindow.getAllWindows() + extensionInfo.name + + BrowserWindow.removeDevToolsExtension = (name) -> + delete extensionInfoMap[name] - extensionInfo = startPage: page, name: manifest.name - @devToolsWebContents?.executeJavaScript "WebInspector.addExtensions([#{JSON.stringify(extensionInfo)}]);" + # Load persistented extensions when devtools is opened. + init = BrowserWindow::_init + BrowserWindow::_init = -> + init.call this + @on 'dev-tools-opened', -> + @_loadDevToolsExtensions Object.keys(extensionInfoMap).map (key) -> extensionInfoMap[key] diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 3c5b059..e164b88 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -52,9 +52,6 @@ setImmediate -> detail: message buttons: ['OK'] - # Load the chrome extension support. - require './chrome-extension.js' - # Load the RPC server. require './rpc-server.js' @@ -80,5 +77,8 @@ setImmediate -> else if packageJson.name? app.setName packageJson.name + # Load the chrome extension support. + require './chrome-extension.js' + # Finally load app's main.js and transfer control to C++. module._load path.join(packagePath, packageJson.main), module, true -- 2.7.4