Use registerProtocolHandler without contentWindow

I am trying to install hotmail for my mailto handlers:

Image

This is done using this code from a webpage area:

navigator.registerProtocolHandler('mailto','http://mail.live.com/secure/start?action=compose&to=%s','Live Mail'); 

From XPCOM we will have to use this: MXR :: WebContentConverter.js # 369) .

So, from the search for the github code, I understand that you are importing it as follows:

 var nsiwchr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].getService(Ci.nsIWebContentHandlerRegistrar); 

So I would register it like this:

 nsiwchr.registerProtocolHandler('mailto','http://mail.live.com/secure/start?action=compose&to=%s','Live Mail', null); 

I use null because I don't have contentWindow , but apparently you cannot pass null for this. Because:

http://mxr.mozilla.org/mozilla-release/source/browser/components/feeds/src/WebContentConverter.js#372

 var uri = this._checkAndGetURI(aURIString, aContentWindow); 

And then he checks:

 aContentWindow.location.hostname != uri.host) 

So, I decided to fake it as follows:

 var fakeContentWindow = { document: { baseURIObject: { asciiHost:"mail.live.com", asciiSpec:"http://mail.live.com/secure", hasRef:true, host:"mail.live.com", hostPort:"mail.live.com", originCharset:"UTF-8", password:"", path:"/secure", port:-1, prePath:"http://mail.live.com", ref:"", //369 scheme:"http", spec:"http://mail.live.com/secure", specIgnoringRef:"http://mail.live.com", userPass:"", username:"" } }, location: { hash:"", //#369 host:"mail.live.com", hostname:"mail.live.com", href:"http://mail.live.com/secure", origin:"http://mxr.mozilla.org", pathname:"/secure", port:"", protocol:"http:", search:"" } }; nsiwchr.registerProtocolHandler('mailto','http://mail.live.com/secure/start?action=compose&to=%s','Live Mail', fakeContentWindow); 

but it causes some completely strange error:

/ * Exception: [XPCWrappedNative_NoHelper object] * / Browser console:

 "[object XPCWrappedNative_NoHelper]" scratchpad.js:999 SP_writeAsErrorComment/<() scratchpad.js:999 Handler.prototype.process() Promise-backend.js:863 this.PromiseWalker.walkerLoop() Promise-backend.js:742 

It does not make sense. I want to successfully trick this without using real contentWindow .

0
javascript firefox-addon xpcom
source share
1 answer

You simply cannot use this high-level API without a window (and you probably do not want to use it, since it will not actually add a handler, but will display a user interface notification that will first ask the user to add it, which is not only not that you want, but it will not work, because there is no interface to display this notification in the first place).

Instead, you want to create your own version based on an implementation that omits all of these security checks, user interface notifications, etc.

Based on registerNotificiation it will look something like this.

 var protocolScheme = "mailtoorsomething"; var uri = Services.io.newURI("someuri?with_%s_replacement", null, null); var name = "Some Name"; var desc = "Some description"; var protocolHandler = Services.io.getProtocolHandler(protocolScheme); if (!(protocolHandler instanceof Ci.nsIExternalProtocolHandler)) { throw new Error("Cannot register handler for built-in protocol"); } var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"]. getService(Ci.nsIExternalProtocolService); var handlerInfo = eps.getProtocolHandlerInfo(protocolScheme); var handlers = handlerInfo.possibleApplicationHandlers; for (let i = 0; i < handlers.length; i++) { let h = handlers.queryElementAt(i, Ci.nsIWebHandlerApp); if (h.uriTemplate == uri.spec) { throw new Error("Already registered"); } } var handler = Cc["@mozilla.org/uriloader/web-handler-app;1"]. createInstance(Ci.nsIWebHandlerApp); handler.name = name; handler.detailedDescription = desc; handler.uriTemplate = uri.spec; handlerInfo.possibleApplicationHandlers.appendElement(handler, false); handlerInfo.alwaysAskBeforeHandling = false; handlerInfo.preferredApplicationHandler = handler; handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp; var hs = Cc["@mozilla.org/uriloader/handler-service;1"]. getService(Ci.nsIHandlerService); hs.store(handlerInfo); 
+2
source share

All Articles