如果用户保存了网页,我希望在插件中收到通知。 有没有办法捕捉这个事件?我只看到了这个,看起来有点奇怪:
Listen to page save event in a Chrome extension and Firefox addon
我更期待一个API,订阅。
答案 0 :(得分:2)
var DOMWindows = Services.wm.getEnumerator(null);
while (DOMWindows.hasMoreElements()) {
var aDOMWindow = DOMWindows.getNext();
var aCommand = aDOMWindow.document.getElementById('Browser:SavePage');
if (aCommand) {
aCommand.addEventListener('command', function(e) {
console.log('doing command', 'id:', e.target.id, 'e:', e);
}, false);
}
}
e
对象上的变量查看器:
确保跟踪未来打开的窗口。
或者这里是对Browser:SavePage
调用的命令的调查,我们可以在这里找到要跟踪的内容:
似乎它调用savePage
函数:
function saveDocument(aDocument, aSkipPrompt)
{
if (!aDocument)
throw "Must have a document when calling saveDocument";
// We want to use cached data because the document is currently visible.
var ifreq =
aDocument.defaultView
.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
var contentDisposition = null;
try {
contentDisposition =
ifreq.getInterface(Components.interfaces.nsIDOMWindowUtils)
.getDocumentMetadata("content-disposition");
} catch (ex) {
// Failure to get a content-disposition is ok
}
var cacheKey = null;
try {
cacheKey =
ifreq.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIWebPageDescriptor);
} catch (ex) {
// We might not find it in the cache. Oh, well.
}
internalSave(aDocument.location.href, aDocument, null, contentDisposition,
aDocument.contentType, false, null, null,
aDocument.referrer ? makeURI(aDocument.referrer) : null,
aDocument, aSkipPrompt, cacheKey);
}
它看起来像是internalSave
:
function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
aContentType, aShouldBypassCache, aFilePickerTitleKey,
aChosenData, aReferrer, aInitiatingDocument, aSkipPrompt,
aCacheKey)
{
if (aSkipPrompt == undefined)
aSkipPrompt = false;
if (aCacheKey == undefined)
aCacheKey = null;
// Note: aDocument == null when this code is used by save-link-as...
var saveMode = GetSaveModeForContentType(aContentType, aDocument);
var file, sourceURI, saveAsType;
// Find the URI object for aURL and the FileName/Extension to use when saving.
// FileName/Extension will be ignored if aChosenData supplied.
if (aChosenData) {
file = aChosenData.file;
sourceURI = aChosenData.uri;
saveAsType = kSaveAsType_Complete;
continueSave();
} else {
var charset = null;
if (aDocument)
charset = aDocument.characterSet;
else if (aReferrer)
charset = aReferrer.originCharset;
var fileInfo = new FileInfo(aDefaultFileName);
initFileInfo(fileInfo, aURL, charset, aDocument,
aContentType, aContentDisposition);
sourceURI = fileInfo.uri;
var fpParams = {
fpTitleKey: aFilePickerTitleKey,
fileInfo: fileInfo,
contentType: aContentType,
saveMode: saveMode,
saveAsType: kSaveAsType_Complete,
file: file
};
// Find a URI to use for determining last-downloaded-to directory
let relatedURI = aReferrer || sourceURI;
promiseTargetFile(fpParams, aSkipPrompt, relatedURI).then(aDialogAccepted => {
if (!aDialogAccepted)
return;
saveAsType = fpParams.saveAsType;
file = fpParams.file;
continueSave();
}).then(null, Components.utils.reportError);
}
function continueSave() {
// XXX We depend on the following holding true in appendFiltersForContentType():
// If we should save as a complete page, the saveAsType is kSaveAsType_Complete.
// If we should save as text, the saveAsType is kSaveAsType_Text.
var useSaveDocument = aDocument &&
(((saveMode & SAVEMODE_COMPLETE_DOM) && (saveAsType == kSaveAsType_Complete)) ||
((saveMode & SAVEMODE_COMPLETE_TEXT) && (saveAsType == kSaveAsType_Text)));
// If we're saving a document, and are saving either in complete mode or
// as converted text, pass the document to the web browser persist component.
// If we're just saving the HTML (second option in the list), send only the URI.
var persistArgs = {
sourceURI : sourceURI,
sourceReferrer : aReferrer,
sourceDocument : useSaveDocument ? aDocument : null,
targetContentType : (saveAsType == kSaveAsType_Text) ? "text/plain" : null,
targetFile : file,
sourceCacheKey : aCacheKey,
sourcePostData : aDocument ? getPostData(aDocument) : null,
bypassCache : aShouldBypassCache,
initiatingWindow : aInitiatingDocument.defaultView
};
// Start the actual save process
internalPersist(persistArgs);
}
}
调用internalPersist
:
function internalPersist(persistArgs)
{
var persist = makeWebBrowserPersist();
// Calculate persist flags.
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES;
if (persistArgs.bypassCache)
persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
else
persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
// Leave it to WebBrowserPersist to discover the encoding type (or lack thereof):
persist.persistFlags |= nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
// Find the URI associated with the target file
var targetFileURL = makeFileURI(persistArgs.targetFile);
var isPrivate = PrivateBrowsingUtils.isWindowPrivate(persistArgs.initiatingWindow);
// Create download and initiate it (below)
var tr = Components.classes["@mozilla.org/transfer;1"].createInstance(Components.interfaces.nsITransfer);
tr.init(persistArgs.sourceURI,
targetFileURL, "", null, null, null, persist, isPrivate);
persist.progressListener = new DownloadListener(window, tr);
if (persistArgs.sourceDocument) {
// Saving a Document, not a URI:
var filesFolder = null;
if (persistArgs.targetContentType != "text/plain") {
// Create the local directory into which to save associated files.
filesFolder = persistArgs.targetFile.clone();
var nameWithoutExtension = getFileBaseName(filesFolder.leafName);
var filesFolderLeafName =
ContentAreaUtils.stringBundle
.formatStringFromName("filesFolder", [nameWithoutExtension], 1);
filesFolder.leafName = filesFolderLeafName;
}
var encodingFlags = 0;
if (persistArgs.targetContentType == "text/plain") {
encodingFlags |= nsIWBP.ENCODE_FLAGS_FORMATTED;
encodingFlags |= nsIWBP.ENCODE_FLAGS_ABSOLUTE_LINKS;
encodingFlags |= nsIWBP.ENCODE_FLAGS_NOFRAMES_CONTENT;
}
else {
encodingFlags |= nsIWBP.ENCODE_FLAGS_ENCODE_BASIC_ENTITIES;
}
const kWrapColumn = 80;
persist.saveDocument(persistArgs.sourceDocument, targetFileURL, filesFolder,
persistArgs.targetContentType, encodingFlags, kWrapColumn);
} else {
let privacyContext = persistArgs.initiatingWindow
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsILoadContext);
persist.saveURI(persistArgs.sourceURI,
persistArgs.sourceCacheKey, persistArgs.sourceReferrer, persistArgs.sourcePostData, null,
targetFileURL, privacyContext);
}
}
所以你可以从那里挑选一些东西,但我不会看到任何简单的东西,但是必须要有东西。