Skip to content

Instantly share code, notes, and snippets.

@Gozala
Created December 19, 2014 10:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gozala/8560f04907f53fe1c5f3 to your computer and use it in GitHub Desktop.
Save Gozala/8560f04907f53fe1c5f3 to your computer and use it in GitHub Desktop.
App protocol handler to map directory
const { utils: Cu, classes: Cc, interfaces: Ci, manager: Cm } = Components;
const io = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
Cm.QueryInterface(Ci.nsIComponentRegistrar)
if (typeof(Symbol) === "undefined") {
var Symbol = String
}
const SubstitutionProtocol = function(scheme) {
this[SubstitutionProtocol.hosts] = Object.create(null)
this.scheme = scheme
this.contract = `@mozilla.org/network/protocol;1?name=${scheme}`
}
SubstitutionProtocol.hosts = Symbol("substitution/protocol/hosts")
SubstitutionProtocol.prototype = {
constructor: SubstitutionProtocol,
description: "Custom substitution protocol implemantion",
classID: Components.ID("{e368b52a-3af0-4585-811c-80a8b020dd24}"),
QueryInterface(iid) {
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsIProtocolHandler) ||
iid.equals(Ci.nsIResProtocolHandler) ||
iid.equals(Ci.nsIFactory))
{
return this
}
throw Cr.NS_ERROR_NO_INTERFACE
},
// nsIResProtocolHandler
getSubstitution(host) {
return this[SubstitutionProtocol.hosts][host]
},
hasSubstitution(host) {
return !!this.getSubstitution(host)
},
setSubstitution(host, uri) {
this[SubstitutionProtocol.hosts][host] = uri
},
resolveURI({host, path}) {
let uri = this.getSubstitution(host)
if (!uri) {
throw Cr.NS_ERROR_NOT_AVAILABLE
}
return uri.resolve(path.substr(1))
},
// nsIProtocolHandler
defaultPort: -1,
protocolFlags: Ci.nsIProtocolHandler.URI_NOAUTH |
Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE |
Ci.nsIProtocolHandler.URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM,
scheme: null,
newURI(spec, originCharset, baseURI) {
let uri = Cc["@mozilla.org/network/standard-url;1"]
.createInstance(Ci.nsIStandardURL)
uri.init(Ci.nsIStandardURL.URLTYPE_STANDARD,
-1, spec, originCharset, baseURI)
return uri.QueryInterface(Ci.nsIURI)
},
newChannel(uri) {
let channel = io.newChannel(this.resolveURI(uri), null, null);
channel.QueryInterface(Ci.nsIChannel).originalURI = uri
return channel
},
// nsIFactory
createInstance(outer, iid) {
if (outer) {
throw Cr.NS_ERROR_NO_AGGREGATION
}
return this
},
lockFactory: function(aLock) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED
},
// component
register() {
Cm.registerFactory(this.classID,
this.description,
this.contract,
this)
},
unregister() {
Cm.unregisterFactory(this.classID,
this)
}
}
// In e10s registered protocol handlers does not seem to content processes there for
// urls aren't loaded as one would expect. To overcome that limitation import this
// module via message manager in every frameManager.
//
// Todo: figure out a better way to propagate registered protocol handlers.
Cc["@mozilla.org/globalmessagemanager;1"].
getService(Ci.nsIMessageListenerManager).
loadFrameScript(`data:,Components.utils.import("${__URI__}", {})`, true);
var EXPORTED_SYMBOLS = ["SubstitutionProtocol"]
let app = new SubstitutionProtocol("app")
app.register()
app.setSubstitution("firefox.html",
io.newURI("file:///Users/gozala/Projects/firefox.html/", null, null))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment