home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / 01_03.iso / software / ghostzilla_hit / files / ghostzilla-1.0-plus-install.exe / chrome / toolkit.jar / content / global / nsProgressDlg.js < prev    next >
Encoding:
JavaScript  |  2002-05-13  |  18.6 KB  |  592 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "License"); you may not use this file except in
  5.  * compliance with the License.  You may obtain a copy of the License at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  10.  * for the specific language governing rights and limitations under the
  11.  * License.
  12.  *
  13.  * The Original Code is Mozilla Communicator client code,
  14.  * released March 31, 1998.
  15.  *
  16.  * The Initial Developer of the Original Code is Netscape Communications
  17.  * Corporation.  Portions created by Netscape are
  18.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  19.  * Reserved.
  20.  *
  21.  * Contributors:
  22.  *     William A. ("PowerGUI") Law <law@netscape.com>
  23.  *     Scott MacGregor <mscott@netscape.com>
  24.  */
  25.  
  26. var prefContractID            = "@mozilla.org/preferences-service;1";
  27. var externalProtocolServiceID = "@mozilla.org/uriloader/external-protocol-service;1";
  28.  
  29. // dialog is just an array we'll use to store various properties from the dialog document...
  30. var dialog;
  31.  
  32. // the helperAppLoader is a nsIHelperAppLauncher object
  33. var helperAppLoader;
  34. var webBrowserPersist;                                                          
  35. var persistArgs;    
  36. const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
  37.  
  38. // random global variables...
  39. var completed = false;
  40. var startTime = 0;
  41. var elapsed = 0;
  42. var interval = 500; // Update every 500 milliseconds.
  43. var lastUpdate = -interval; // Update initially.
  44. var keepProgressWindowUpBox;
  45. var targetFile;
  46. var gRestartChecked = false;
  47.  
  48. // These are to throttle down the updating of the download rate figure.
  49. var priorRate = 0;
  50. var rateChanges = 0;
  51. var rateChangeLimit = 2;
  52.  
  53. // all progress notifications are done through our nsIWebProgressListener implementation...
  54. var progressListener = {
  55.     onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus)
  56.     {
  57.       if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
  58.       {
  59.         // we are done downloading...
  60.         completed = true;
  61.         // Indicate completion in status area.
  62.         var msg = getString( "completeMsg" );
  63.         msg = replaceInsert( msg, 1, formatSeconds( elapsed/1000 ) );
  64.         dialog.status.setAttribute("value", msg);
  65.  
  66.         // Put progress meter at 100%.
  67.         dialog.progress.setAttribute( "value", 100 );
  68.         dialog.progress.setAttribute( "mode", "normal" );
  69.         var percentMsg = getString( "percentMsg" );
  70.         percentMsg = replaceInsert( percentMsg, 1, 100 );
  71.         dialog.progressText.setAttribute("label", percentMsg);
  72.  
  73.         const nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist;
  74.         if (helperAppLoader || webBrowserPersist &&
  75.             webBrowserPersist.currentState == nsIWebBrowserPersist.PERSIST_STATE_FINISHED)
  76.           setTimeout("processEndOfDownload()", 0);
  77.       }
  78.     },
  79.  
  80.     onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
  81.     {
  82.  
  83.       if (!gRestartChecked)
  84.       {
  85.         gRestartChecked = true;
  86.         try 
  87.         {
  88.           // right now, all that supports restarting downloads is ftp (rfc959)    
  89.           ftpChannel = aRequest.QueryInterface(Components.interfaces.nsIFTPChannel);
  90.           if (ftpChannel) {
  91.             dialog.pauseResumeDeck.setAttribute("selectedIndex", "1");
  92.           }
  93.         }
  94.         catch (ex) {}
  95.       }
  96.  
  97.       // this is so that we don't clobber the status text if 
  98.       // a onProgressChange event happens after we press the pause btn.
  99.       if (dialog.downloadPaused) 
  100.       {
  101.         dialog.status.setAttribute("value", getString("pausedMsg"));
  102.       }
  103.  
  104.       dialog.request = aRequest;  
  105.  
  106.       var overallProgress = aCurTotalProgress;
  107.  
  108.       // Get current time.
  109.       var now = ( new Date() ).getTime();
  110.       // If interval hasn't elapsed, ignore it.
  111.       if ( now - lastUpdate < interval && aMaxTotalProgress != "-1" &&  parseInt(aCurTotalProgress) < parseInt(aMaxTotalProgress) )
  112.         return;
  113.  
  114.       // Update this time.
  115.       lastUpdate = now;
  116.  
  117.       // Update download rate.
  118.       elapsed = now - startTime;
  119.       var rate; // aCurTotalProgress/sec
  120.       if ( elapsed )
  121.         rate = ( aCurTotalProgress * 1000 ) / elapsed;
  122.       else
  123.         rate = 0;
  124.  
  125.       // Update elapsed time display.
  126.       dialog.timeElapsed.setAttribute("value", formatSeconds( elapsed / 1000 ));
  127.  
  128.       // Calculate percentage.
  129.       var percent;
  130.       if ( aMaxTotalProgress > 0)
  131.       {
  132.         percent = Math.floor((overallProgress*100.0)/aMaxTotalProgress);
  133.         if ( percent > 100 )
  134.           percent = 100;
  135.  
  136.         // Advance progress meter.
  137.         dialog.progress.setAttribute( "value", percent );
  138.       }
  139.       else
  140.       {
  141.         percent = -1;
  142.  
  143.         // Progress meter should be barber-pole in this case.
  144.         dialog.progress.setAttribute( "mode", "undetermined" );
  145.       }
  146.  
  147.       // now that we've set the progress and the time, update # bytes downloaded...
  148.       // Update status (nnK of mmK bytes at xx.xK aCurTotalProgress/sec)
  149.       var status = getString( "progressMsg" );
  150.  
  151.       // Insert 1 is the number of kilobytes downloaded so far.
  152.       status = replaceInsert( status, 1, parseInt( overallProgress/1024 + .5 ) );
  153.  
  154.       // Insert 2 is the total number of kilobytes to be downloaded (if known).
  155.       if ( aMaxTotalProgress != "-1" )
  156.          status = replaceInsert( status, 2, parseInt( aMaxTotalProgress/1024 + .5 ) );
  157.       else
  158.          status = replaceInsert( status, 2, "??" );
  159.  
  160.       if ( rate )
  161.       {
  162.         // rate is bytes/sec
  163.         var kRate = rate / 1024; // K bytes/sec;
  164.         kRate = parseInt( kRate * 10 + .5 ); // xxx (3 digits)
  165.         // Don't update too often!
  166.         if ( kRate != priorRate )
  167.         {
  168.           if ( rateChanges++ == rateChangeLimit )
  169.           {
  170.              // Time to update download rate.
  171.              priorRate = kRate;
  172.              rateChanges = 0;
  173.           }
  174.           else
  175.           {
  176.             // Stick with old rate for a bit longer.
  177.             kRate = priorRate;
  178.           }
  179.         }
  180.         else
  181.           rateChanges = 0;
  182.  
  183.          var fraction = kRate % 10;
  184.          kRate = parseInt( ( kRate - fraction ) / 10 );
  185.  
  186.          // Insert 3 is the download rate (in kilobytes/sec).
  187.          status = replaceInsert( status, 3, kRate + "." + fraction );
  188.       }
  189.       else
  190.        status = replaceInsert( status, 3, "??.?" );
  191.  
  192.       // Update status msg.
  193.       dialog.status.setAttribute("value", status);
  194.  
  195.       // Update percentage label on progress meter.      
  196.       if (percent < 0)
  197.         dialog.progressText.setAttribute("value", "");
  198.       else
  199.       {
  200.         var percentMsg = getString( "percentMsg" );      
  201.         percentMsg = replaceInsert( percentMsg, 1, percent );
  202.         dialog.progressText.setAttribute("value", percentMsg);
  203.       }
  204.  
  205.       // Update time remaining.
  206.       if ( rate && (aMaxTotalProgress > 0) )
  207.       {
  208.         var rem = ( aMaxTotalProgress - aCurTotalProgress ) / rate;
  209.         rem = parseInt( rem + .5 );
  210.         dialog.timeLeft.setAttribute("value", formatSeconds( rem ));
  211.       }
  212.       else
  213.         dialog.timeLeft.setAttribute("value", getString( "unknownTime" ));
  214.     },
  215.     onLocationChange: function(aWebProgress, aRequest, aLocation)
  216.     {
  217.       // we can ignore this notification
  218.     },
  219.     onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage)
  220.     {
  221.     },
  222.     onSecurityChange: function(aWebProgress, aRequest, state)
  223.     {
  224.     },
  225.     QueryInterface : function(iid)
  226.     {
  227.      if (iid.equals(Components.interfaces.nsIWebProgressListener) || iid.equals(Components.interfaces.nsISupportsWeakReference))
  228.       return this;
  229.  
  230.      throw Components.results.NS_NOINTERFACE;
  231.     }
  232. };
  233.  
  234. function getString( stringId ) {
  235.    // Check if we've fetched this string already.
  236.    if ( !dialog.strings[ stringId ] ) {
  237.       // Try to get it.
  238.       var elem = document.getElementById( "dialog.strings."+stringId );
  239.       try {
  240.         if ( elem
  241.            &&
  242.            elem.childNodes
  243.            &&
  244.            elem.childNodes[0]
  245.            &&
  246.            elem.childNodes[0].nodeValue ) {
  247.          dialog.strings[ stringId ] = elem.childNodes[0].nodeValue;
  248.         } else {
  249.           // If unable to fetch string, use an empty string.
  250.           dialog.strings[ stringId ] = "";
  251.         }
  252.       } catch (e) { dialog.strings[ stringId ] = ""; }
  253.    }
  254.    return dialog.strings[ stringId ];
  255. }
  256.  
  257. function formatSeconds( secs )
  258. {
  259.   // Round the number of seconds to remove fractions.
  260.   secs = parseInt( secs + .5 );
  261.   var hours = parseInt( secs/3600 );
  262.   secs -= hours*3600;
  263.   var mins = parseInt( secs/60 );
  264.   secs -= mins*60;
  265.   var result;
  266.   if ( hours )
  267.     result = getString( "longTimeFormat" );
  268.   else
  269.     result = getString( "shortTimeFormat" );
  270.  
  271.   if ( hours < 10 )
  272.      hours = "0" + hours;
  273.   if ( mins < 10 )
  274.      mins = "0" + mins;
  275.   if ( secs < 10 )
  276.      secs = "0" + secs;
  277.  
  278.   // Insert hours, minutes, and seconds into result string.
  279.   result = replaceInsert( result, 1, hours );
  280.   result = replaceInsert( result, 2, mins );
  281.   result = replaceInsert( result, 3, secs );
  282.  
  283.   return result;
  284. }
  285.  
  286. function loadDialog()
  287. {
  288.   var sourceUrlValue = {};
  289.   var initialDownloadTimeValue = {};
  290.   var sourceUrl = null;
  291.   
  292.    // targetFile is global because we are going to want re-use later one...
  293.   if (helperAppLoader) {
  294.     targetFile =  helperAppLoader.getDownloadInfo(sourceUrlValue, initialDownloadTimeValue);
  295.  
  296.     sourceUrl = sourceUrlValue.value;
  297.     startTime = initialDownloadTimeValue.value / 1000;
  298.   }
  299.   else if (webBrowserPersist) {
  300.     // When saving web pages, the file we're saving into is passed to us as a parameter.
  301.     try {
  302.       persistArgs.source.QueryInterface(Components.interfaces.nsIURI);
  303.       sourceUrl = persistArgs.source;
  304.     }
  305.     catch (e) {
  306.       sourceUrl = { spec: persistArgs.source.URL };
  307.     }
  308.   
  309.     // When saving web pages, we don't need to do anything special to receive the time
  310.     // at which the transfer started, so just assume it started 'now'.
  311.     startTime = ( new Date() ).getTime();  
  312.   }  
  313.   
  314.   // set the elapsed time on the first pass...
  315.   var now = ( new Date() ).getTime();
  316.   // intialize the elapsed time global variable slot
  317.   elapsed = now - startTime;
  318.   // Update elapsed time display.
  319.   dialog.timeElapsed.setAttribute("value", formatSeconds( elapsed / 1000 ));
  320.   dialog.timeLeft.setAttribute("value", formatSeconds( 0 ));
  321.  
  322.   dialog.location.setAttribute("value", sourceUrl.spec );
  323.   dialog.fileName.setAttribute( "value", targetFile.path );
  324.  
  325.   var prefs = Components.classes[prefContractID].getService(Components.interfaces.nsIPrefBranch);
  326.   if (prefs)
  327.     keepProgressWindowUpBox.checked = prefs.getBoolPref("browser.download.progressDnldDialog.keepAlive");
  328. }
  329.  
  330. function replaceInsert( text, index, value ) {
  331.    var result = text;
  332.    var regExp = new RegExp( "#"+index );
  333.    result = result.replace( regExp, value );
  334.    return result;
  335. }
  336.  
  337. function onLoad() {
  338.     // Set global variables.
  339.     try {
  340.       helperAppLoader = window.arguments[0].QueryInterface( Components.interfaces.nsIHelperAppLauncher );
  341.     }
  342.     catch (e) {
  343.       webBrowserPersist = window.arguments[0].QueryInterface( Components.interfaces.nsIWebBrowserPersist );
  344.       setTimeout("checkPersistComplete()", 100);
  345.     }
  346.  
  347.     if ( !helperAppLoader && !webBrowserPersist ) {
  348.         dump( "Invalid argument to helperAppDldProgress.xul\n" );
  349.         window.close()
  350.         return;
  351.     }
  352.  
  353.     dialog = new Object;
  354.     dialog.strings = new Array;
  355.     dialog.location    = document.getElementById("dialog.location");
  356.     dialog.contentType = document.getElementById("dialog.contentType");
  357.     dialog.fileName    = document.getElementById("dialog.fileName");
  358.     dialog.status      = document.getElementById("dialog.status");
  359.     dialog.progress    = document.getElementById("dialog.progress");
  360.     dialog.progressText = document.getElementById("dialog.progressText");
  361.     dialog.timeLeft    = document.getElementById("dialog.timeLeft");
  362.     dialog.timeElapsed = document.getElementById("dialog.timeElapsed");
  363.     dialog.cancel      = document.getElementById("cancel");
  364.     dialog.pause       = document.getElementById("pause");
  365.     dialog.resume      = document.getElementById("resume");
  366.     dialog.pauseResumeDeck = document.getElementById("pauseResumeDeck");
  367.     dialog.request     = 0;
  368.     dialog.downloadPaused = false;
  369.     keepProgressWindowUpBox = document.getElementById('keepProgressDialogUp');
  370.  
  371.     // Set up dialog button callbacks.
  372.     var object = this;
  373.     doSetOKCancel("", function () { return object.onCancel();});
  374.  
  375.     // set our web progress listener on the helper app launcher
  376.     if (helperAppLoader) 
  377.       helperAppLoader.setWebProgressListener(progressListener);
  378.     else if (webBrowserPersist) {
  379.       webBrowserPersist.progressListener = progressListener;
  380.       
  381.       persistArgs = window.arguments[1];
  382.       
  383.       targetFile = persistArgs.target;
  384.         
  385.       // If the code reaches this point, the user has agreed to replace existing files in the
  386.       // file picker. 
  387.       const flags = nsIWBP.PERSIST_FLAGS_NO_CONVERSION | nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
  388.       if (persistArgs.bypassCache)
  389.         webBrowserPersist.persistFlags |= nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
  390.       else 
  391.         webBrowserPersist.persistFlags |= nsIWBP.PERSIST_FLAGS_FROM_CACHE;
  392.       
  393.       try {
  394.         var uri = persistArgs.source.QueryInterface(Components.interfaces.nsIURI);
  395.         webBrowserPersist.saveURI(uri, persistArgs.postData, targetFile);
  396.       }
  397.       catch (e) {
  398.         // Saving a Document, not a URI:
  399.         
  400.         var filesFolder = null;
  401.         if (persistArgs.contentType != "text/plain") {
  402.           // Create the local directory into which to save associated files. 
  403.           const lfContractID = "@mozilla.org/file/local;1";
  404.           const lfIID = Components.interfaces.nsILocalFile;
  405.           filesFolder = Components .classes[lfContractID].createInstance(lfIID);
  406.           filesFolder.initWithPath(persistArgs.target.path);
  407.           
  408.           var nameWithoutExtension = filesFolder.leafName;
  409.           nameWithoutExtension = nameWithoutExtension.substring(0, nameWithoutExtension.lastIndexOf("."));
  410.           var filesFolderLeafName = getString("filesFolder");
  411.           filesFolderLeafName = filesFolderLeafName.replace(/\^BASE\^/, nameWithoutExtension);
  412.  
  413.           filesFolder.leafName = filesFolderLeafName;
  414.           
  415.           if (!filesFolder.exists())
  416.             filesFolder.create(lfIID.DIRECTORY_TYPE, 0755);
  417.         }
  418.           
  419.         var encodingFlags = 0;
  420.         if (persistArgs.contentType == "text/plain") {
  421.           encodingFlags |= nsIWBP.ENCODE_FLAGS_FORMATTED;
  422.           encodingFlags |= nsIWBP.ENCODE_FLAGS_ABSOLUTE_LINKS;
  423.           encodingFlags |= nsIWBP.ENCODE_FLAGS_NOFRAMES_CONTENT;        
  424.         }
  425.         
  426.         const kWrapColumn = 80;
  427.  
  428.         webBrowserPersist.saveDocument(persistArgs.source, targetFile, filesFolder, 
  429.                                        persistArgs.contentType, encodingFlags, kWrapColumn);
  430.       }
  431.     }
  432.     
  433.     // Fill dialog.
  434.     loadDialog();
  435.  
  436.     if ( window.opener ) {
  437.         moveToAlertPosition();
  438.     } else {
  439.         centerWindowOnScreen();
  440.     }
  441.     
  442.     // Set initial focus
  443.     if ( !completed )
  444.     {
  445.         keepProgressWindowUpBox.focus();
  446.     }
  447. }
  448.  
  449. function onUnload()
  450. {
  451.  
  452.   // remember the user's decision for the checkbox.
  453.  
  454.   var prefs = Components.classes[prefContractID].getService(Components.interfaces.nsIPrefBranch);
  455.   if (prefs)
  456.     prefs.setBoolPref("browser.download.progressDnldDialog.keepAlive", keepProgressWindowUpBox.checked);
  457.  
  458.    // Cancel app launcher.
  459.    if (helperAppLoader)
  460.    {
  461.      try
  462.      {
  463.        helperAppLoader.closeProgressWindow();
  464.        helperAppLoader = null;
  465.      }
  466.  
  467.      catch( exception ) {}
  468.    }
  469. }
  470.  
  471. // If the user presses cancel, tell the app launcher and close the dialog...
  472. function onCancel ()
  473. {
  474.    // Cancel app launcher.
  475.    if (helperAppLoader && !completed)
  476.    {
  477.      try
  478.      {
  479.        helperAppLoader.Cancel();
  480.      }
  481.  
  482.      catch( exception ) {}
  483.    }
  484.    else if (webBrowserPersist)
  485.    {
  486.      webBrowserPersist.cancelSave();
  487.    }
  488.  
  489.   // Close up dialog by returning true.
  490.   return true;
  491. }
  492.  
  493. // closeWindow should only be called from processEndOfDownload
  494. function closeWindow()
  495. {
  496.   // while the time out was fired the user may have checked the
  497.   // keep this dialog open box...so we should abort and not actually
  498.   // close the window.
  499.  
  500.   if (!keepProgressWindowUpBox.checked)
  501.     window.close();
  502.   else
  503.     setupPostProgressUI();
  504. }
  505.  
  506. function setupPostProgressUI()
  507. {
  508.   //dialog.cancel.childNodes[0].nodeValue = "Close";
  509.   // turn the cancel button into a close button
  510.   var cancelButton = document.getElementById('cancel');
  511.   if (cancelButton)
  512.   {
  513.     cancelButton.label = getString("close");
  514.     cancelButton.focus();
  515.   }
  516.  
  517.   // enable the open and open folder buttons
  518.   var openFolderButton = document.getElementById('openFolder');
  519.   var openButton = document.getElementById('open');
  520.  
  521.   openFolderButton.removeAttribute("disabled");
  522.   if ( !targetFile.isExecutable() )
  523.   {
  524.     openButton.removeAttribute("disabled");
  525.   }
  526.  
  527.   dialog.pause.disabled = true; // setAttribute("disabled", true);
  528.   dialog.resume.disabled = true;
  529.   
  530. }
  531.  
  532. // when we receive a stop notification we are done reporting progress on the download
  533. // now we have to decide if the window is supposed to go away or if we are supposed to remain open
  534. // and enable the open and open folder buttons on the dialog.
  535. function processEndOfDownload()
  536. {
  537.   if (!keepProgressWindowUpBox.checked) {
  538.     closeWindow(); // shut down, we are all done.
  539.     return;
  540.   }
  541.  
  542.   // o.t the user has asked the window to stay open so leave it open and enable the open and open new folder buttons
  543.   setupPostProgressUI();
  544. }
  545.  
  546. function doOpen()
  547. {
  548.   try {
  549.     var localFile = targetFile.QueryInterface(Components.interfaces.nsILocalFile);
  550.     if (localFile)
  551.       localFile.launch();
  552.     window.close();
  553.   } catch (ex) {}
  554. }
  555.  
  556. function doOpenFolder()
  557. {
  558.   try {
  559.     var localFile = targetFile.QueryInterface(Components.interfaces.nsILocalFile);
  560.     if (localFile)
  561.       localFile.reveal();
  562.     window.close();
  563.   } catch (ex) {}
  564. }
  565.  
  566. function doPauseButton() {
  567.     if (dialog.downloadPaused)
  568.     {
  569.         // resume
  570.         dialog.downloadPaused = false;
  571.         dialog.pauseResumeDeck.setAttribute("selectedIndex", "1");
  572.         dialog.request.resume()
  573.     }
  574.     else
  575.     {
  576.         // suspend
  577.         dialog.downloadPaused = true;
  578.         dialog.pauseResumeDeck.setAttribute("selectedIndex", "2");
  579.         dialog.request.suspend()
  580.     }
  581. }
  582.  
  583. function checkPersistComplete()
  584. {
  585.   const nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist;
  586.   if (webBrowserPersist.currentState == nsIWebBrowserPersist.PERSIST_STATE_FINISHED) {
  587.     dump("*** all done\n");
  588.     processEndOfDownload();
  589.   }
  590. }
  591.  
  592.