зеркало из https://github.com/mozilla/gecko-dev.git
Download manager. Not part of build.
This commit is contained in:
Родитель
3333249a1c
Коммит
58fd5f7236
|
@ -0,0 +1,327 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Blake Ross <blaker@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var dialog = new Object;
|
||||
dialog.strings = new Array;
|
||||
const interval = 500; // Update every 500 milliseconds.
|
||||
|
||||
function nsDownloadProgressListener() {
|
||||
}
|
||||
|
||||
nsDownloadProgressListener.prototype = {
|
||||
startTime: 0,
|
||||
elapsed: 0,
|
||||
rateChanges: 0,
|
||||
rateChangeLimit: 0,
|
||||
priorRate: 0,
|
||||
lastUpdate: -500,
|
||||
doc: null,
|
||||
get document() {
|
||||
return this.doc;
|
||||
},
|
||||
set document(newval) {
|
||||
return this.doc = newval;
|
||||
},
|
||||
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus, aDownloadItem)
|
||||
{
|
||||
if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
|
||||
{
|
||||
this.downloadItem = null;
|
||||
// we are done downloading...
|
||||
// Indicate completion in status area.
|
||||
var msg = getString( "completeMsg", this.doc );
|
||||
msg = replaceInsert( msg, 1, formatSeconds( this.elapsed/1000, this.doc ) );
|
||||
var aDownloadID = aDownloadItem.target.path;
|
||||
var elt = this.doc.getElementById(aDownloadID).firstChild.firstChild;
|
||||
var status = elt.nextSibling.nextSibling.nextSibling.nextSibling;
|
||||
status.setAttribute("label", msg);
|
||||
|
||||
var progress = elt.nextSibling.firstChild;
|
||||
// Put progress meter at 100%.
|
||||
progress.setAttribute( "value", 100 );
|
||||
progress.setAttribute( "mode", "normal" );
|
||||
var percentMsg = getString( "percentMsg", this.doc );
|
||||
percentMsg = replaceInsert( percentMsg, 1, 100 );
|
||||
}
|
||||
},
|
||||
|
||||
onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress, aDownloadItem)
|
||||
{
|
||||
if (!this.startTime)
|
||||
this.startTime = aDownloadItem.startTime / 1000;
|
||||
|
||||
var overallProgress = aCurTotalProgress;
|
||||
// Get current time.
|
||||
var now = ( new Date() ).getTime();
|
||||
// If interval hasn't elapsed, ignore it.
|
||||
if ( now - this.lastUpdate < interval && aMaxTotalProgress != "-1" && parseInt(aCurTotalProgress) < parseInt(aMaxTotalProgress) )
|
||||
return;
|
||||
|
||||
// Update this time.
|
||||
this.lastUpdate = now;
|
||||
|
||||
// Update download rate.
|
||||
this.elapsed = now - this.startTime;
|
||||
var rate; // aCurTotalProgress/sec
|
||||
if ( this.elapsed )
|
||||
rate = ( aCurTotalProgress * 1000 ) / this.elapsed;
|
||||
else
|
||||
rate = 0;
|
||||
|
||||
var aDownloadID = aDownloadItem.target.path;
|
||||
var elt = this.doc.getElementById(aDownloadID).firstChild.firstChild;
|
||||
if (this.doc.getElementById("TimeElapsed").getAttribute("hidden") != "true") {
|
||||
elapsedCol = elt.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;
|
||||
// Update elapsed time display.
|
||||
elapsedCol.setAttribute("label", formatSeconds( this.elapsed / 1000, this.doc ));
|
||||
}
|
||||
// Calculate percentage.
|
||||
var percent;
|
||||
var progress = elt.nextSibling.firstChild;
|
||||
if ( aMaxTotalProgress > 0)
|
||||
{
|
||||
percent = Math.floor((overallProgress*100.0)/aMaxTotalProgress);
|
||||
if ( percent > 100 )
|
||||
percent = 100;
|
||||
|
||||
// Advance progress meter.
|
||||
progress.setAttribute( "value", percent );
|
||||
}
|
||||
else
|
||||
{
|
||||
percent = -1;
|
||||
|
||||
// Progress meter should be barber-pole in this case.
|
||||
progress.setAttribute( "mode", "undetermined" );
|
||||
}
|
||||
|
||||
// now that we've set the progress and the time, update # bytes downloaded...
|
||||
// Update status (nnK of mmK bytes at xx.xK aCurTotalProgress/sec)
|
||||
var status = getString( "progressMsgNoRate", this.doc );
|
||||
|
||||
// Insert 1 is the number of kilobytes downloaded so far.
|
||||
status = replaceInsert( status, 1, parseInt( overallProgress/1024 + .5 ) );
|
||||
|
||||
// Insert 2 is the total number of kilobytes to be downloaded (if known).
|
||||
if ( aMaxTotalProgress != "-1" )
|
||||
status = replaceInsert( status, 2, parseInt( aMaxTotalProgress/1024 + .5 ) );
|
||||
else
|
||||
status = replaceInsert( status, 2, "??" );
|
||||
|
||||
var rateMsg = getString( "rateMsg", this.doc );
|
||||
if ( rate )
|
||||
{
|
||||
// rate is bytes/sec
|
||||
var kRate = rate / 1024; // K bytes/sec;
|
||||
kRate = parseInt( kRate * 10 + .5 ); // xxx (3 digits)
|
||||
// Don't update too often!
|
||||
if ( kRate != this.priorRate )
|
||||
{
|
||||
if ( this.rateChanges++ == this.rateChangeLimit )
|
||||
{
|
||||
// Time to update download rate.
|
||||
this.priorRate = kRate;
|
||||
this.rateChanges = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stick with old rate for a bit longer.
|
||||
kRate = this.priorRate;
|
||||
}
|
||||
}
|
||||
else
|
||||
this.rateChanges = 0;
|
||||
|
||||
var fraction = kRate % 10;
|
||||
kRate = parseInt( ( kRate - fraction ) / 10 );
|
||||
|
||||
// Insert 3 is the download rate (in kilobytes/sec).
|
||||
rateMsg = replaceInsert( rateMsg, 1, kRate + "." + fraction );
|
||||
}
|
||||
else
|
||||
rateMsg = replaceInsert( rateMsg, 1, "??.?" );
|
||||
|
||||
var progress = elt.nextSibling.nextSibling.nextSibling;
|
||||
|
||||
// Update status msg.
|
||||
var statusElt = progress.nextSibling;
|
||||
statusElt.setAttribute("label", status);
|
||||
|
||||
var rateElt = statusElt.nextSibling;
|
||||
rateElt.setAttribute("label", rateMsg);
|
||||
// Update percentage label on progress meter.
|
||||
if (this.doc.getElementById("ProgressText").getAttribute("hidden") != "true") {
|
||||
var progressText = elt.firstChild.nextSibling.nextSibling;
|
||||
if (percent < 0)
|
||||
progressText.setAttribute("label", "");
|
||||
else {
|
||||
var percentMsg = getString( "percentMsg", this.doc );
|
||||
percentMsg = replaceInsert( percentMsg, 1, percent );
|
||||
progressText.setAttribute("label", percentMsg);
|
||||
}
|
||||
}
|
||||
// Update time remaining.
|
||||
if ( rate && (aMaxTotalProgress > 0) )
|
||||
{
|
||||
var rem = ( aMaxTotalProgress - aCurTotalProgress ) / rate;
|
||||
rem = parseInt( rem + .5 );
|
||||
progress.setAttribute("label", formatSeconds( rem, this.doc ));
|
||||
}
|
||||
else
|
||||
progress.setAttribute("label", getString( "unknownTime", this.doc ));
|
||||
},
|
||||
onLocationChange: function(aWebProgress, aRequest, aLocation, aDownloadItem)
|
||||
{
|
||||
},
|
||||
onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage, aDownloadItem)
|
||||
{
|
||||
// XXX error handling
|
||||
},
|
||||
onSecurityChange: function(aWebProgress, aRequest, state, aDownloadItem)
|
||||
{
|
||||
},
|
||||
QueryInterface : function(iid)
|
||||
{
|
||||
if (iid.equals(Components.interfaces.nsIDownloadProgressListener) ||
|
||||
iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
var nsDownloadProgressListenerFactory = {
|
||||
createInstance: function (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
return (new nsDownloadProgressListener()).QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
var nsDownloadProgressListenerModule = {
|
||||
|
||||
registerSelf: function (compMgr, fileSpec, location, type)
|
||||
{
|
||||
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentManagerObsolete);
|
||||
compMgr.registerComponentWithType(Components.ID("{09cddbea-1dd2-11b2-aa15-c41ffea19d79}"),
|
||||
"Download Progress Listener",
|
||||
"@mozilla.org/download-manager/listener;1", fileSpec,
|
||||
location, true, true, type);
|
||||
},
|
||||
canUnload: function(compMgr)
|
||||
{
|
||||
return true;
|
||||
},
|
||||
|
||||
getClassObject: function (compMgr, cid, iid) {
|
||||
if (!cid.equals(Components.ID("{09cddbea-1dd2-11b2-aa15-c41ffea19d79}")))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
if (!iid.equals(Components.interfaces.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return nsDownloadProgressListenerFactory;
|
||||
}
|
||||
};
|
||||
|
||||
function NSGetModule(compMgr, fileSpec) {
|
||||
return nsDownloadProgressListenerModule;
|
||||
}
|
||||
|
||||
function replaceInsert( text, index, value ) {
|
||||
var result = text;
|
||||
var regExp = new RegExp( "#"+index );
|
||||
result = result.replace( regExp, value );
|
||||
return result;
|
||||
}
|
||||
|
||||
function getString( stringId, doc ) {
|
||||
// Check if we've fetched this string already.
|
||||
if ( !dialog.strings[ stringId ] ) {
|
||||
// Try to get it.
|
||||
var elem = doc.getElementById( "dialog.strings."+stringId );
|
||||
try {
|
||||
if ( elem
|
||||
&&
|
||||
elem.childNodes
|
||||
&&
|
||||
elem.childNodes[0]
|
||||
&&
|
||||
elem.childNodes[0].nodeValue ) {
|
||||
dialog.strings[ stringId ] = elem.childNodes[0].nodeValue;
|
||||
} else {
|
||||
// If unable to fetch string, use an empty string.
|
||||
dialog.strings[ stringId ] = "";
|
||||
}
|
||||
} catch (e) { dialog.strings[ stringId ] = ""; }
|
||||
}
|
||||
return dialog.strings[ stringId ];
|
||||
}
|
||||
|
||||
function formatSeconds( secs, doc )
|
||||
{
|
||||
// Round the number of seconds to remove fractions.
|
||||
secs = parseInt( secs + .5 );
|
||||
var hours = parseInt( secs/3600 );
|
||||
secs -= hours*3600;
|
||||
var mins = parseInt( secs/60 );
|
||||
secs -= mins*60;
|
||||
var result;
|
||||
if ( hours )
|
||||
result = getString( "longTimeFormat", doc );
|
||||
else
|
||||
result = getString( "shortTimeFormat", doc );
|
||||
|
||||
if ( hours < 10 )
|
||||
hours = "0" + hours;
|
||||
if ( mins < 10 )
|
||||
mins = "0" + mins;
|
||||
if ( secs < 10 )
|
||||
secs = "0" + secs;
|
||||
|
||||
// Insert hours, minutes, and seconds into result string.
|
||||
result = replaceInsert( result, 1, hours );
|
||||
result = replaceInsert( result, 2, mins );
|
||||
result = replaceInsert( result, 3, secs );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче