我想使用他们的WebExtensions API创建一个Firefox扩展。扩展名应查找与名称中的特定模式匹配的任何尝试下载的文件。如果扩展程序发现尝试下载的名称与该特定模式匹配,则会将下载内容放入另一个硬编码目录中。
看起来很简单。但是,在查看Firefox的WebExtensions API中的可用功能之后,我找不到任何可以轻松执行此操作的内容。以下是我看过的主要链接:
WebExtensions {➞{3}} {➞{3}}
JavaScript APIs {➞{3}} {➞{3}} {➞{3}}
似乎都不适合我正在寻找的东西。任何人都知道我怎么能做到这一点?
答案 0 :(得分:1)
使用WebExtensions执行此操作的“正确”方式看起来并不是(但是?)Firefox支持。谷歌浏览器有'onDeterminingFilename'事件,允许您向用户“建议”文件名。如果在这种情况下需要,允许用户覆盖您的扩展名的“建议”可能会更好。
执行此操作的强力方法是向downloads.onCreated
添加侦听器。该听众传递的是downloads.DownloadItem
,它会为您提供url
和filename
。然后,听众可以downloads.cancel()
下载并使用您想要的filename
发起一个新的downloads.download()
。
这在实际中如何工作取决于downloads.onCreated
事件确实在与用户的交互方面实际触发的时间。是否在与用户“另存为”对话框之前或之后触发?您需要对此进行测试,以了解哪种方法最适合您希望用户拥有的感觉。 downloads.State
类型可以包含的有限值集指示仅在“另存为”对话框完成后才触发事件,但这可能不是准确的指示。如果它在“另存为”对话框之前触发,我们可以通过将saveAs: true
属性添加到我们传递给downloads.download()
的对象1}}来显示该加载项建议的文件名。 p>
像(未经测试)的东西:
var ignoreDownloadUrls=[];
var ignoreDownloadIds=[];
chrome.downloads.onCreated.addlistener(forceDownloadFilenameIfUrlMatch);
function forceDownloadFilenameIfUrlMatch(downloadItem){
//Check the URL for duplication (may not be needed, need to test).
let foundUrlIndex = ignoreDownloadUrls.findIndex(function(element,index){
if(element === downloadItem.url){
return true;
}//else
return false;
});
if(foundUrlIndex>-1) {
//This is the callback resulting from our creating the download
// with the new filename. We only want to ignore the URL once,
// so, remove the URL from our ignore list.
// This makes the assumption that the events we get are reasonably
// orderly (only one created event per URL which we want to
// change, etc.). This may need to be more complex in real use.
ignoreDownloadUrls.splice(foundUrlIndex,1);
//We do not want to change this download, as we created it.
return;
}
//Test the ID for one we created:
let foundIdIndex = ignoreDownloadIds.findIndex(function(element,index){
if(element === downloadItem.id){
return true;
}//else
return false;
});
if(foundIdIndex>-1) {
//This is an event resulting from our creating the download
// with the new filename.
//We do not want to change this download, as we created it.
return;
}
if(downloadItem.url.idexOf(myMatchString) >-1){
chrome.downloads.cancel(downloadItem.id);
//Remember the URL so we don't change it twice.
// Remembering the URL may not be the best way to do this. Need
// to test as to the order which events and the download callback
// occur.
ignoreDownloadUrls.push(download.url);
chrome.downloads.download({
url: downloadItem.url,
filename: myNewFilename
}, function(id){
//We could use the callback of the downloads.download() to remember
// the downloadId of the download we created and only ignore that
// one. That would rely on the callback being called prior to the
// new onCreated event. Might work that way in practice. It
// would certainly be better to remember the specifically created
// downloadId rather than just ignore (once) a specific URL.
// Testing should indicate if we need to use the download ID,
// or ignore the URL (once).
//Remember the downloadId so we don't change it twice.
ignoreDownloadIds.push(id);
});
}
}