Last active
December 22, 2015 09:29
-
-
Save Infocatcher/6452231 to your computer and use it in GitHub Desktop.
Firefox: don't remove finished downloads (browser.download.useToolkitUI = false), code for Custom Buttons extension https://addons.mozilla.org/addon/custom-buttons/ ("initialization" section)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://gist.github.com/Infocatcher/6452231 | |
// More: https://github.com/Infocatcher/Download_Panel_Tweaker | |
// (c) Infocatcher 2013 | |
var retentionDays = 21; | |
function dontRemoveFinishedDownloads(patch) { | |
// See https://github.com/Infocatcher/Download_Panel_Tweaker/issues/5 for details | |
try { // Firefox 26+ | |
// http://mxr.mozilla.org/mozilla-central/source/toolkit/components/jsdownloads/src/DownloadIntegration.jsm | |
var {DownloadIntegration} = Components.utils.import("resource://gre/modules/DownloadIntegration.jsm", {}); | |
} | |
catch(e) { | |
} | |
if(DownloadIntegration && "shouldPersistDownload" in DownloadIntegration) { | |
const bakKey = "_customButtonsDontRemoveFinishedDownloads_shouldPersistDownload"; | |
if(!patch ^ bakKey in DownloadIntegration) | |
return; | |
//LOG("dontRemoveFinishedDownloads(" + patch + ")"); | |
var store = "_store" in DownloadIntegration && DownloadIntegration._store; | |
if(patch) { | |
DownloadIntegration[bakKey] = DownloadIntegration.shouldPersistDownload; | |
var wrapped = DownloadIntegration.shouldPersistDownload = function downloadPanelTweakerWrapper(download) { | |
if(download.hasPartialData || !download.stopped) | |
return true; | |
//var retentionDays = prefs.get("downloadsMaxRetentionDays"); | |
return retentionDays > 0 | |
&& download.startTime > (Date.now() - retentionDays*24*60*60*1000); | |
}; | |
if(store) { | |
//LOG("dontRemoveFinishedDownloads(" + patch + "): override DownloadStore.onsaveitem"); | |
store[bakKey] = store.onsaveitem; | |
store.onsaveitem = wrapped; | |
} | |
} | |
else { | |
DownloadIntegration.shouldPersistDownload = DownloadIntegration[bakKey]; | |
delete DownloadIntegration[bakKey]; | |
if(store && bakKey in store) { | |
//LOG("dontRemoveFinishedDownloads(" + patch + "): restore DownloadStore.onsaveitem"); | |
store.onsaveitem = store[bakKey]; | |
delete store[bakKey]; | |
} | |
} | |
} | |
else { | |
dontRemoveFinishedDownloadsLegacy(patch); | |
} | |
} | |
function dontRemoveFinishedDownloadsLegacy(patch) { | |
const bakKey = "_customButtonsDontRemoveFinishedDownloads_downloads"; | |
const newKey = "_customButtonsDontRemoveFinishedDownloads_downloadsWrapper"; | |
if(!patch ^ bakKey in Services) | |
return; | |
//var logPrefix = "dontRemoveFinishedDownloadsLegacy(" + patch + "): "; | |
if(patch) { | |
var cleanUp = function downloadPanelTweakerWrapper() { | |
var stack = new Error().stack; | |
//LOG("Services.downloads.cleanUp()\n" + stack); | |
if( | |
stack.indexOf("@resource://app/components/DownloadsStartup.js:") != -1 | |
|| stack.indexOf("@resource://gre/components/DownloadsStartup.js:") != -1 // Firefox 20 and older | |
) { | |
//LOG("Prevent Services.downloads.cleanUp()"); | |
return undefined; | |
} | |
return downloads.cleanUp.apply(downloads, arguments); | |
}; | |
if(newKey in Services) { | |
var downloads = Services[newKey].__proto__; | |
Services[bakKey] = null; | |
setProperty(Services[newKey], "cleanUp", cleanUp); | |
//LOG(logPrefix + "Will use old wrapper for Services.downloads"); | |
} | |
else { | |
var downloads = Services[bakKey] = Services.downloads; | |
var downloadsWrapper = Services[newKey] = { | |
__proto__: downloads, | |
cleanUp: cleanUp | |
}; | |
setProperty(Services, "downloads", downloadsWrapper); | |
//LOG(logPrefix + "Create wrapper for Services.downloads"); | |
} | |
} | |
else { | |
if(Services.downloads == Services[newKey] && Services[bakKey]) { | |
setProperty(Services, "downloads", Services[bakKey]); | |
delete Services[newKey]; | |
//LOG(logPrefix + "Restore Services.downloads"); | |
} | |
else { | |
// Yes, we create some memory leaks here, but it's better than break other extensions | |
delete Services[newKey].cleanUp; | |
//LOG(logPrefix + "Can't completely restore Services.downloads: detected third-party wrapper"); | |
} | |
delete Services[bakKey]; | |
} | |
} | |
function setProperty(o, p, v) { | |
Object.defineProperty(o, p, { | |
value: v, | |
configurable: true, | |
writable: true, | |
enumerable: true | |
}); | |
} | |
function destructor(reason) { | |
if(reason == "update" || reason == "delete") | |
dontRemoveFinishedDownloads(false); | |
} | |
if( | |
typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ | |
&& addDestructor != ("addDestructor" in window && window.addDestructor) | |
) | |
addDestructor(destructor, this); | |
else | |
this.onDestroy = destructor; | |
dontRemoveFinishedDownloads(true); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment