home *** CD-ROM | disk | FTP | other *** search
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla 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/MPL/
- *
- * 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 Progress Dialog.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corp.
- * Portions created by the Initial Developer are Copyright (C) 2002
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Bill Law <law@netscape.com>
- * Aaron Kaluszka <ask@swva.net>
- *
- * 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 MPL, 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 MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
- /* This file implements the nsIProgressDialog interface. See nsIProgressDialog.idl
- *
- * The implementation consists of a JavaScript "class" named nsProgressDialog,
- * comprised of:
- * - a JS constructor function
- * - a prototype providing all the interface methods and implementation stuff
- *
- * In addition, this file implements an nsIModule object that registers the
- * nsProgressDialog component.
- */
-
- /* ctor
- */
- function nsProgressDialog() {
- // Initialize data properties.
- this.mParent = null;
- this.mOperation = null;
- this.mStartTime = ( new Date() ).getTime();
- this.observer = null;
- this.mLastUpdate = Number.MIN_VALUE; // To ensure first onProgress causes update.
- this.mInterval = 750; // Default to .75 seconds.
- this.mElapsed = 0;
- this.mLoaded = false;
- this.fields = new Array;
- this.strings = new Array;
- this.mSource = null;
- this.mTarget = null;
- this.mMIMEInfo = null;
- this.mDialog = null;
- this.mDisplayName = null;
- this.mPaused = false;
- this.mRequest = null;
- this.mCompleted = false;
- this.mMode = "normal";
- this.mPercent = 0;
- this.mRate = 0;
- this.mBundle = null;
- this.mCancelDownloadOnClose = true;
- }
-
- const nsIProgressDialog = Components.interfaces.nsIProgressDialog;
-
- nsProgressDialog.prototype = {
- // Turn this on to get debugging messages.
- debug: false,
-
- // Chrome-related constants.
- dialogChrome: "chrome://global/content/nsProgressDialog.xul",
- dialogFeatures: "chrome,titlebar,minimizable=yes,dialog=no",
-
- // getters/setters
- get saving() { return this.MIMEInfo == null ||
- this.MIMEInfo.preferredAction == Components.interfaces.nsIMIMEInfo.saveToDisk; },
- get parent() { return this.mParent; },
- set parent(newval) { return this.mParent = newval; },
- get operation() { return this.mOperation; },
- set operation(newval) { return this.mOperation = newval; },
- get observer() { return this.mObserver; },
- set observer(newval) { return this.mObserver = newval; },
- get startTime() { return this.mStartTime; },
- set startTime(newval) { return this.mStartTime = newval/1000; }, // PR_Now() is in microseconds, so we convert.
- get lastUpdate() { return this.mLastUpdate; },
- set lastUpdate(newval) { return this.mLastUpdate = newval; },
- get interval() { return this.mInterval; },
- set interval(newval) { return this.mInterval = newval; },
- get elapsed() { return this.mElapsed; },
- set elapsed(newval) { return this.mElapsed = newval; },
- get loaded() { return this.mLoaded; },
- set loaded(newval) { return this.mLoaded = newval; },
- get source() { return this.mSource; },
- set source(newval) { return this.mSource = newval; },
- get target() { return this.mTarget; },
- set target(newval) { return this.mTarget = newval; },
- get MIMEInfo() { return this.mMIMEInfo; },
- set MIMEInfo(newval) { return this.mMIMEInfo = newval; },
- get dialog() { return this.mDialog; },
- set dialog(newval) { return this.mDialog = newval; },
- get displayName() { return this.mDisplayName; },
- set displayName(newval) { return this.mDisplayName = newval; },
- get paused() { return this.mPaused; },
- get request() { return this.mRequest; },
- set request(newval) { return this.mRequest = newval; },
- get completed() { return this.mCompleted; },
- get mode() { return this.mMode; },
- get percent() { return this.mPercent; },
- get rate() { return this.mRate; },
- get kRate() { return this.mRate / 1024; },
- get cancelDownloadOnClose() { return this.mCancelDownloadOnClose; },
- set cancelDownloadOnClose(newval) { return this.mCancelDownloadOnClose = newval; },
-
- // These setters use functions that update the dialog.
- set paused(newval) { return this.setPaused(newval); },
- set completed(newval) { return this.setCompleted(newval); },
- set mode(newval) { return this.setMode(newval); },
- set percent(newval) { return this.setPercent(newval); },
- set rate(newval) { return this.setRate(newval); },
-
- // ---------- nsIProgressDialog methods ----------
-
- // open: Store aParentWindow and open the dialog.
- open: function( aParentWindow ) {
- // Save parent and "persist" operation.
- this.parent = aParentWindow;
-
- // Open dialog using the WindowWatcher service.
- var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
- .getService( Components.interfaces.nsIWindowWatcher );
- this.dialog = ww.openWindow( this.parent,
- this.dialogChrome,
- null,
- this.dialogFeatures,
- this );
- },
-
- init: function( aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime, aOperation ) {
- this.source = aSource;
- this.target = aTarget;
- this.displayName = aDisplayName;
- this.MIMEInfo = aMIMEInfo;
- if ( aStartTime ) {
- this.startTime = aStartTime;
- }
- this.operation = aOperation;
- },
-
- // ---------- nsIWebProgressListener methods ----------
-
- // Look for STATE_STOP and update dialog to indicate completion when it happens.
- onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus ) {
- if ( aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP ) {
- // we are done downloading...
- this.completed = true;
- }
- },
-
- // Handle progress notifications.
- onProgressChange: function( aWebProgress,
- aRequest,
- aCurSelfProgress,
- aMaxSelfProgress,
- aCurTotalProgress,
- aMaxTotalProgress ) {
- // Remember the request; this will also initialize the pause/resume stuff.
- this.request = aRequest;
-
- var overallProgress = aCurTotalProgress;
-
- // Get current time.
- var now = ( new Date() ).getTime();
-
- // If interval hasn't elapsed, ignore it.
- if ( now - this.lastUpdate < this.interval &&
- aMaxTotalProgress != "-1" &&
- parseInt( aCurTotalProgress ) < parseInt( aMaxTotalProgress ) ) {
- return;
- }
-
- // Update this time.
- this.lastUpdate = now;
-
- // Update elapsed time.
- this.elapsed = now - this.startTime;
-
- // Calculate percentage.
- if ( aMaxTotalProgress > 0) {
- this.percent = Math.floor( ( overallProgress * 100.0 ) / aMaxTotalProgress );
- } else {
- this.percent = -1;
- }
-
- // If dialog not loaded, then don't bother trying to update display.
- if ( !this.loaded ) {
- return;
- }
-
- // Update dialog's display of elapsed time.
- this.setValue( "timeElapsed", this.formatSeconds( this.elapsed / 1000 ) );
-
- // 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 = this.getString( "progressMsg" );
-
- // Insert 1 is the number of kilobytes downloaded so far.
- status = this.replaceInsert( status, 1, parseInt( overallProgress/1024 + .5 ) );
-
- // Insert 2 is the total number of kilobytes to be downloaded (if known).
- if ( aMaxTotalProgress != "-1" ) {
- status = this.replaceInsert( status, 2, parseInt( aMaxTotalProgress/1024 + .5 ) );
- } else {
- status = this.replaceInsert( status, 2, "??" );
- }
-
- // Insert 3 is the download rate.
- if ( this.elapsed ) {
- this.rate = ( aCurTotalProgress * 1000 ) / this.elapsed;
- status = this.replaceInsert( status, 3, this.rateToKRate( this.rate ) );
- } else {
- // Rate not established, yet.
- status = this.replaceInsert( status, 3, "??.?" );
- }
-
- // All 3 inserts are taken care of, now update status msg.
- this.setValue( "status", status );
-
- // Update time remaining.
- if ( this.rate && ( aMaxTotalProgress > 0 ) ) {
- // Calculate how much time to download remaining at this rate.
- var rem = Math.round( ( aMaxTotalProgress - aCurTotalProgress ) / this.rate );
- this.setValue( "timeLeft", this.formatSeconds( rem ) );
- } else {
- // We don't know how much time remains.
- this.setValue( "timeLeft", this.getString( "unknownTime" ) );
- }
- },
-
- // Look for error notifications and display alert to user.
- onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) {
- // Check for error condition (only if dialog is still open).
- if ( aStatus != Components.results.NS_OK ) {
- if ( this.loaded ) {
- // Get prompt service.
- var prompter = Components.classes[ "@mozilla.org/embedcomp/prompt-service;1" ]
- .getService( Components.interfaces.nsIPromptService );
- // Display error alert (using text supplied by back-end).
- var title = this.getProperty( this.saving ? "savingAlertTitle" : "openingAlertTitle",
- [ this.fileName() ],
- 1 );
- prompter.alert( this.dialog, title, aMessage );
-
- // Close the dialog.
- if ( !this.completed ) {
- this.onCancel();
- }
- } else {
- // Error occurred prior to onload even firing.
- // We can't handle this error until we're done loading, so
- // defer the handling of this call.
- this.dialog.setTimeout( function(obj,wp,req,stat,msg){obj.onStatusChange(wp,req,stat,msg)},
- 100, this, aWebProgress, aRequest, aStatus, aMessage );
- }
- }
- },
-
- // Ignore onLocationChange and onSecurityChange notifications.
- onLocationChange: function( aWebProgress, aRequest, aLocation ) {
- },
-
- onSecurityChange: function( aWebProgress, aRequest, state ) {
- },
-
- // ---------- nsIObserver methods ----------
- observe: function( anObject, aTopic, aData ) {
- // Something of interest occured on the dialog.
- // Dispatch to corresponding implementation method.
- switch ( aTopic ) {
- case "onload":
- this.onLoad();
- break;
- case "oncancel":
- this.onCancel();
- break;
- case "onpause":
- this.onPause();
- break;
- case "onlaunch":
- this.onLaunch();
- break;
- case "onreveal":
- this.onReveal();
- break;
- case "onunload":
- this.onUnload();
- break;
- case "oncompleted":
- // This event comes in when setCompleted needs to be deferred because
- // the dialog isn't loaded yet.
- this.completed = true;
- break;
- default:
- break;
- }
- },
-
- // ---------- nsISupports methods ----------
-
- // This "class" supports nsIProgressDialog, nsIWebProgressListener (by virtue
- // of interface inheritance), nsIObserver, and nsISupports.
- QueryInterface: function (iid) {
- if (!iid.equals(Components.interfaces.nsIProgressDialog) &&
- !iid.equals(Components.interfaces.nsIDownload) &&
- !iid.equals(Components.interfaces.nsIWebProgressListener) &&
- !iid.equals(Components.interfaces.nsIObserver) &&
- !iid.equals(Components.interfaces.nsISupports)) {
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
- return this;
- },
-
- // ---------- implementation methods ----------
-
- // Initialize the dialog.
- onLoad: function() {
- // Note that onLoad has finished.
- this.loaded = true;
-
- // Fill dialog.
- this.loadDialog();
-
- // Position dialog.
- if ( this.dialog.opener ) {
- this.dialog.moveToAlertPosition();
- } else {
- this.dialog.centerWindowOnScreen();
- }
-
- // Set initial focus on "keep open" box. If that box is hidden, or, if
- // the download is already complete, then focus is on the cancel/close
- // button. The download may be complete if it was really short and the
- // dialog took longer to open than to download the data.
- if ( !this.completed && !this.saving ) {
- this.dialogElement( "keep" ).focus();
- } else {
- this.dialogElement( "cancel" ).focus();
- }
- },
-
- // load dialog with initial contents
- loadDialog: function() {
- // Check whether we're saving versus opening with a helper app.
- if ( !this.saving ) {
- // Put proper label on source field.
- this.setValue( "sourceLabel", this.getString( "openingSource" ) );
-
- // Target is the "preferred" application. Hide if empty.
- if ( this.MIMEInfo && this.MIMEInfo.preferredApplicationHandler ) {
- var appName = this.MIMEInfo.preferredApplicationHandler.leafName;
- if ( appName == null || appName.length == 0 ) {
- this.hide( "targetRow" );
- } else {
- // Use the "with:" label.
- this.setValue( "targetLabel", this.getString( "openingTarget" ) );
- // Name of application.
- this.setValue( "target", appName );
- }
- } else {
- this.hide( "targetRow" );
- }
- } else {
- // Target is the destination file.
- this.setValue( "target", this.target.path );
- }
-
- // Set source field.
- this.setValue( "source", this.source.spec );
-
- var now = ( new Date() ).getTime();
-
- // Intialize the elapsed time.
- if ( !this.elapsed ) {
- this.elapsed = now - this.startTime;
- }
-
- // Update elapsed time display.
- this.setValue( "timeElapsed", this.formatSeconds( this.elapsed / 1000 ) );
- this.setValue( "timeLeft", this.getString( "unknownTime" ) );
-
- // Initialize the "keep open" box. Hide this if we're opening a helper app.
- if ( !this.saving ) {
- // Hide this in this case.
- this.hide( "keep" );
- } else {
- // Initialize using last-set value from prefs.
- var prefs = Components.classes[ "@mozilla.org/preferences-service;1" ]
- .getService( Components.interfaces.nsIPrefBranch );
- if ( prefs ) {
- this.dialogElement( "keep" ).checked = prefs.getBoolPref( "browser.download.progressDnldDialog.keepAlive" );
- }
- }
-
- // Initialize title.
- this.setTitle();
- },
-
- // Cancel button stops the download (if not completed),
- // and closes the dialog.
- onCancel: function() {
- // Cancel the download, if not completed.
- if ( !this.completed ) {
- if ( this.operation ) {
- this.operation.cancelSave();
- // XXX We're supposed to clean up files/directories.
- }
- if ( this.observer ) {
- this.observer.observe( this, "oncancel", "" );
- }
- this.paused = false;
- }
- // Test whether the dialog is already closed.
- // This will be the case if we've come through onUnload.
- if ( this.dialog ) {
- // Close the dialog.
- this.dialog.close();
- }
- },
-
- // onunload event means the dialog has closed.
- // We go through our onCancel logic to stop the download if still in progress.
- onUnload: function() {
- // Remember "keep dialog open" setting, if visible.
- if ( this.saving ) {
- var prefs = Components.classes["@mozilla.org/preferences-service;1"]
- .getService( Components.interfaces.nsIPrefBranch );
- if ( prefs ) {
- prefs.setBoolPref( "browser.download.progressDnldDialog.keepAlive", this.dialogElement( "keep" ).checked );
- }
- }
- this.dialog = null; // The dialog is history.
- if ( this.mCancelDownloadOnClose ) {
- this.onCancel();
- }
- },
-
- // onpause event means the user pressed the pause/resume button
- // Toggle the pause/resume state (see the function setPause(), below).i
- onPause: function() {
- this.paused = !this.paused;
- },
-
- // onlaunch event means the user pressed the launch button
- // Invoke the launch method of the target file.
- onLaunch: function() {
- try {
- const kDontAskAgainPref = "browser.download.progressDnlgDialog.dontAskForLaunch";
- try {
- var pref = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- var dontAskAgain = pref.getBoolPref(kDontAskAgainPref);
- } catch (e) {
- // we need to ask if we're unsure
- dontAskAgain = false;
- }
- if ( !dontAskAgain && this.target.isExecutable() ) {
- try {
- var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService( Components.interfaces.nsIPromptService );
- } catch (ex) {
- // getService doesn't return null, it throws
- return;
- }
- var title = this.getProperty( "openingAlertTitle",
- [ this.fileName() ],
- 1 );
- var msg = this.getProperty( "securityAlertMsg",
- [ this.fileName() ],
- 1 );
- var dontaskmsg = this.getProperty( "dontAskAgain",
- [ ], 0 );
- var checkbox = {value:0};
- var okToProceed = promptService.confirmCheck(this.dialog, title, msg, dontaskmsg, checkbox);
- try {
- if (checkbox.value != dontAskAgain)
- pref.setBoolPref(kDontAskAgainPref, checkbox.value);
- } catch (ex) {}
-
- if ( !okToProceed )
- return;
- }
- this.target.launch();
- this.dialog.close();
- } catch ( exception ) {
- // XXX Need code here to tell user the launch failed!
- dump( "nsProgressDialog::onLaunch failed: " + exception + "\n" );
- }
- },
-
- // onreveal event means the user pressed the "reveal location" button
- // Invoke the reveal method of the target file.
- onReveal: function() {
- try {
- this.target.reveal();
- this.dialog.close();
- } catch ( exception ) {
- }
- },
-
- // Get filename from target file.
- fileName: function() {
- return this.target ? this.target.leafName : "";
- },
-
- // Set the dialog title.
- setTitle: function() {
- // Start with saving/opening template.
- // If percentage is not known (-1), use alternate template
- var title = this.saving
- ? ( this.percent != -1 ? this.getString( "savingTitle" ) : this.getString( "unknownSavingTitle" ) )
- : ( this.percent != -1 ? this.getString( "openingTitle" ) : this.getString( "unknownOpeningTitle" ) );
-
-
- // Use file name as insert 1.
- title = this.replaceInsert( title, 1, this.fileName() );
-
- // Use percentage as insert 2 (if known).
- if ( this.percent != -1 ) {
- title = this.replaceInsert( title, 2, this.percent );
- }
-
- // Set <window>'s title attribute.
- if ( this.dialog ) {
- this.dialog.title = title;
- }
- },
-
- // Update the dialog to indicate specified percent complete.
- setPercent: function( percent ) {
- // Maximum percentage is 100.
- if ( percent > 100 ) {
- percent = 100;
- }
- // Test if percentage is changing.
- if ( this.percent != percent ) {
- this.mPercent = percent;
-
- // If dialog not opened yet, bail early.
- if ( !this.loaded ) {
- return this.mPercent;
- }
-
- if ( percent == -1 ) {
- // Progress meter needs to be in "undetermined" mode.
- this.mode = "undetermined";
-
- // Update progress meter percentage text.
- this.setValue( "progressText", "" );
- } else {
- // Progress meter needs to be in normal mode.
- this.mode = "normal";
-
- // Set progress meter thermometer.
- this.setValue( "progress", percent );
-
- // Update progress meter percentage text.
- this.setValue( "progressText", this.replaceInsert( this.getString( "percentMsg" ), 1, percent ) );
- }
-
- // Update title.
- this.setTitle();
- }
- return this.mPercent;
- },
-
- // Update download rate and dialog display.
- // Note that we don't want the displayed value to quiver
- // between essentially identical values (e.g., 99.9Kb and
- // 100.0Kb) so we only update if we see a big change.
- setRate: function( rate ) {
- if ( rate ) {
- // rate is bytes/sec
- var change = Math.abs( this.rate - rate );
- // Don't update too often!
- if ( change > this.rate / 10 ) {
- // Displayed rate changes.
- this.mRate = rate;
- }
- }
- return this.mRate;
- },
-
- // Handle download completion.
- setCompleted: function() {
- // If dialog hasn't loaded yet, defer this.
- if ( !this.loaded ) {
- this.dialog.setTimeout( function(obj){obj.setCompleted()}, 100, this );
- return false;
- }
- if ( !this.mCompleted ) {
- this.mCompleted = true;
-
- // If the "keep dialog open" box is checked, then update dialog.
- if ( this.dialog && this.dialogElement( "keep" ).checked ) {
- // Indicate completion in status area.
- var string = this.getString( "completeMsg" );
- string = this.replaceInsert( string,
- 1,
- this.formatSeconds( this.elapsed/1000 ) );
- string = this.replaceInsert( string,
- 2,
- this.target.fileSize >> 10 );
-
- this.setValue( "status", string);
- // Put progress meter at 100%.
- this.percent = 100;
-
- // Set time remaining to 00:00.
- this.setValue( "timeLeft", this.formatSeconds( 0 ) );
-
- // Change Cancel button to Close, and give it focus.
- var cancelButton = this.dialogElement( "cancel" );
- cancelButton.label = this.getString( "close" );
- cancelButton.focus();
-
- // Activate reveal/launch buttons if we enable them.
- var enableButtons = true;
- try {
- var prefs = Components.classes[ "@mozilla.org/preferences-service;1" ]
- .getService( Components.interfaces.nsIPrefBranch );
- enableButtons = prefs.getBoolPref( "browser.download.progressDnldDialog.enable_launch_reveal_buttons" );
- } catch ( e ) {
- }
-
- if ( enableButtons ) {
- this.enable( "reveal" );
- try {
- if ( this.target ) {
- this.enable( "launch" );
- }
- } catch(e) {
- }
- }
-
- // Disable the Pause/Resume buttons.
- this.dialogElement( "pauseResume" ).disabled = true;
-
- // Fix up dialog layout (which gets messed up sometimes).
- this.dialog.sizeToContent();
-
- // GetAttention to show the user that we're done
- this.dialog.getAttention();
- } else if ( this.dialog ) {
- this.dialog.close();
- }
- }
- return this.mCompleted;
- },
-
- // Set progress meter to given mode ("normal" or "undetermined").
- setMode: function( newMode ) {
- if ( this.mode != newMode ) {
- // Need to update progress meter.
- this.dialogElement( "progress" ).setAttribute( "mode", newMode );
- }
- return this.mMode = newMode;
- },
-
- // Set pause/resume state.
- setPaused: function( pausing ) {
- // If state changing, then update stuff.
- if ( this.paused != pausing ) {
- var string = pausing ? "resume" : "pause";
- this.dialogElement( "pauseResume" ).label = this.getString(string);
-
- // If we have a request, suspend/resume it.
- if ( this.request ) {
- if ( pausing ) {
- this.request.suspend();
- } else {
- this.request.resume();
- }
- }
- }
- return this.mPaused = pausing;
- },
-
- // Convert raw rate (bytes/sec) to Kbytes/sec (to nearest tenth).
- rateToKRate: function( rate ) {
- return ( rate / 1024 ).toFixed(1);
- },
-
- // Format number of seconds in hh:mm:ss form.
- formatSeconds: function( secs ) {
- // 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 = this.getString( "longTimeFormat" );
- else
- result = this.getString( "shortTimeFormat" );
-
- 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 = this.replaceInsert( result, 1, hours );
- result = this.replaceInsert( result, 2, mins );
- result = this.replaceInsert( result, 3, secs );
-
- return result;
- },
-
- // Get dialog element using argument as id.
- dialogElement: function( id ) {
- // Check if we've already fetched it.
- if ( !( id in this.fields ) ) {
- // No, then get it from dialog.
- try {
- this.fields[ id ] = this.dialog.document.getElementById( id );
- } catch(e) {
- this.fields[ id ] = {
- value: "",
- setAttribute: function(id,val) {},
- removeAttribute: function(id) {}
- }
- }
- }
- return this.fields[ id ];
- },
-
- // Set dialog element value for given dialog element.
- setValue: function( id, val ) {
- this.dialogElement( id ).value = val;
- },
-
- // Enable dialgo element.
- enable: function( field ) {
- this.dialogElement( field ).removeAttribute( "disabled" );
- },
-
- // Get localizable string from properties file.
- getProperty: function( propertyId, strings, len ) {
- if ( !this.mBundle ) {
- this.mBundle = Components.classes[ "@mozilla.org/intl/stringbundle;1" ]
- .getService( Components.interfaces.nsIStringBundleService )
- .createBundle( "chrome://global/locale/nsProgressDialog.properties");
- }
- return this.mBundle.formatStringFromName( propertyId, strings, len );
- },
-
- // Get localizable string (from dialog <data> elements).
- getString: function ( stringId ) {
- // Check if we've fetched this string already.
- if ( !( this.strings && stringId in this.strings ) ) {
- // Presume the string is empty if we can't get it.
- this.strings[ stringId ] = "";
- // Try to get it.
- try {
- this.strings[ stringId ] = this.dialog.document.getElementById( "string."+stringId ).childNodes[0].nodeValue;
- } catch (e) {}
- }
- return this.strings[ stringId ];
- },
-
- // Replaces insert ("#n") with input text.
- replaceInsert: function( text, index, value ) {
- var result = text;
- var regExp = new RegExp( "#"+index );
- result = result.replace( regExp, value );
- return result;
- },
-
- // Hide a given dialog field.
- hide: function( field ) {
- this.dialogElement( field ).setAttribute( "style", "display: none;" );
- // Hide the associated separator, too.
- this.dialogElement( field+"Separator" ).setAttribute( "style", "display: none;" );
- },
-
- // Return input in hex, prepended with "0x" and leading zeros (to 8 digits).
- hex: function( x ) {
- var hex = Number(x).toString(16);
- return "0x" + ( "00000000" + hex ).substring( hex.length );
- },
-
- // Dump text (if debug is on).
- dump: function( text ) {
- if ( this.debug ) {
- dump( text );
- }
- }
- }
-
- // This Component's module implementation. All the code below is used to get this
- // component registered and accessible via XPCOM.
- var module = {
- // registerSelf: Register this component.
- registerSelf: function (compMgr, fileSpec, location, type) {
- var compReg = compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
- compReg.registerFactoryLocation( this.cid,
- "Mozilla Download Progress Dialog",
- this.contractId,
- fileSpec,
- location,
- type );
- },
-
- // getClassObject: Return this component's factory object.
- getClassObject: function (compMgr, cid, iid) {
- if (!cid.equals(this.cid))
- throw Components.results.NS_ERROR_NO_INTERFACE;
-
- if (!iid.equals(Components.interfaces.nsIFactory))
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
- return this.factory;
- },
-
- /* CID for this class */
- cid: Components.ID("{F5D248FD-024C-4f30-B208-F3003B85BC92}"),
-
- /* Contract ID for this class */
- contractId: "@mozilla.org/progressdialog;1",
-
- /* factory object */
- factory: {
- // createInstance: Return a new nsProgressDialog object.
- createInstance: function (outer, iid) {
- if (outer != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return (new nsProgressDialog()).QueryInterface(iid);
- }
- },
-
- // canUnload: n/a (returns true)
- canUnload: function(compMgr) {
- return true;
- }
- };
-
- // NSGetModule: Return the nsIModule object.
- function NSGetModule(compMgr, fileSpec) {
- return module;
- }
-