Intercept/handle mime type/file

时光总嘲笑我的痴心妄想 提交于 2019-11-29 07:47:09

Based on @nmaiers post this is how you do it:

This is how you do it IF the mime type already exists. If it doesn't exist I don't know how to add it, probably some register function.

For some reason the type for my torrents is application/x-download I have no idea why. If you want info on how I figured that out than I'll tell you. So in the example below I use that as file type.

When we console.log(wrappedHandlerInfo) we see that it looks like this:

so now let's do that enumerate all application handlers (i got this from here: MXR :: gApplicationsPane, and if .type == 'application/x-download' let'sbreak` so we can than play with that object.

var handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].getService(Ci.nsIHandlerService);

var listOfWrappedHandlers = handlerService.enumerate();
var i = 0;
while (listOfWrappedHandlers.hasMoreElements()) {
  var wrappedHandlerInfo = listOfWrappedHandlers.getNext().QueryInterface(Ci.nsIHandlerInfo);
  console.log(i, 'handler for', wrappedHandlerInfo.type, wrappedHandlerInfo);
  if (wrappedHandlerInfo.type == 'application/x-download') {
    break;
  }
  i++;
}
console.log('Listed ', i, ' handlers');
console.log('wrappedHandlerInfo=', wrappedHandlerInfo); //should be the application/x-download one as we broke the loop once it found that

now we have to set its properties then save it.

// Change and save mime handler settings.
wrappedHandlerInfo.alwaysAskBeforeHandling = false;
wrappedHandlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
handlerService.store(wrappedHandlerInfo);

I'm not sure what to change those properties too though, maybe @nmaier can advise us on that.

We see here on MXR :: nsIHandlerService.idl #L69 that store does this:

69    * Save the preferred action, preferred handler, possible handlers, and
70    * always ask properties of the given handler info object to the datastore.
71    * Updates an existing record or creates a new one if necessary.
72    *
73    * Note: if preferred action is undefined or invalid, then we assume
74    * the default value nsIHandlerInfo::useHelperApp.
75    *
76    * @param aHandlerInfo  the handler info object
77    */
78   void store(in nsIHandlerInfo aHandlerInfo);

ANOTHER WAY

Ok i found an even better way, this way you don't need to loop to find the handler.

Do this:

var mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
var CONTENT_TYPE = ''; //'application/x-download'; can leave this blank
var TYPE_EXTENSION = 'torrent';

var handlerInfo = mimeService.getFromTypeAndExtension(CONTENT_TYPE, TYPE_EXTENSION);
console.info('handlerInfo:', handlerInfo); //http://i.imgur.com/dUKox24.png

    // Change and save mime handler settings.
    handlerInfo.alwaysAskBeforeHandling = false;
    handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
    handlerService.store(handlerInfo);

This handlerInfo object is slightly different in that it has a primaryExtension attribute which holds torrent.


Problem with both ways

The problem with both ways is that, if the mime type doesn't exist, you have to register it somehow, I don't know how. Probably use mime service and some register function.

Update August 3rd 2014

I think i found a solution for the problem mentioned in bullet above (problem with both ways).

MXR :: addPossibleApplicationHandler

235   addPossibleApplicationHandler: function(aNewHandler) {
236     var possibleApps = this.possibleApplicationHandlers.enumerate();
237     while (possibleApps.hasMoreElements()) {
238       if (possibleApps.getNext().equals(aNewHandler))
239         return;
240     }
241     this.possibleApplicationHandlers.appendElement(aNewHandler, false);
242   },
243 

This is code for addPossibleApplicationHandler, we probably just need to copy that and edit somehow.

Update August 3rd 2014

Ok this is how to add protocol handler (it only adds a nsIWebAppHandler but im sure to add a local meaning a nsIAppHandler it should be similar just no need for uri param:

https://gist.github.com/Noitidart/2faaac70c62bc13e7773#add-a-handler-to-a-protocol


Info on functions available in nsIMIMEService: MXR :: nsIMIMEService.idl

nmaier

There are multiple ways, that all boil down to nsIMimeService/nsIHandlerService and nsIMimeInfo and setting the appropriate nsIHandlerInfo. E.g. see PDF.js making itself the handler for PDF files (by effectively disabling all handler or plugins and implementing a stream converter), or my answer on how to register a web protocol handler (not mime related but protocol related, but the handler info stuff still applies).

Depending on how you'd like to handle things, you may use the nsIHandlerApp-ervied interfaces e.g. to pass the uri (protocols) or file (mime) directly to some local or web application, or implement a full blown stream converter like PDF.js.

In theory, it would be also possible to implement new kinds of nsIHandlerApp-derived interfaces, implementing in particular launchWithURI (protocols) or launchWithFile (mime content types and file extensions (downloads)). However, this is a bit tricky as nsIHandlerService only handles the built-in interfaces.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!