Skip to content

Instantly share code, notes, and snippets.

@Gozala
Created August 27, 2012 23:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Gozala/3493210 to your computer and use it in GitHub Desktop.
Save Gozala/3493210 to your computer and use it in GitHub Desktop.
API for chrome URI registration
/*jshint asi:true globalstrict:true*/
'use strict';
// Workaround for Bug 785891
// and sugar around: https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIComponentManager#addBootstrappedManifestLocation%28
let { Cc, Ci, Cm } = require('chrome')
let ioService = Cc['@mozilla.org/network/io-service;1'].
getService(Ci.nsIIOService)
let { pathFor } = require('api-utils/system')
function makeURI(uri) {
try { return ioService.newURI(uri, null, null) }
catch (error) { return null }
}
function nsIURI(location) {
return !location ? null :
location instanceof Ci.nsIURI ? location :
makeURI(location) || makeURI('file://' + location)
}
function createMappingEntry(root, section) {
// Create path to directory in the profile associated with mapping being
// registered:
// foo, file://path/to/foo, content -> `chrome.manifest.content.foo`
let path = pathFor('ProfLD') + '/chrome.manifest.' + section + '.' + root
let directory = Cc['@mozilla.org/file/local;1'].
createInstance(Ci.nsILocalFile)
directory.initWithPath(path)
return directory
}
function set(root, uri, section) {
/**
Registers mapping for the chrome URI. If `uri` is `null` and mapping was
registered through this API, registered mapping will be unregistered.
Example:
chrome.set('foo', 'file:///path/to/foo/', 'content')
Supported sections values are:
- `content`
- `locale`
- `skin`
If `section` is omitted, then `content` is used.
**/
uri = nsIURI(uri).spec
section = section || 'content'
let directory = createMappingEntry(root, section)
if (uri) {
let mapping = section + ' ' + root + ' ' + uri + '\n'
// Remove directory in case it already there
if (directory.exists()) directory.remove(true)
// Create directory and `chrome.manifest` file in it.
directory.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0777', 8))
let file = directory.clone()
file.append('chrome.manifest')
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt('0666', 8))
let stream = Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream)
stream.init(file, 0x02, parseInt('0666', 8, 0), 0)
console.log(mapping)
stream.write(mapping, mapping.length)
stream.flush()
stream.close()
Cm.addBootstrappedManifestLocation(directory)
}
else {
Cm.removeBootstrappedManifestLocation(directory)
directory.remove(true)
}
}
exports.set = set
@olivier-m
Copy link

Hi, there's a bug with this code on Windows. I fixed it with the following patch (I also added unload support):

diff --git a/chrome.js b/chrome.js
index 0f7ec7a..0c15617 100644
--- a/chrome.js
+++ b/chrome.js
@@ -9,6 +9,9 @@ let { Cc, Ci, Cm } = require('chrome')
 let ioService = Cc['@mozilla.org/network/io-service;1'].
                 getService(Ci.nsIIOService)
 let { pathFor } = require('api-utils/system')
+let { join } = require('api-utils/file')
+const unload = require('sdk/system/unload')
+

 function makeURI(uri) {
   try { return ioService.newURI(uri, null, null) }
@@ -25,7 +28,7 @@ function createMappingEntry(root, section) {
   // Create path to directory in the profile associated with mapping being
   // registered:
   // foo, file://path/to/foo, content -> `chrome.manifest.content.foo`
-  let path = pathFor('ProfLD') + '/chrome.manifest.' + section + '.' + root
+  let path = join(pathFor('ProfLD'), 'chrome.manifest.' + section + '.' + root)
   let directory = Cc['@mozilla.org/file/local;1'].
                   createInstance(Ci.nsILocalFile)
   directory.initWithPath(path)
@@ -68,7 +71,12 @@ function set(root, uri, section) {
     stream.write(mapping, mapping.length)
     stream.flush()
     stream.close()
-    Cm.addBootstrappedManifestLocation(directory)
+    Cm.addBootstrappedManifestLocation(directory)
+
+    unload.when(function() {
+      Cm.removeBootstrappedManifestLocation(directory)
+      directory.remove(true)
+    });
   }
   else {
     Cm.removeBootstrappedManifestLocation(directory)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment