mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-09 16:57:30 +09:00
Add Pale Moon
This commit is contained in:
parent
dcd9973243
commit
fe8028fa2e
1173 changed files with 143053 additions and 934 deletions
674
application/palemoon/components/statusbar/Downloads.jsm
Normal file
674
application/palemoon/components/statusbar/Downloads.jsm
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPORTED_SYMBOLS = ["S4EDownloadService"];
|
||||
|
||||
const CC = Components.classes;
|
||||
const CI = Components.interfaces;
|
||||
const CU = Components.utils;
|
||||
|
||||
CU.import("resource://gre/modules/Services.jsm");
|
||||
CU.import("resource://gre/modules/PluralForm.jsm");
|
||||
CU.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
CU.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
CU.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function S4EDownloadService(window, gBrowser, service, getters)
|
||||
{
|
||||
this._window = window;
|
||||
this._gBrowser = gBrowser;
|
||||
this._service = service;
|
||||
this._getters = getters;
|
||||
|
||||
this._handler = new JSTransferHandler(this._window, this);
|
||||
}
|
||||
|
||||
S4EDownloadService.prototype =
|
||||
{
|
||||
_window: null,
|
||||
_gBrowser: null,
|
||||
_service: null,
|
||||
_getters: null,
|
||||
|
||||
_handler: null,
|
||||
_listening: false,
|
||||
|
||||
_binding: false,
|
||||
_customizing: false,
|
||||
|
||||
_lastTime: Infinity,
|
||||
|
||||
_dlActive: false,
|
||||
_dlPaused: false,
|
||||
_dlFinished: false,
|
||||
|
||||
_dlCountStr: null,
|
||||
_dlTimeStr: null,
|
||||
|
||||
_dlProgressAvg: 0,
|
||||
_dlProgressMax: 0,
|
||||
_dlProgressMin: 0,
|
||||
_dlProgressType: "active",
|
||||
|
||||
_dlNotifyTimer: 0,
|
||||
_dlNotifyGlowTimer: 0,
|
||||
|
||||
init: function()
|
||||
{
|
||||
if(!this._getters.downloadButton)
|
||||
{
|
||||
this.uninit();
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._listening)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._handler.start();
|
||||
this._listening = true;
|
||||
|
||||
this._lastTime = Infinity;
|
||||
|
||||
this.updateBinding();
|
||||
this.updateStatus();
|
||||
},
|
||||
|
||||
uninit: function()
|
||||
{
|
||||
if(!this._listening)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._listening = false;
|
||||
this._handler.stop();
|
||||
|
||||
this.releaseBinding();
|
||||
},
|
||||
|
||||
destroy: function()
|
||||
{
|
||||
this.uninit();
|
||||
this._handler.destroy();
|
||||
|
||||
["_window", "_gBrowser", "_service", "_getters", "_handler"].forEach(function(prop)
|
||||
{
|
||||
delete this[prop];
|
||||
}, this);
|
||||
},
|
||||
|
||||
updateBinding: function()
|
||||
{
|
||||
if(!this._listening)
|
||||
{
|
||||
this.releaseBinding();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(this._service.downloadButtonAction)
|
||||
{
|
||||
case 1: // Default
|
||||
this.attachBinding();
|
||||
break;
|
||||
default:
|
||||
this.releaseBinding();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
attachBinding: function()
|
||||
{
|
||||
if(this._binding)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let db = this._window.DownloadsButton;
|
||||
|
||||
db._getAnchorS4EBackup = db.getAnchor;
|
||||
db.getAnchor = this.getAnchor.bind(this);
|
||||
|
||||
db._releaseAnchorS4EBackup = db.releaseAnchor;
|
||||
db.releaseAnchor = function() {};
|
||||
|
||||
this._binding = true;
|
||||
},
|
||||
|
||||
releaseBinding: function()
|
||||
{
|
||||
if(!this._binding)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let db = this._window.DownloadsButton;
|
||||
|
||||
db.getAnchor = db._getAnchorS4EBackup;
|
||||
db.releaseAnchor = db._releaseAnchorS4EBackup;
|
||||
|
||||
this._binding = false;
|
||||
},
|
||||
|
||||
customizing: function(val)
|
||||
{
|
||||
this._customizing = val;
|
||||
},
|
||||
|
||||
updateStatus: function(lastFinished)
|
||||
{
|
||||
if(!this._getters.downloadButton)
|
||||
{
|
||||
this.uninit();
|
||||
return;
|
||||
}
|
||||
|
||||
let numActive = 0;
|
||||
let numPaused = 0;
|
||||
let activeTotalSize = 0;
|
||||
let activeTransferred = 0;
|
||||
let activeMaxProgress = -Infinity;
|
||||
let activeMinProgress = Infinity;
|
||||
let pausedTotalSize = 0;
|
||||
let pausedTransferred = 0;
|
||||
let pausedMaxProgress = -Infinity;
|
||||
let pausedMinProgress = Infinity;
|
||||
let maxTime = -Infinity;
|
||||
|
||||
let dls = ((this.isPrivateWindow) ? this._handler.activePrivateEntries() : this._handler.activeEntries());
|
||||
for(let dl of dls)
|
||||
{
|
||||
if(dl.state == CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING)
|
||||
{
|
||||
numActive++;
|
||||
if(dl.size > 0)
|
||||
{
|
||||
if(dl.speed > 0)
|
||||
{
|
||||
maxTime = Math.max(maxTime, (dl.size - dl.transferred) / dl.speed);
|
||||
}
|
||||
|
||||
activeTotalSize += dl.size;
|
||||
activeTransferred += dl.transferred;
|
||||
|
||||
let currentProgress = ((dl.transferred * 100) / dl.size);
|
||||
activeMaxProgress = Math.max(activeMaxProgress, currentProgress);
|
||||
activeMinProgress = Math.min(activeMinProgress, currentProgress);
|
||||
}
|
||||
}
|
||||
else if(dl.state == CI.nsIDownloadManager.DOWNLOAD_PAUSED)
|
||||
{
|
||||
numPaused++;
|
||||
if(dl.size > 0)
|
||||
{
|
||||
pausedTotalSize += dl.size;
|
||||
pausedTransferred += dl.transferred;
|
||||
|
||||
let currentProgress = ((dl.transferred * 100) / dl.size);
|
||||
pausedMaxProgress = Math.max(pausedMaxProgress, currentProgress);
|
||||
pausedMinProgress = Math.min(pausedMinProgress, currentProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((numActive + numPaused) == 0)
|
||||
{
|
||||
this._dlActive = false;
|
||||
this._dlFinished = lastFinished;
|
||||
this.updateButton();
|
||||
this._lastTime = Infinity;
|
||||
return;
|
||||
}
|
||||
|
||||
let dlPaused = (numActive == 0);
|
||||
let dlStatus = ((dlPaused) ? this._getters.strings.getString("pausedDownloads")
|
||||
: this._getters.strings.getString("activeDownloads"));
|
||||
let dlCount = ((dlPaused) ? numPaused : numActive);
|
||||
let dlTotalSize = ((dlPaused) ? pausedTotalSize : activeTotalSize);
|
||||
let dlTransferred = ((dlPaused) ? pausedTransferred : activeTransferred);
|
||||
let dlMaxProgress = ((dlPaused) ? pausedMaxProgress : activeMaxProgress);
|
||||
let dlMinProgress = ((dlPaused) ? pausedMinProgress : activeMinProgress);
|
||||
let dlProgressType = ((dlPaused) ? "paused" : "active");
|
||||
|
||||
[this._dlTimeStr, this._lastTime] = DownloadUtils.getTimeLeft(maxTime, this._lastTime);
|
||||
this._dlCountStr = PluralForm.get(dlCount, dlStatus).replace("#1", dlCount);
|
||||
this._dlProgressAvg = ((dlTotalSize == 0) ? 100 : ((dlTransferred * 100) / dlTotalSize));
|
||||
this._dlProgressMax = ((dlTotalSize == 0) ? 100 : dlMaxProgress);
|
||||
this._dlProgressMin = ((dlTotalSize == 0) ? 100 : dlMinProgress);
|
||||
this._dlProgressType = dlProgressType + ((dlTotalSize == 0) ? "-unknown" : "");
|
||||
this._dlPaused = dlPaused;
|
||||
this._dlActive = true;
|
||||
this._dlFinished = false;
|
||||
|
||||
this.updateButton();
|
||||
},
|
||||
|
||||
updateButton: function()
|
||||
{
|
||||
let download_button = this._getters.downloadButton;
|
||||
let download_tooltip = this._getters.downloadButtonTooltip;
|
||||
let download_progress = this._getters.downloadButtonProgress;
|
||||
let download_label = this._getters.downloadButtonLabel;
|
||||
if(!download_button)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this._dlActive)
|
||||
{
|
||||
download_button.collapsed = true;
|
||||
download_label.value = download_tooltip.label = this._getters.strings.getString("noDownloads");
|
||||
|
||||
download_progress.collapsed = true;
|
||||
download_progress.value = 0;
|
||||
|
||||
if(this._dlFinished && this._handler.hasPBAPI && !this.isUIShowing)
|
||||
{
|
||||
this.callAttention(download_button);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch(this._service.downloadProgress)
|
||||
{
|
||||
case 2:
|
||||
download_progress.value = this._dlProgressMax;
|
||||
break;
|
||||
case 3:
|
||||
download_progress.value = this._dlProgressMin;
|
||||
break;
|
||||
default:
|
||||
download_progress.value = this._dlProgressAvg;
|
||||
break;
|
||||
}
|
||||
download_progress.setAttribute("pmType", this._dlProgressType);
|
||||
download_progress.collapsed = (this._service.downloadProgress == 0);
|
||||
|
||||
download_label.value = this.buildString(this._service.downloadLabel);
|
||||
download_tooltip.label = this.buildString(this._service.downloadTooltip);
|
||||
|
||||
this.clearAttention(download_button);
|
||||
download_button.collapsed = false;
|
||||
},
|
||||
|
||||
callAttention: function(download_button)
|
||||
{
|
||||
if(this._dlNotifyGlowTimer != 0)
|
||||
{
|
||||
this._window.clearTimeout(this._dlNotifyGlowTimer);
|
||||
this._dlNotifyGlowTimer = 0;
|
||||
}
|
||||
|
||||
download_button.setAttribute("attention", "true");
|
||||
|
||||
if(this._service.downloadNotifyTimeout)
|
||||
{
|
||||
this._dlNotifyGlowTimer = this._window.setTimeout(function(self, button)
|
||||
{
|
||||
self._dlNotifyGlowTimer = 0;
|
||||
button.removeAttribute("attention");
|
||||
}, this._service.downloadNotifyTimeout, this, download_button);
|
||||
}
|
||||
},
|
||||
|
||||
clearAttention: function(download_button)
|
||||
{
|
||||
if(this._dlNotifyGlowTimer != 0)
|
||||
{
|
||||
this._window.clearTimeout(this._dlNotifyGlowTimer);
|
||||
this._dlNotifyGlowTimer = 0;
|
||||
}
|
||||
|
||||
download_button.removeAttribute("attention");
|
||||
},
|
||||
|
||||
notify: function()
|
||||
{
|
||||
if(this._dlNotifyTimer == 0 && this._service.downloadNotifyAnimate)
|
||||
{
|
||||
let download_button_anchor = this._getters.downloadButtonAnchor;
|
||||
let download_notify_anchor = this._getters.downloadNotifyAnchor;
|
||||
if(download_button_anchor)
|
||||
{
|
||||
if(!download_notify_anchor.style.transform)
|
||||
{
|
||||
let bAnchorRect = download_button_anchor.getBoundingClientRect();
|
||||
let nAnchorRect = download_notify_anchor.getBoundingClientRect();
|
||||
|
||||
let translateX = bAnchorRect.left - nAnchorRect.left;
|
||||
translateX += .5 * (bAnchorRect.width - nAnchorRect.width);
|
||||
|
||||
let translateY = bAnchorRect.top - nAnchorRect.top;
|
||||
translateY += .5 * (bAnchorRect.height - nAnchorRect.height);
|
||||
|
||||
download_notify_anchor.style.transform = "translate(" + translateX + "px, " + translateY + "px)";
|
||||
}
|
||||
|
||||
download_notify_anchor.setAttribute("notification", "finish");
|
||||
this._dlNotifyTimer = this._window.setTimeout(function(self, anchor)
|
||||
{
|
||||
self._dlNotifyTimer = 0;
|
||||
anchor.removeAttribute("notification");
|
||||
anchor.style.transform = "";
|
||||
}, 1000, this, download_notify_anchor);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
clearFinished: function()
|
||||
{
|
||||
this._dlFinished = false;
|
||||
let download_button = this._getters.downloadButton;
|
||||
if(download_button)
|
||||
{
|
||||
this.clearAttention(download_button);
|
||||
}
|
||||
},
|
||||
|
||||
getAnchor: function(aCallback)
|
||||
{
|
||||
if(this._customizing)
|
||||
{
|
||||
aCallback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
aCallback(this._getters.downloadButtonAnchor);
|
||||
},
|
||||
|
||||
openUI: function(aEvent)
|
||||
{
|
||||
this.clearFinished();
|
||||
|
||||
switch(this._service.downloadButtonAction)
|
||||
{
|
||||
case 1: // Firefox Default
|
||||
this._handler.openUINative();
|
||||
break;
|
||||
case 2: // Show Library
|
||||
this._window.PlacesCommandHook.showPlacesOrganizer("Downloads");
|
||||
break;
|
||||
case 3: // Show Tab
|
||||
let found = this._gBrowser.browsers.some(function(browser, index)
|
||||
{
|
||||
if("about:downloads" == browser.currentURI.spec)
|
||||
{
|
||||
this._gBrowser.selectedTab = this._gBrowser.tabContainer.childNodes[index];
|
||||
return true;
|
||||
}
|
||||
}, this);
|
||||
|
||||
if(!found)
|
||||
{
|
||||
this._window.openUILinkIn("about:downloads", "tab");
|
||||
}
|
||||
break;
|
||||
case 4: // External Command
|
||||
let command = this._service.downloadButtonActionCommand;
|
||||
if(commend)
|
||||
{
|
||||
this._window.goDoCommand(command);
|
||||
}
|
||||
break;
|
||||
default: // Nothing
|
||||
break;
|
||||
}
|
||||
|
||||
aEvent.stopPropagation();
|
||||
},
|
||||
|
||||
get isPrivateWindow()
|
||||
{
|
||||
return this._handler.hasPBAPI && PrivateBrowsingUtils.isWindowPrivate(this._window);
|
||||
},
|
||||
|
||||
get isUIShowing()
|
||||
{
|
||||
switch(this._service.downloadButtonAction)
|
||||
{
|
||||
case 1: // Firefox Default
|
||||
return this._handler.isUIShowingNative;
|
||||
case 2: // Show Library
|
||||
var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
|
||||
if(organizer)
|
||||
{
|
||||
let selectedNode = organizer.PlacesOrganizer._places.selectedNode;
|
||||
let downloadsItemId = organizer.PlacesUIUtils.leftPaneQueries["Downloads"];
|
||||
return selectedNode && selectedNode.itemId === downloadsItemId;
|
||||
}
|
||||
return false;
|
||||
case 3: // Show tab
|
||||
let currentURI = this._gBrowser.currentURI;
|
||||
return currentURI && currentURI.spec == "about:downloads";
|
||||
default: // Nothing
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
buildString: function(mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case 0:
|
||||
return this._dlCountStr;
|
||||
case 1:
|
||||
return ((this._dlPaused) ? this._dlCountStr : this._dlTimeStr);
|
||||
default:
|
||||
let compStr = this._dlCountStr;
|
||||
if(!this._dlPaused)
|
||||
{
|
||||
compStr += " (" + this._dlTimeStr + ")";
|
||||
}
|
||||
return compStr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function JSTransferHandler(window, downloadService)
|
||||
{
|
||||
this._window = window;
|
||||
|
||||
let api = CU.import("resource://gre/modules/Downloads.jsm", {}).Downloads;
|
||||
|
||||
this._activePublic = new JSTransferListener(downloadService, api.getList(api.PUBLIC), false);
|
||||
this._activePrivate = new JSTransferListener(downloadService, api.getList(api.PRIVATE), true);
|
||||
}
|
||||
|
||||
JSTransferHandler.prototype =
|
||||
{
|
||||
_window: null,
|
||||
_activePublic: null,
|
||||
_activePrivate: null,
|
||||
|
||||
destroy: function()
|
||||
{
|
||||
this._activePublic.destroy();
|
||||
this._activePrivate.destroy();
|
||||
|
||||
["_window", "_activePublic", "_activePrivate"].forEach(function(prop)
|
||||
{
|
||||
delete this[prop];
|
||||
}, this);
|
||||
},
|
||||
|
||||
start: function()
|
||||
{
|
||||
this._activePublic.start();
|
||||
this._activePrivate.start();
|
||||
},
|
||||
|
||||
stop: function()
|
||||
{
|
||||
this._activePublic.stop();
|
||||
this._activePrivate.stop();
|
||||
},
|
||||
|
||||
get hasPBAPI()
|
||||
{
|
||||
return true;
|
||||
},
|
||||
|
||||
openUINative: function()
|
||||
{
|
||||
this._window.DownloadsPanel.showPanel();
|
||||
},
|
||||
|
||||
get isUIShowingNative()
|
||||
{
|
||||
return this._window.DownloadsPanel.isPanelShowing;
|
||||
},
|
||||
|
||||
activeEntries: function()
|
||||
{
|
||||
return this._activePublic.downloads();
|
||||
},
|
||||
|
||||
activePrivateEntries: function()
|
||||
{
|
||||
return this._activePrivate.downloads();
|
||||
}
|
||||
};
|
||||
|
||||
function JSTransferListener(downloadService, listPromise, isPrivate)
|
||||
{
|
||||
this._downloadService = downloadService;
|
||||
this._isPrivate = isPrivate;
|
||||
this._downloads = new Map();
|
||||
|
||||
listPromise.then(this.initList.bind(this)).then(null, CU.reportError);
|
||||
}
|
||||
|
||||
JSTransferListener.prototype =
|
||||
{
|
||||
_downloadService: null,
|
||||
_list: null,
|
||||
_downloads: null,
|
||||
_isPrivate: false,
|
||||
_wantsStart: false,
|
||||
|
||||
initList: function(list)
|
||||
{
|
||||
this._list = list;
|
||||
if(this._wantsStart) {
|
||||
this.start();
|
||||
}
|
||||
|
||||
this._list.getAll().then(this.initDownloads.bind(this)).then(null, CU.reportError);
|
||||
},
|
||||
|
||||
initDownloads: function(downloads)
|
||||
{
|
||||
downloads.forEach(function(download)
|
||||
{
|
||||
this.onDownloadAdded(download);
|
||||
}, this);
|
||||
},
|
||||
|
||||
destroy: function()
|
||||
{
|
||||
this._downloads.clear();
|
||||
|
||||
["_downloadService", "_list", "_downloads"].forEach(function(prop)
|
||||
{
|
||||
delete this[prop];
|
||||
}, this);
|
||||
},
|
||||
|
||||
start: function()
|
||||
{
|
||||
if(!this._list)
|
||||
{
|
||||
this._wantsStart = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this._list.addView(this);
|
||||
},
|
||||
|
||||
stop: function()
|
||||
{
|
||||
if(!this._list)
|
||||
{
|
||||
this._wantsStart = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this._list.removeView(this);
|
||||
},
|
||||
|
||||
downloads: function()
|
||||
{
|
||||
return this._downloads.values();
|
||||
},
|
||||
|
||||
convertToState: function(dl)
|
||||
{
|
||||
if(dl.succeeded)
|
||||
{
|
||||
return CI.nsIDownloadManager.DOWNLOAD_FINISHED;
|
||||
}
|
||||
if(dl.error && dl.error.becauseBlockedByParentalControls)
|
||||
{
|
||||
return CI.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL;
|
||||
}
|
||||
if(dl.error)
|
||||
{
|
||||
return CI.nsIDownloadManager.DOWNLOAD_FAILED;
|
||||
}
|
||||
if(dl.canceled && dl.hasPartialData)
|
||||
{
|
||||
return CI.nsIDownloadManager.DOWNLOAD_PAUSED;
|
||||
}
|
||||
if(dl.canceled)
|
||||
{
|
||||
return CI.nsIDownloadManager.DOWNLOAD_CANCELED;
|
||||
}
|
||||
if(dl.stopped)
|
||||
{
|
||||
return CI.nsIDownloadManager.DOWNLOAD_NOTSTARTED;
|
||||
}
|
||||
return CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING;
|
||||
},
|
||||
|
||||
onDownloadAdded: function(aDownload)
|
||||
{
|
||||
let dl = this._downloads.get(aDownload);
|
||||
if(!dl)
|
||||
{
|
||||
dl = {};
|
||||
this._downloads.set(aDownload, dl);
|
||||
}
|
||||
|
||||
dl.state = this.convertToState(aDownload);
|
||||
dl.size = aDownload.totalBytes;
|
||||
dl.speed = aDownload.speed;
|
||||
dl.transferred = aDownload.currentBytes;
|
||||
},
|
||||
|
||||
onDownloadChanged: function(aDownload)
|
||||
{
|
||||
this.onDownloadAdded(aDownload);
|
||||
|
||||
if(this._isPrivate != this._downloadService.isPrivateWindow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._downloadService.updateStatus(aDownload.succeeded);
|
||||
|
||||
if(aDownload.succeeded)
|
||||
{
|
||||
this._downloadService.notify()
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadRemoved: function(aDownload)
|
||||
{
|
||||
this._downloads.delete(aDownload);
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue