gpt4 book ai didi

javascript - 列出协议(protocol)和内容类型处理程序

转载 作者:行者123 更新时间:2023-11-30 12:29:40 27 4
gpt4 key购买 nike

是否有XPCOM接口用于列出所有协议处理程序和内容类型处理程序?

我看到该信息在mimeTypes.rdf中可用,尽管我看到了用于获取有关特定已知处理程序的信息的接口,但找不到任何列出所有接口的XPCOM接口。

最佳答案

嘿布雷特,这是我在处理MailtoWebmail时写的,请分享您学到的知识,怪癖等:

GitHubGIST :: Noitidart / _ff-addon-tutorial-CheckGetSetRemoveAddHandlerOfProtocol.md

获取handlerInfo对象

nsIHandlerService方法

返回的handlerInfo对象与使用上述nsiExternalProtocolService方法完全相同。

如果转到选项面板并将其更改为always,则在日志alwaysAskBeforeHandling中的handlerInfo属性将正确反映。

var handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].getService(Ci.nsIHandlerService);
var listOfWrappedHandlers = handlerService.enumerate();
var i = 0;
while (listOfWrappedHandlers.hasMoreElements()) {
var handlerInfo = listOfWrappedHandlers.getNext().QueryInterface(Ci.nsIHandlerInfo);
//console.log(i, 'handler for', wrappedHandlerInfo.type, wrappedHandlerInfo);
if (handlerInfo.type == 'mailto') {
break;
}
i++;
}
console.log('handlerServicehandlerInfo=', handlerInfo); //is the mailto one as we broke the loop once it found that


possibleLocalHandlers中没有 handlerInfo

nsiExternalProtocolService方法

返回的 handlerInfo对象与使用上述 nsIHandlerService方法完全相同。

如果转到选项面板并将其更改为always,则在日志 alwaysAskBeforeHandling中的 handlerInfo属性将正确反映。

var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
var handlerInfo = eps.getProtocolHandlerInfo('mailto');
console.log('epsHandlerInfo', handlerInfo)


possibleLocalHandlers中没有 handlerInfo

nsIMIMEService方法

注意:有一些怪异之处,例如不能准确地体现 preferedHandleralwaysAskBeforeHandling(到目前为止,我只是注意到这两个,我没有探索其他特性,但是它们可能同样被提升了

使用 nsIHandlerServicensiExternalProtocolService的前两种方法,如果转到选项面板并将其更改为always,则在日志中 alwaysAskBeforeHandlinghandlerInfo属性将正确反映。但是,如果使用此方法 handlerInfo来获取 nsIMIMEService,则它不能准确反映 alwaysAskBeforeHandling的下拉设置,这是如此奇怪:

它还具有 possibleApplicationHandlers,其长度为 0。奇。它也有 possibleLocalHandlers,在我的情况下,其长度为 53

var mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
var CONTENT_TYPE = 'mailto';
var TYPE_EXTENSION = '';

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


mimeServiceHandlerInfo具有与EPS和HandlerService的前两种方法返回的 handlerInfo不同的对象键。

检查与此相关的处理程序

从上述三种方法中的任何一种使用 handlerInfo(我还没有测试 nsiMIMServicehandlerInfo,但是我猜它应该可以工作)

queryElementAt方法

这种方式不会列出“ Microsoft Outlook”,它只会列出gmail,ymail和我添加的内容,很奇怪

 var handlers = handlerInfo.possibleApplicationHandlers;
console.log('handlers', handlers)
for (var i = 0; i < handlers.length; ++i) {
var handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp); //instead of Ci.nsIHandlerApp
console.log('poss handler', i, handler, handler.uriTemplate);

}


enumerate方法

我也不认为这种方式会列出“ Microsoft Outlook”,但我不确定,因为它仅记录小的 handler对象。

这种方式只为第一个非系统默认处理程序返回/记录小对象( handler)(我想就是这样,但肯定只返回一个)。它为其返回名称等,我通过添加 .QueryInterface(Ci.nsIHandlerApp)来解决此问题

 var handlers = handlerInfo.possibleApplicationHandlers.enumerate();
