From bd00a85e0d5eaff33677c122bf774c3e6667879c Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Tue, 26 Jan 2016 19:15:05 +0100 Subject: [PATCH] Use `chrome://` URIs for `require()` calls Apparently, `chrome://` URIs registered in chrome.manifest cannot be used in bootstrap.js until its `startup()` function is called. Therefore this commit reorganizes the code of bootstrap.coffee a bit, so that actual work is done inside `startup()` (where it is supposed to be, after all). Outside of that function we now mostly simply declare variables that the `shutdown()` function needs to access as well. Some things were moved into main.coffee as well. - Using `chrome://` URIs is the way add-ons are "supposed" to do it. - If a `require()` call fails, we now get much shorter URIs in the error message, making things easier to debug. - This allows to get rid of the hack of sending `__SCRIPT_URI_SPEC__` to frame scripts. --- extension/bootstrap.coffee | 55 +++++++++++----------------- extension/lib/l10n.coffee | 2 +- extension/lib/main.coffee | 32 +++++++++------- extension/lib/message-manager.coffee | 8 ++-- extension/lib/utils.coffee | 2 +- 5 files changed, 46 insertions(+), 53 deletions(-) diff --git a/extension/bootstrap.coffee b/extension/bootstrap.coffee index 52b0cad..e04f957 100644 --- a/extension/bootstrap.coffee +++ b/extension/bootstrap.coffee @@ -31,20 +31,17 @@ do (global = this) -> {classes: Cc, interfaces: Ci, utils: Cu} = Components + ADDON_PATH = 'chrome://vimfx' IS_FRAME_SCRIPT = (typeof content != 'undefined') if IS_FRAME_SCRIPT # Tell the main process that this frame script was created, and get data # back that only the main process has access to. - [data] = sendSyncMessage('VimFx:tabCreated') + [ok] = sendSyncMessage("#{ADDON_PATH}/tabCreated") # The main process told this frame script not to do anything (or there was # an error and no message was received at all). - return unless data - - FRAME_SCRIPT_ENVIRONMENT = global - global = {} - [global.__SCRIPT_URI_SPEC__] = data + return unless ok else # Make `Services` and `console` available globally, just like they are in @@ -56,16 +53,9 @@ do (global = this) -> catch Cu.import('resource://gre/modules/devtools/Console.jsm') - - FRAME_SCRIPT_ENVIRONMENT = null - shutdownHandlers = [] - createURI = (path, base = null) -> Services.io.newURI(path, null, base) - baseURI = createURI(global.__SCRIPT_URI_SPEC__) - - # Everything up to the first `!` is the absolute path to the .xpi. - dirname = (uri) -> uri.match(///^ [^!]+!/ (.+) /[^/]+ $///)[1] + dirname = (uri) -> uri.split('/')[...-1].join('/') or '.' require = (path, moduleRoot = '.', dir = '.') -> unless path[0] == '.' @@ -77,36 +67,33 @@ do (global = this) -> path = subPath ? main ? 'index' moduleRoot = dir - fullPath = createURI("#{dir}/#{path}.js", baseURI).spec + prefix = "#{ADDON_PATH}/content" + uri = "#{prefix}/#{dir}/#{path}.js" + normalizedUri = Services.io.newURI(uri, null, null).spec + currentDir = dirname(".#{normalizedUri[prefix.length..]}") - unless require.scopes[fullPath]? + unless require.scopes[normalizedUri]? module = exports: {} onShutdown: (fn) -> shutdownHandlers.push(fn) - require.scopes[fullPath] = scope = { - require: (path) -> require(path, moduleRoot, "./#{dirname(fullPath)}") + require.scopes[normalizedUri] = scope = { + require: (path) -> require(path, moduleRoot, currentDir) module, exports: module.exports Cc, Ci, Cu - IS_FRAME_SCRIPT, FRAME_SCRIPT_ENVIRONMENT + ADDON_PATH + IS_FRAME_SCRIPT + FRAME_SCRIPT_ENVIRONMENT: if IS_FRAME_SCRIPT then global else null } - Services.scriptloader.loadSubScript(fullPath, scope, 'UTF-8') - - return require.scopes[fullPath].module.exports - - require.scopes = {} - require.data = require('./require-data') + Services.scriptloader.loadSubScript(normalizedUri, scope, 'UTF-8') - unless IS_FRAME_SCRIPT - # Set default prefs and apply migrations as early as possible. - {applyMigrations} = require('./lib/legacy') - migrations = require('./lib/migrations') - prefs = require('./lib/prefs') + return require.scopes[normalizedUri].module.exports - prefs.default.init() - applyMigrations(migrations) + global.startup = (args...) -> + require.scopes = {} + require.data = require('./require-data') - main = if IS_FRAME_SCRIPT then './lib/main-frame' else './lib/main' - global.startup = require(main) + main = if IS_FRAME_SCRIPT then './lib/main-frame' else './lib/main' + require(main)(args...) global.shutdown = -> require('./lib/message-manager').send('shutdown') unless IS_FRAME_SCRIPT diff --git a/extension/lib/l10n.coffee b/extension/lib/l10n.coffee index 949a7a5..49a99fd 100644 --- a/extension/lib/l10n.coffee +++ b/extension/lib/l10n.coffee @@ -24,7 +24,7 @@ PROPERTIES_FILE = 'vimfx.properties' stringBundle = Services.strings.createBundle( # Randomize URI to work around bug 719376. - "chrome://vimfx/locale/#{PROPERTIES_FILE}?#{Math.random()}" + "#{ADDON_PATH}/locale/#{PROPERTIES_FILE}?#{Math.random()}" ) module.exports = (name, values...) -> diff --git a/extension/lib/main.coffee b/extension/lib/main.coffee index f05167e..ff73212 100644 --- a/extension/lib/main.coffee +++ b/extension/lib/main.coffee @@ -21,22 +21,28 @@ # This file pulls in all the different parts of VimFx, initializes them, and # stiches them together. -createAPI = require('./api') -button = require('./button') -defaults = require('./defaults') -UIEventManager = require('./events') -messageManager = require('./message-manager') -modes = require('./modes') -options = require('./options') -parsePref = require('./parse-prefs') -prefs = require('./prefs') -utils = require('./utils') -VimFx = require('./vimfx') -test = try require('../test/index') +createAPI = require('./api') +button = require('./button') +defaults = require('./defaults') +UIEventManager = require('./events') +{applyMigrations} = require('./legacy') +messageManager = require('./message-manager') +migrations = require('./migrations') +modes = require('./modes') +options = require('./options') +parsePref = require('./parse-prefs') +prefs = require('./prefs') +utils = require('./utils') +VimFx = require('./vimfx') +test = try require('../test/index') Cu.import('resource://gre/modules/AddonManager.jsm') module.exports = (data, reason) -> + # Set default prefs and apply migrations as early as possible. + prefs.default.init() + applyMigrations(migrations) + parsedOptions = {} for pref of defaults.all_options parsedOptions[pref] = parsePref(pref) @@ -129,7 +135,7 @@ module.exports = (data, reason) -> setWindowAttribute(window, 'mode', 'normal') setWindowAttribute(window, 'focus-type', null) - return [__SCRIPT_URI_SPEC__] + return true ) messageManager.load('bootstrap') diff --git a/extension/lib/message-manager.coffee b/extension/lib/message-manager.coffee index 047ff34..5bf4d40 100644 --- a/extension/lib/message-manager.coffee +++ b/extension/lib/message-manager.coffee @@ -22,7 +22,7 @@ # messages between the main process and frame scripts. There is one frame script # per tab, and only them can access web page content. -namespace = (name) -> "VimFx:#{name}" +namespace = (name) -> "#{ADDON_PATH}/#{name}" defaultMM = if IS_FRAME_SCRIPT @@ -33,10 +33,10 @@ defaultMM = load = (name, messageManager = defaultMM) -> # Randomize URI to work around bug 1051238. - url = "chrome://vimfx/content/#{name}.js?#{Math.random()}" - messageManager.loadFrameScript(url, true) + uri = "#{ADDON_PATH}/content/#{name}.js?#{Math.random()}" + messageManager.loadFrameScript(uri, true) module.onShutdown(-> - messageManager.removeDelayedFrameScript(url) + messageManager.removeDelayedFrameScript(uri) ) listen = (name, listener, messageManager = defaultMM) -> diff --git a/extension/lib/utils.coffee b/extension/lib/utils.coffee index bc94aec..0fb54a5 100644 --- a/extension/lib/utils.coffee +++ b/extension/lib/utils.coffee @@ -395,7 +395,7 @@ hasEventListeners = (element, type) -> return false loadCss = (name) -> - uri = Services.io.newURI("chrome://vimfx/skin/#{name}.css", null, null) + uri = Services.io.newURI("#{ADDON_PATH}/skin/#{name}.css", null, null) method = nsIStyleSheetService.AUTHOR_SHEET unless nsIStyleSheetService.sheetRegistered(uri, method) nsIStyleSheetService.loadAndRegisterSheet(uri, method) -- 2.39.3