while (handlers.hasMoreElements()) {
var handler = handlers.getNext().QueryInterface(Ci.nsIWebHandlerApp); //instead of Ci.nsIHandlerApp
console.log('handler', handler);
}


关于 enumeratequeryElementAt的说明


是QI'ing Ci.nsIHandlerAppuriTemplate对象中没有 handler,所以我将其更改为 Ci.nsIWebHandlerApp,这在对象 uriTemplate中重新调整。


可以用 handlerpossibleApplicationHandlers中的QI Ci.nsIHandlerApp但不能用 handlerpossibleLocalHandlers中的QI Ci.nsIWebHandlerApp它将引发以下异常:

异常:组件返回失败代码:0x80004002(NS_NOINTERFACE)[nsISupports.QueryInterface]



向协议添加处理程序

registerProtocolHandler显示添加处理程序时要进行的所有检查,并显示如何添加处理程序。 MXR :: mozilla-release/ mozilla/ browser/ components/ feeds/ src/ WebContentConverter.js #L368 - registerProtocolHandler

此代码段显示了如何添加 nsIWebAppHandler。我不确定如何添加 nsILocalAppHandler(我不确定它是否甚至被称为 nsILocalAppHandler,也许只是(实际上可能是) nsIAppHandler)。在将其添加到此处之前,不会进行任何验证检查。在添加之前,您应该执行以下检查:


检查我们要添加的处理程序是否已经存在,可能是处理程序 MXR :: mozilla-release/ mozilla/ browser/ components/ feeds/ src/ WebContentConverter.js #349 - _protocolHandlerRegistered

有趣的是,这里只检查 possibleApplicationHandlers而不检查 possibleLocalHandlers,我不确定为什么,但是可能是因为我们正在处理 nsIWebAppHandler

检查以确保要添加处理程序的协议尚未在内部处理(我们不想让它们接管,例如“ chrome”)。 MXR :: mozilla-release/ mozilla/ browser/ components/ feeds/ src/ WebContentConverter.js #390
检查我们要添加处理程序的协议是否在黑名单中。如果它在黑名单中,则表示它不希望添加其他处理程序。我不确定这有多重要,但是 registerProtocolHandler可以做到。 MXR :: mozilla-release/ mozilla/ browser/ components/ feeds/ src/ WebContentConverter.js #402


因此,最后是有关如何在不执行上述三个检查中的任何一个的情况下添加处理程序的代码。

var protocol = 'mailto';
var name = 'Hotmail Mailto Handler';
var newURIArgs = {
aURL: 'http://mail.live.com/secure/start?action=compose&to=%s',
aOriginCharset: null,
aBaseURI: null
};
var myURI = Services.io.newURI(newURIArgs.aURL, newURIArgs.aOriginCharset, newURIArgs.aBaseURI);
var myURISpec = myURI.spec;


var handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].createInstance(Ci.nsIWebHandlerApp);
handler.name = name;
handler.uriTemplate = myURISpec;

var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
var handlerInfo = eps.getProtocolHandlerInfo(protocol);
handlerInfo.possibleApplicationHandlers.appendElement(handler, false);

if (handlerInfo.possibleApplicationHandlers.length > 1) {
// May want to always ask user before handling because it now has multiple possibleApplicationsHandlers BUT dont have to
//handlerInfo.alwaysAskBeforeHandling = true;
}

var hs = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
hs.store(handlerInfo);


如何获取协议的当前设置处理程序

首先使用获取 handlerInfo对象- handlerInfo-方法或获取 nsIHandlerService对象- handlerInfo方法来获取协议的 nsiExternalProtocolService对象。


然后首先检查 handlerInfo.alwaysAskBeforeHandling是否为 true。如果是这种情况,则活动处理程序为“始终询问”。如果是这种情况,则 handlerInfo.preferredApplicationHandlerhandlerInfo.preferredAction是陈旧的。陈旧是指它们不是真实的,它们被设置为之前设置的值。
handlerInfo.alwaysAskBeforeHandlingfalse,然后检查 handlerInfo.preferredAction

如果 handlerInfo.preferredAction == Ci.nsIHandlerInfo.useSystemDefaulthandler.preferredApplicaitonHandler过时,那就是它上次设置的时间。因此,活动处理程序是 userSystemDefault的任何内容。 (在撰写本文时,2014年8月3日-我不确定如何确定协议的系统默认处理程序)
如果 handlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp大于默认处理程序,则保存在 handlerInfo.preferredApplicationHandler中。在这种情况下, handler.preferredApplicaitonHandler不应为 null。在所有其他情况下, handler.preferredApplicaitonHandler可能为 null
如果 handlerInfo.preferredAction == Ci.nsIHandlerInfo.saveToDisk比默认处理程序要下载
如果 handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally大于默认处理程序,我在撰写本文时仍不知道(2014年8月3日)



演示/示例-将mailto处理程序设置为“ Yahoo! Mail”

//start - demo make handler for mailto be y! mail
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
var handlerInfo = eps.getProtocolHandlerInfo('mailto');
console.log('epsHandlerInfo', handlerInfo)

var handlers = handlerInfo.possibleApplicationHandlers.enumerate();
var foundYahooMailHandler = false;
while (handlers.hasMoreElements()) {
var handler = handlers.getNext();
if (handler.QueryInterface(Ci.nsIWebHandlerApp).uriTemplate == 'https://compose.mail.yahoo.com/?To=%s') { //this is how i decided to indentify if the handler is of yahoo mail
foundYahooMailHandler = true;
break;
}
}

if (foundYahooMailHandler) {
//it was found. and in the while loop when i found it, i "break"ed out of the loop which left handlerInfo set at the yahoo mail handler
//set this to the prefered handler as this handler is the y! mail handler
handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp; //Ci.nsIHandlerInfo has keys: alwaysAsk:1, handleInternally:3, saveToDisk:0, useHelperApp:2, useSystemDefault:4
handlerInfo.preferredApplicationHandler = handler;
handlerInfo.alwaysAskBeforeHandling = false;
var hs = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
hs.store(handlerInfo);
} else {
alert('could not find yahoo mail handler. meaning i couldnt find a handler with uriTemplate of ...compose.mail.yahoo....')
}
//end - demo make handler for mailto be y! mail


演示/如何删除处理程序的示例

var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
var handlerInfo = eps.getProtocolHandlerInfo('mailto');
console.log('epsHandlerInfo', handlerInfo)

console.log('handlerInfo.preferredApplicationHandler', handlerInfo.preferredApplicationHandler);
console.log('handlerInfo.possibleApplicationHandlers', handlerInfo.possibleApplicationHandlers);

var handlers = handlerInfo.possibleApplicationHandlers;
console.log('handlers', handlers)
for (var i = 0; i < handlers.length; ++i) {
var handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
console.log('handler', i, handler, handler.uriTemplate);

if (Services.wm.getMostRecentWindow(null).confirm('delete handler at position ' + i + '? its uriTemplate = "' + handler.uriTemplate + '" and name = "' + handler.name + '"')) {
if (handler.equals(handlerInfo.preferredApplicationHandler)) {
Services.wm.getMostRecentWindow(null).alert('the preferredApplicationHandler was the one we are removing now, so null the preferredAppHand and set to always ask');
//if the last preferredApplicationHandler was this then nullify it, just me trying to keep things not stale
handlerInfo.preferredApplicationHandler = null;
if (handlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp) {
//it looks like the preferredAction was to use this helper app, so now that its no longer there we will have to ask what the user wants to do next time the uesrs clicks a mailto: link
handlerInfo.alwaysAskBeforeHandling = true;
handlerInfo.preferredAction = Ci.nsIHandlerInfo.alwaysAsk; //this doesnt really do anything but its just nice to be not stale. it doesnt do anything because firefox checks handlerInfo.alwaysAskBeforeHandling to decide if it should ask. so me doing this is just formality to be looking nice
}
}
handlers.removeElementAt(i);
i--;
}
var hs = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
hs.store(handlerInfo);
}

关于javascript - 列出协议(protocol)和内容类型处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28133920/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com