First part of bug 214260 work... teaching the download manager about XPInstall downloads, and providing an updated XPInstall confirmation dialog.

This commit is contained in:
ben%bengoodger.com 2003-12-08 08:05:15 +00:00
Родитель cbb5c411b3
Коммит 6a6f1609ff
23 изменённых файлов: 738 добавлений и 902 удалений

Просмотреть файл

@ -41,6 +41,9 @@
// pref("startup.homepage_override_url","chrome://browser-region/locale/region.properties");
pref("browser.chromeURL","chrome://browser/content/");
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
pref("xpinstall.dialog.progress", "chrome://mozapps/content/downloads/downloads.xul");
pref("xpinstall.dialog.progress.type", "Download:Manager");
pref("keyword.enabled", true);
pref("keyword.URL", "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&ie=UTF-8&oe=UTF-8&q=");

Просмотреть файл

@ -41,6 +41,9 @@
// pref("startup.homepage_override_url","chrome://browser-region/locale/region.properties");
pref("browser.chromeURL","chrome://browser/content/");
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
pref("xpinstall.dialog.progress", "chrome://mozapps/content/downloads/downloads.xul");
pref("xpinstall.dialog.progress.type", "Download:Manager");
pref("keyword.enabled", true);
pref("keyword.URL", "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&ie=UTF-8&oe=UTF-8&q=");

Просмотреть файл

@ -132,7 +132,7 @@
<command id="Tools:Downloads" oncommand="toOpenWindowByType('Download:Manager',
'chrome://mozapps/content/downloads/downloads.xul',
'chrome,all,dialog=no,resizable');"/>
'chrome,dialog=no,resizable');"/>
#ifdef XP_MACOSX
<command id="minimizeWindow" label="&minimizeWindow.label;" disabled="true"/>

Просмотреть файл

@ -1112,7 +1112,7 @@ nsDownloadManager::OpenDownloadManager(PRBool aShouldFocus, nsIDownload* aDownlo
rv = ww->OpenWindow(aParent,
DOWNLOAD_MANAGER_FE_URL,
"_blank",
"chrome,all,dialog=no,resizable",
"chrome,dialog=no,resizable",
params,
getter_AddRefs(newWindow));
}

Просмотреть файл

@ -42,7 +42,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = downloads
DIRS = downloads xpinstall
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
# XXXben this is temporary, until Thunderbird is converted to Pinstripe on MacOS X. For now,

Просмотреть файл

@ -49,6 +49,14 @@ var gDownloadsView = null;
var gUserInterfered = false;
var gActiveDownloads = [];
// This variable exists because for XPInstalls, we don't want to close the
// download manager until the XPInstallManager sends the DIALOG_CLOSE status
// message. Setting this variable to false when the downloads window is
// opened by the xpinstall manager prevents the window from being closed after
// each download completes (because xpinstall downloads are done sequentially,
// not concurrently)
var gCanAutoClose = true;
///////////////////////////////////////////////////////////////////////////////
// Utility Functions
function setRDFProperty(aID, aProperty, aValue)
@ -157,7 +165,8 @@ function autoClose(aDownload)
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var autoClose = pref.getBoolPref(PREF_BDM_CLOSEWHENDONE)
if (autoClose && (!window.opener || window.opener.location.href == window.location.href))
if (autoClose && (!window.opener || window.opener.location.href == window.location.href) &&
gCanAutoClose)
gCloseDownloadManager();
}
}
@ -172,23 +181,31 @@ function gCloseDownloadManager()
var gDownloadObserver = {
observe: function (aSubject, aTopic, aState)
{
var dl = aSubject.QueryInterface(Components.interfaces.nsIDownload);
switch (aTopic) {
case "dl-done":
var dl = aSubject.QueryInterface(Components.interfaces.nsIDownload);
downloadCompleted(dl);
autoClose(dl);
break;
case "dl-failed":
case "dl-cancel":
var dl = aSubject.QueryInterface(Components.interfaces.nsIDownload);
downloadCompleted(dl);
break;
case "dl-start":
// Add this download to the percentage average tally
var dl = aSubject.QueryInterface(Components.interfaces.nsIDownload);
gActiveDownloads.push(dl);
break;
case "xpinstall-download-started":
var windowArgs = aSubject.QueryInterface(Components.interfaces.nsISupportsArray);
var params = windowArgs.QueryElementAt(0, Components.interfaces.nsISupportsInterfacePointer);
params = params.data.QueryInterface(Components.interfaces.nsIDialogParamBlock);
var installObserver = windowArgs.QueryElementAt(1, Components.interfaces.nsISupportsInterfacePointer);
installObserver = installObserver.data.QueryInterface(Components.interfaces.nsIObserver);
XPInstallDownloadManager.addDownloads(params, installObserver);
break;
}
}
};
@ -418,6 +435,18 @@ function Startup()
observerService.addObserver(gDownloadObserver, "dl-cancel", false);
observerService.addObserver(gDownloadObserver, "dl-failed", false);
observerService.addObserver(gDownloadObserver, "dl-start", false);
observerService.addObserver(gDownloadObserver, "xpinstall-download-started", false);
// Now look and see if we're being opened by XPInstall
if ("arguments" in window) {
try {
var params = window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock);
var installObserver = window.arguments[1].QueryInterface(Components.interfaces.nsIObserver);
gCanAutoClose = false;
XPInstallDownloadManager.addDownloads(params, installObserver);
}
catch (e) { }
}
// This is for the "Clean Up" button, which requires there to be
// non-active downloads before it can be enabled.
@ -443,8 +472,134 @@ function Shutdown()
observerService.removeObserver(gDownloadObserver, "dl-cancel");
observerService.removeObserver(gDownloadObserver, "dl-failed");
observerService.removeObserver(gDownloadObserver, "dl-start");
observerService.removeObserver(gDownloadObserver, "xpinstall-download-started");
}
///////////////////////////////////////////////////////////////////////////////
// XPInstall
var XPInstallDownloadManager = {
_XPInstallDownloads: [],
_XPInstallProgressListener: null,
init: function ()
{
this._XPInstallProgressListener = new XPInstallProgressListener(this._XPInstallDownloads);
},
addDownloads: function (aParams, aObserver)
{
var numXPInstallItems = aParams.GetInt(1);
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var tempDir = fileLocator.get("TmpD", Components.interfaces.nsIFile);
var mimeService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"].getService(Components.interfaces.nsIMIMEService);
var xpiString = "";
for (var i = 0; i < numXPInstallItems;) {
// Pretty Name
var displayName = aParams.GetString(i++);
// URI
var uri = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIURI);
uri.spec = aParams.GetString(i++);
var iconURL = aParams.GetString(i++);
// Local File Target
var url = uri.QueryInterface(Components.interfaces.nsIURL);
var localTarget = tempDir.clone();
localTarget.append(url.fileName);
xpiString += localTarget.path + ",";
// MIME Info
var mimeInfo = mimeService.getFromTypeAndExtension(null, url.fileExtension);
var download = gDownloadManager.addDownload(uri, localTarget, displayName, mimeInfo, 0, null);
this._XPInstallDownloads.push(download);
// Advance the enumerator
var certName = aParams.GetString(i++);
}
// Store the list of things we're downloading so we can reinitialize the FE
// properly if the window is closed and then reopened.
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var str = Components.classes["@mozilla.org/pref-localizedstring;1"].createInstance(Components.interfaces.nsIPrefLocalizedString);
str.data = xpiString;
pref.setComplexValue(PREF_BDM_CLOSEWHENDONE, Components.interfaces.nsIPrefLocalizedString, str);
aObserver.observe(this._XPInstallProgressListener, "xpinstall-progress", "open");
}
}
function XPInstallProgressListener(aDownloads)
{
this._XPInstallDownloads = aDownloads;
}
// implements nsIXPIProgressDialog
XPInstallProgressListener.prototype = {
onStateChange: function (aIndex, aState, aValue)
{
const nsIXPIPD = Components.interfaces.nsIXPIProgressDialog;
const nsIWPL = Components.interfaces.nsIWebProgressListener;
var wpl = this._XPInstallDownloads[aIndex].QueryInterface(nsIWPL);
switch (aState) {
case nsIXPIPD.DOWNLOAD_START:
wpl.onStateChange(null, null, nsIWPL.STATE_START, 0);
break;
case nsIXPIPD.DOWNLOAD_DONE:
break;
case nsIXPIPD.INSTALL_START:
break;
case nsIXPIPD.INSTALL_DONE:
wpl.onStateChange(null, null, nsIWPL.STATE_STOP, 0);
break;
case nsIXPIPD.DIALOG_CLOSE:
// Close now, if we're allowed to.
gCanAutoClose = true;
var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
var brandBundle = sbs.createBundle("chrome://global/locale/brand.properties");
var xpinstallBundle = sbs.createBundle("chrome://mozapps/locale/xpinstall/xpinstallConfirm.properties");
var brandShortName = brandBundle.GetStringFromName("brandShortName");
var message = xpinstallBundle.formatStringFromName("installComplete", [brandShortName], 1);
var title = xpinstallBundle.GetStringFromName("installCompleteTitle");
var promptSvc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
promptSvc.alert(null, title, message);
autoClose();
break;
}
},
onProgress: function (aIndex, aValue, aMaxValue)
{
const nsIWPL = Components.interfaces.nsIWebProgressListener;
var wpl = this._XPInstallDownloads[aIndex].QueryInterface(nsIWPL);
wpl.onProgressChange(null, null, 0, 0, aValue, aMaxValue);
},
QueryInterface: function( iid )
{
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIXPIProgressDialog))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
///////////////////////////////////////////////////////////////////////////////
// View Context Menus
var gContextMenus = [

Просмотреть файл

@ -1,893 +0,0 @@
/*
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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.org Code.
#
# The Initial Developer of the Original Code is
# Doron Rosenberg.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Bill Law <law@netscape.com>
# Scott MacGregor <mscott@netscape.com>
# Ben Goodger <ben@bengoodger.com> (2.0)
#
# 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 nsIHelperAppLauncherDialog interface.
*
* The implementation consists of a JavaScript "class" named nsUnknownContentTypeDialog,
* 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
* nsUnknownContentTypeDialog component.
*/
/* ctor
*/
function nsUnknownContentTypeDialog() {
// Initialize data properties.
this.mLauncher = null;
this.mContext = null;
this.mSourcePath = null;
this.chosenApp = null;
this.givenDefaultApp = false;
this.updateSelf = true;
this.mTitle = "";
}
nsUnknownContentTypeDialog.prototype = {
nsIMIMEInfo : Components.interfaces.nsIMIMEInfo,
// This "class" supports nsIHelperAppLauncherDialog, and nsISupports.
QueryInterface: function (iid) {
if (!iid.equals(Components.interfaces.nsIHelperAppLauncherDialog) &&
!iid.equals(Components.interfaces.nsISupports)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
// ---------- nsIHelperAppLauncherDialog methods ----------
// show: Open XUL dialog using window watcher. Since the dialog is not
// modal, it needs to be a top level window and the way to open
// one of those is via that route).
show: function(aLauncher, aContext) {
this.mLauncher = aLauncher;
this.mContext = aContext;
// Display the dialog using the Window Watcher interface.
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
this.mDialog = ww.openWindow(null, // no parent
"chrome://mozapps/content/downloads/unknownContentType.xul",
null,
"chrome,centerscreen,titlebar,dialog=yes",
null);
// Hook this object to the dialog.
this.mDialog.dialog = this;
// Hook up utility functions.
// XXXben these lines can disappear if we can get XULPP to run on stuff not
// thus referenced in jar.mns.
this.getSpecialFolderKey = this.mDialog.getSpecialFolderKey;
// Watch for error notifications.
this.progressListener.helperAppDlg = this;
this.mLauncher.setWebProgressListener(this.progressListener);
},
// promptForSaveToFile: Display file picker dialog and return selected file.
// This is called by the External Helper App Service
// after the ucth dialog calls |saveToDisk| with a null
// target filename (no target, therefore user must pick).
//
// Alternatively, if the user has selected to have all
// files download to a specific location, return that
// location and don't ask via the dialog.
//
// Note - this function is called without a dialog, so it cannot access any part
// of the dialog XUL as other functions on this object do.
promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension) {
var result = "";
this.mLauncher = aLauncher;
// If the user is always downloading to the same location, the default download
// folder is stored in preferences. If a value is found stored, use that
// automatically and don't ask via a dialog.
const kDownloadFolderPref = "browser.download.defaultFolder";
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
try {
result = prefs.getComplexValue(kDownloadFolderPref, Components.interfaces.nsILocalFile);
result = this.validateLeafName(result, aDefaultFile);
}
catch (e) {
// If we get here, it's because we have a new profile and the user has never configured download
// options, so "browser.download.defaultFolder" is not set yet. If the default is autodownload,
// we need to discover the default save location.
var autodownload = prefs.getBoolPref("browser.download.useDownloadDir");
if (autodownload) {
// XXXben we should really have a way of using XULPP on JS component files.
// This code is very similar to that in pref-downloads.js, except the platform
// checks are done at runtime. ugh.
function getSpecialFolderKey(aFolderType)
{
#ifdef XP_WIN
return aFolderType == "Desktop" ? "DeskV" : "Pers";
#else
#ifdef XP_MACOSX
return aFolderType == "Desktop" ? "UsrDsk" : "UsrDocs";
#else
return "Home";
#endif
#endif
}
function getDownloadsFolder(aFolder)
{
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var dir = fileLocator.get(getSpecialFolderKey(aFolder), Components.interfaces.nsILocalFile);
var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
var description = bundle.GetStringFromName("myDownloads");
if (aFolder != "Desktop")
dir.append(description);
return dir;
}
var defaultFolder = null;
switch (prefs.getIntPref("browser.download.folderList")) {
case 0:
defaultFolder = getDownloadsFolder("Desktop")
break;
case 1:
defaultFolder = getDownloadsFolder("Downloads");
break;
case 2:
defaultFolder = prefs.getComplexValue("browser.download.dir", Components.interfaces.nsILocalFile);
break;
}
// While we're here, set the pref too so that we don't keep coming back into this less efficient
// code block.
prefs.setComplexValue("browser.download.defaultFolder", Components.interfaces.nsILocalFile, defaultFolder);
result = this.validateLeafName(defaultFolder, aDefaultFile);
}
}
if (!result) {
// Use file picker to show dialog.
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
var windowTitle = bundle.GetStringFromName("saveDialogTitle");
var parent = aContext.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowInternal);
picker.init(parent, windowTitle, nsIFilePicker.modeSave);
picker.defaultString = aDefaultFile;
if (aSuggestedFileExtension) {
// aSuggestedFileExtension includes the period, so strip it
picker.defaultExtension = aSuggestedFileExtension.substring(1);
}
else {
try {
picker.defaultExtension = this.mLauncher.MIMEInfo.primaryExtension;
}
catch (ex) { }
}
var wildCardExtension = "*";
if (aSuggestedFileExtension) {
wildCardExtension += aSuggestedFileExtension;
picker.appendFilter(this.mLauncher.MIMEInfo.Description, wildCardExtension);
}
picker.appendFilters( nsIFilePicker.filterAll );
// Pull in the user's preferences and get the default download directory.
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
try {
var startDir = prefs.getComplexValue("browser.download.dir", Components.interfaces.nsILocalFile);
if (startDir.exists()) {
picker.displayDirectory = startDir;
}
}
catch(exception) { }
var dlgResult = picker.show();
if (dlgResult == nsIFilePicker.returnCancel) {
// null result means user cancelled.
return null;
}
// Be sure to save the directory the user chose through the Save As...
// dialog as the new browser.download.dir
result = picker.file;
if (result) {
var newDir = result.parent;
prefs.setComplexValue("browser.download.dir", Components.interfaces.nsILocalFile, newDir);
}
}
return result;
},
validateLeafName: function (aLocalFile, aLeafName)
{
aLocalFile.append(aLeafName);
// Since we're automatically downloading, we don't get the file picker's
// logic to check for existing files, so we need to do that here.
//
// Note - this code is identical to that in
// browser/base/content/contentAreaUtils.js.
// If you are updating this code, update that code too! We can't share code
// here since this is called in a js component.
while (aLocalFile.exists()) {
var parts = /.+-(\d+)(\..*)?$/.exec(aLocalFile.leafName);
if (parts) {
aLocalFile.leafName = aLocalFile.leafName.replace(/((\d+)\.)/,
function (str, p1, part, s) {
return (parseInt(part) + 1) + ".";
});
}
else {
aLocalFile.leafName = aLocalFile.leafName.replace(/\./, "-1$&");
}
}
return aLocalFile;
},
// ---------- implementation methods ----------
// Web progress listener so we can detect errors while mLauncher is
// streaming the data to a temporary file.
progressListener: {
// Implementation properties.
helperAppDlg: null,
// nsIWebProgressListener methods.
// Look for error notifications and display alert to user.
onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) {
if ( aStatus != Components.results.NS_OK ) {
// 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).
prompter.alert( this.dialog, this.helperAppDlg.mTitle, aMessage );
// Close the dialog.
this.helperAppDlg.onCancel();
if ( this.helperAppDlg.mDialog ) {
this.helperAppDlg.mDialog.close();
}
}
},
// Ignore onProgressChange, onStateChange, onLocationChange, and onSecurityChange notifications.
onProgressChange: function( aWebProgress,
aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress ) {
},
onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus ) {
},
onLocationChange: function( aWebProgress, aRequest, aLocation ) {
},
onSecurityChange: function( aWebProgress, aRequest, state ) {
}
},
// initDialog: Fill various dialog fields with initial content.
initDialog : function() {
// Put file name in window title.
var win = this.dialogElement( "unknownContentType" );
var suggestedFileName = this.mLauncher.suggestedFileName;
// Some URIs do not implement nsIURL, so we can't just QI.
var url = this.mLauncher.source;
var fname = "";
this.mSourcePath = url.prePath;
try {
url = url.QueryInterface( Components.interfaces.nsIURL );
// A url, use file name from it.
fname = url.fileName;
this.mSourcePath += url.directory;
} catch (ex) {
// A generic uri, use path.
fname = url.path;
this.mSourcePath += url.path;
}
if (suggestedFileName)
fname = suggestedFileName;
this.mTitle = this.dialogElement("strings").getFormattedString("title", [fname]);
win.setAttribute( "title", this.mTitle );
// Put content type, filename and location into intro.
this.initIntro(url, fname);
var iconString = "moz-icon://" + fname + "?size=16&contentType=" + this.mLauncher.MIMEInfo.MIMEType;
this.dialogElement("contentTypeImage").setAttribute("src", iconString);
this.initAppAndSaveToDiskValues();
// Initialize "always ask me" box. This should always be disabled
// and set to true for the ambiguous type application/octet-stream.
// We don't also check for application/x-msdownload here since we
// want users to be able to autodownload .exe files.
var rememberChoice = this.dialogElement("rememberChoice");
if (this.mLauncher.MIMEInfo.MIMEType == "application/octet-stream") {
rememberChoice.checked = false;
rememberChoice.disabled = true;
}
else {
rememberChoice.checked = !this.mLauncher.MIMEInfo.alwaysAskBeforeHandling;
}
this.toggleRememberChoice(rememberChoice);
// XXXben - menulist won't init properly, hack.
var openHandler = this.dialogElement("openHandler");
openHandler.parentNode.removeChild(openHandler);
var openParent = this.dialogElement("open").parentNode;
openParent.appendChild(openHandler);
this.mDialog.setTimeout("dialog.postShowCallback()", 0);
},
postShowCallback: function () {
this.mDialog.sizeToContent();
// Set initial focus
this.dialogElement("mode").focus();
},
// initIntro:
initIntro: function(url, filename) {
this.dialogElement( "location" ).value = filename;
// if mSourcePath is a local file, then let's use the pretty path name instead of an ugly
// url...
var pathString = this.mSourcePath;
try
{
var fileURL = url.QueryInterface(Components.interfaces.nsIFileURL);
if (fileURL)
{
var fileObject = fileURL.file;
if (fileObject)
{
var parentObject = fileObject.parent;
if (parentObject)
{
pathString = parentObject.path;
}
}
}
} catch(ex) {}
// Set the location text, which is separate from the intro text so it can be cropped
var location = this.dialogElement( "source" );
location.value = pathString;
// Show the type of file.
var type = this.dialogElement("type");
var mimeInfo = this.mLauncher.MIMEInfo;
// 1. Try to use the pretty description of the type, if one is available.
var typeString = mimeInfo.Description;
if (typeString == "") {
// 2. If there is none, use the extension to identify the file, e.g. "ZIP file"
var primaryExtension = "";
try {
primaryExtension = mimeInfo.primaryExtension;
}
catch (ex) {
}
if (primaryExtension != "")
typeString = primaryExtension.toUpperCase() + " file";
// 3. If we can't even do that, just give up and show the MIME type.
else
typeString = mimeInfo.MIMEType;
}
type.value = typeString;
},
// Returns true if opening the default application makes sense.
openWithDefaultOK: function() {
var result;
// The checking is different on Windows...
#ifdef XP_WIN
// Windows presents some special cases.
// We need to prevent use of "system default" when the file is
// executable (so the user doesn't launch nasty programs downloaded
// from the web), and, enable use of "system default" if it isn't
// executable (because we will prompt the user for the default app
// in that case).
// Need to get temporary file and check for executable-ness.
var tmpFile = this.mLauncher.targetFile;
// Default is Ok if the file isn't executable (and vice-versa).
return !tmpFile.isExecutable();
#else
// On other platforms, default is Ok if there is a default app.
// Note that nsIMIMEInfo providers need to ensure that this holds true
// on each platform.
return this.mLauncher.MIMEInfo.defaultApplicationHandler;
#endif
},
// Set "default" application description field.
initDefaultApp: function() {
// Use description, if we can get one.
var desc = this.mLauncher.MIMEInfo.defaultDescription;
if (desc) {
var defaultApp = this.dialogElement("strings").getFormattedString("defaultApp", [desc]);
this.dialogElement("defaultHandler").label = defaultApp;
}
},
// getPath:
getPath: function (aFile) {
#ifdef XP_MACOSX
return aFile.leafName || aFile.path;
#else
return aFile.path;
#endif
},
// initAppAndSaveToDiskValues:
initAppAndSaveToDiskValues: function() {
var modeGroup = this.dialogElement("mode");
// We don't let users open .exe files or random binary data directly
// from the browser at the moment because of security concerns.
var openWithDefaultOK = this.openWithDefaultOK();
var mimeType = this.mLauncher.MIMEInfo.MIMEType;
if ((mimeType == "application/octet-stream" ||
mimeType == "application/x-msdownload") && !openWithDefaultOK) {
this.dialogElement("open").disabled = true;
var openHandler = this.dialogElement("openHandler");
openHandler.disabled = true;
openHandler.label = "";
modeGroup.selectedItem = this.dialogElement("save");
return;
}
// Fill in helper app info, if there is any.
this.chosenApp = this.mLauncher.MIMEInfo.preferredApplicationHandler;
// Initialize "default application" field.
this.initDefaultApp();
var otherHandler = this.dialogElement("otherHandler");
// Fill application name textbox.
if (this.chosenApp && this.chosenApp.path) {
otherHandler.setAttribute("path", this.getPath(this.chosenApp));
otherHandler.label = this.chosenApp.leafName;
otherHandler.hidden = false;
}
var useDefault = this.dialogElement("useSystemDefault");
var openHandler = this.dialogElement("openHandler");
openHandler.selectedIndex = 0;
if (this.mLauncher.MIMEInfo.preferredAction == this.nsIMIMEInfo.useSystemDefault) {
// Open (using system default).
modeGroup.selectedItem = this.dialogElement("open");
} else if (this.mLauncher.MIMEInfo.preferredAction == this.nsIMIMEInfo.useHelperApp) {
// Open with given helper app.
modeGroup.selectedItem = this.dialogElement("open");
openHandler.selectedIndex = 1;
} else {
// Save to disk.
modeGroup.selectedItem = this.dialogElement("save");
}
// If we don't have a "default app" then disable that choice.
if (!openWithDefaultOK) {
var useDefault = this.dialogElement("defaultHandler");
var isSelected = useDefault.selected;
// Disable that choice.
useDefault.hidden = true;
// If that's the default, then switch to "save to disk."
if (isSelected) {
openHandler.selectedIndex = 1;
modeGroup.selectedItem = this.dialogElement("save");
}
}
// otherHandler is always disabled on Mac
#ifdef XP_MACOSX
otherHandler.hidden = true;
otherHandler.nextSibling.hidden = otherHandler.nextSibling.nextSibling.hidden = true;
#else
otherHandler.nextSibling.hidden = otherHandler.nextSibling.nextSibling.hidden = false;
#endif
this.updateOKButton();
},
// Returns the user-selected application
helperAppChoice: function() {
return this.chosenApp;
},
get saveToDisk() {
return this.dialogElement("save").selected;
},
get useOtherHandler() {
return this.dialogElement("open").selected && this.dialogElement("openHandler").selectedIndex == 1;
},
get useSystemDefault() {
return this.dialogElement("open").selected && this.dialogElement("openHandler").selectedIndex == 0;
},
toggleRememberChoice: function (aCheckbox) {
this.dialogElement("settingsChange").hidden = !aCheckbox.checked;
this.mDialog.sizeToContent();
},
openHandlerCommand: function () {
if (this.dialogElement("openHandler").selectedItem.id == "choose")
this.chooseApp();
},
updateOKButton: function() {
var ok = false;
if (this.dialogElement("save").selected) {
// This is always OK.
ok = true;
}
else if (this.dialogElement("open").selected) {
switch (this.dialogElement("openHandler").selectedIndex) {
case 0:
// No app need be specified in this case.
ok = true;
break;
case 1:
// only enable the OK button if we have a default app to use or if
// the user chose an app....
ok = this.chosenApp || /\S/.test(this.dialogElement("otherHandler").getAttribute("path"));
break;
}
}
// Enable Ok button if ok to press.
this.mDialog.document.documentElement.getButton("accept").disabled = !ok;
},
// Returns true iff the user-specified helper app has been modified.
appChanged: function() {
return this.helperAppChoice() != this.mLauncher.MIMEInfo.preferredApplicationHandler;
},
updateMIMEInfo: function() {
var needUpdate = false;
// If current selection differs from what's in the mime info object,
// then we need to update.
if (this.saveToDisk) {
needUpdate = this.mLauncher.MIMEInfo.preferredAction != this.nsIMIMEInfo.saveToDisk;
if (needUpdate)
this.mLauncher.MIMEInfo.preferredAction = this.nsIMIMEInfo.saveToDisk;
}
else if (this.useSystemDefault) {
needUpdate = this.mLauncher.MIMEInfo.preferredAction != this.nsIMIMEInfo.useSystemDefault;
if (needUpdate)
this.mLauncher.MIMEInfo.preferredAction = this.nsIMIMEInfo.useSystemDefault;
}
else {
// For "open with", we need to check both preferred action and whether the user chose
// a new app.
needUpdate = this.mLauncher.MIMEInfo.preferredAction != this.nsIMIMEInfo.useHelperApp || this.appChanged();
if (needUpdate) {
this.mLauncher.MIMEInfo.preferredAction = this.nsIMIMEInfo.useHelperApp;
// App may have changed - Update application and description
var app = this.helperAppChoice();
this.mLauncher.MIMEInfo.preferredApplicationHandler = app;
this.mLauncher.MIMEInfo.applicationDescription = "";
}
}
// We will also need to update if the "always ask" flag has changed.
needUpdate = needUpdate || this.mLauncher.MIMEInfo.alwaysAskBeforeHandling != (!this.dialogElement("rememberChoice").checked);
// One last special case: If the input "always ask" flag was false, then we always
// update. In that case we are displaying the helper app dialog for the first
// time for this mime type and we need to store the user's action in the mimeTypes.rdf
// data source (whether that action has changed or not; if it didn't change, then we need
// to store the "always ask" flag so the helper app dialog will or won't display
// next time, per the user's selection).
needUpdate = needUpdate || !this.mLauncher.MIMEInfo.alwaysAskBeforeHandling;
// Make sure mime info has updated setting for the "always ask" flag.
this.mLauncher.MIMEInfo.alwaysAskBeforeHandling = !this.dialogElement("rememberChoice").checked;
return needUpdate;
},
// See if the user changed things, and if so, update the
// mimeTypes.rdf entry for this mime type.
updateHelperAppPref: function() {
var ha = new this.mDialog.HelperApps();
ha.updateTypeInfo(this.mLauncher.MIMEInfo);
},
// onOK:
onOK: function() {
// Verify typed app path, if necessary.
if (this.useOtherHandler) {
var helperApp = this.helperAppChoice();
if (!helperApp || !helperApp.exists()) {
// Show alert and try again.
var bundle = this.dialogElement("strings");
var msg = bundle.getFormattedString("badApp", [this.dialogElement("otherHandler").path]);
var svc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
svc.alert(this.mDialog, bundle.getString("badApp.title"), msg);
// Disable the OK button.
this.mDialog.document.documentElement.getButton("accept").disabled = true;
this.dialogElement("mode").focus();
// Clear chosen application.
this.chosenApp = null;
// Leave dialog up.
return false;
}
}
// Remove our web progress listener (a progress dialog will be
// taking over).
this.mLauncher.setWebProgressListener(null);
// saveToDisk and launchWithApplication can return errors in
// certain circumstances (e.g. The user clicks cancel in the
// "Save to Disk" dialog. In those cases, we don't want to
// update the helper application preferences in the RDF file.
try {
var needUpdate = this.updateMIMEInfo();
if (this.dialogElement("save").selected) {
// If we're using a default download location, create a path
// for the file to be saved to to pass to |saveToDisk| - otherwise
// we must ask the user to pick a save name.
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var targetFile = null;
try {
targetFile = prefs.getComplexValue("browser.download.defaultFolder",
Components.interfaces.nsILocalFile);
var leafName = this.dialogElement("location").value;
targetFile.append(leafName);
// Ensure that we don't overwrite any existing files here.
targetFile = this.validateLeafName(targetFile, leafName);
}
catch(e) {}
this.mLauncher.saveToDisk(targetFile, false);
}
else
this.mLauncher.launchWithApplication(null, false);
// Update user pref for this mime type (if necessary). We do not
// store anything in the mime type preferences for the ambiguous
// type application/octet-stream. We do NOT do this for
// application/x-msdownload since we want users to be able to
// autodownload these to disk.
if (needUpdate && this.mLauncher.MIMEInfo.MIMEType != "application/octet-stream")
this.updateHelperAppPref();
} catch(e) { }
// Unhook dialog from this object.
this.mDialog.dialog = null;
// Close up dialog by returning true.
return true;
},
// onCancel:
onCancel: function() {
// Remove our web progress listener.
this.mLauncher.setWebProgressListener(null);
// Cancel app launcher.
try {
this.mLauncher.Cancel();
} catch(exception) {
}
// Unhook dialog from this object.
this.mDialog.dialog = null;
// Close up dialog by returning true.
return true;
},
// dialogElement: Convenience.
dialogElement: function(id) {
return this.mDialog.document.getElementById(id);
},
// chooseApp: Open file picker and prompt user for application.
chooseApp: function() {
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(this.mDialog,
this.dialogElement("strings").getString("chooseAppFilePickerTitle"),
nsIFilePicker.modeOpen);
fp.appendFilters(nsIFilePicker.filterApps);
if (fp.show() == nsIFilePicker.returnOK && fp.file) {
// Remember the file they chose to run.
this.chosenApp = fp.file;
// Update dialog.
var otherHandler = this.dialogElement("otherHandler");
otherHandler.removeAttribute("hidden");
otherHandler.setAttribute("path", this.getPath(this.chosenApp));
otherHandler.label = this.chosenApp.leafName;
this.dialogElement("openHandler").selectedIndex = 1;
this.dialogElement("mode").selectedItem = this.dialogElement("open");
}
},
// Turn this on to get debugging messages.
debug: false,
// Dump text (if debug is on).
dump: function( text ) {
if ( this.debug ) {
dump( text );
}
},
// dumpInfo:
doDebug: function() {
const nsIProgressDialog = Components.interfaces.nsIProgressDialog;
// Open new progress dialog.
var progress = Components.classes[ "@mozilla.org/progressdialog;1" ]
.createInstance( nsIProgressDialog );
// Show it.
progress.open( this.mDialog );
},
// dumpObj:
dumpObj: function( spec ) {
var val = "<undefined>";
try {
val = eval( "this."+spec ).toString();
} catch( exception ) {
}
this.dump( spec + "=" + val + "\n" );
},
// dumpObjectProperties
dumpObjectProperties: function( desc, obj ) {
for( prop in obj ) {
this.dump( desc + "." + prop + "=" );
var val = "<undefined>";
try {
val = obj[ prop ];
} catch ( exception ) {
}
this.dump( val + "\n" );
}
}
}
// This Component's module implementation. All the code below is used to get this
// component registered and accessible via XPCOM.
var module = {
firstTime: true,
// registerSelf: Register this component.
registerSelf: function (compMgr, fileSpec, location, type) {
if (this.firstTime) {
this.firstTime = false;
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
}
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.registerFactoryLocation( this.cid,
"Unknown Content Type 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("{F68578EB-6EC2-4169-AE19-8C6243F0ABE1}"),
/* Contract ID for this class */
contractId: "@mozilla.org/helperapplauncherdialog;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 nsUnknownContentTypeDialog()).QueryInterface(iid);
}
},
// canUnload: n/a (returns true)
canUnload: function(compMgr) {
return true;
}
};
// NSGetModule: Return the nsIModule object.
function NSGetModule(compMgr, fileSpec) {
return module;
}

Просмотреть файл

@ -178,6 +178,12 @@ function uninit()
gHelperApps.destroy();
}
// WARNING WARNING WARNING
// This is a Options OK Callback
// When this function is called the Downloads panel's document object
// MAY NOT BE AVAILABLE. As a result referring to any item in it in this
// function will probably cause the Options window not to close when OK
// is pressed.
function updateSaveToFolder()
{
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
@ -200,8 +206,10 @@ function updateSaveToFolder()
// user chooses to have all files auto-download to a specific folder.
if (data.askOnSave.value == "true") {
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var bundle = document.getElementById("strings");
var description = bundle.getString("myDownloads");
var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
var description = bundle.GetStringFromName("myDownloads");
var targetFolder = null;
switch (parseInt(data.downloadFolderList.value)) {

Просмотреть файл

@ -0,0 +1,30 @@
#
# 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 Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,5 @@
installitem {
-moz-binding: url("chrome://mozapps/content/xpinstall/xpinstallItem.xml#installitem");
display: -moz-box;
}

Просмотреть файл

@ -0,0 +1,91 @@
var XPInstallConfirm =
{
_param: null
};
XPInstallConfirm.init = function ()
{
var bundle = document.getElementById("xpinstallConfirmStrings");
this._param = window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock);
if (!this._param)
close();
this._param.SetInt(0, 1); // The default return value is "Cancel"
var itemList = document.getElementById("itemList");
var numItemsToInstall = this._param.GetInt(1);
for (var i = 0; i < numItemsToInstall; ++i) {
var installItem = document.createElement("installitem");
itemList.appendChild(installItem);
installItem.name = this._param.GetString(i);
installItem.url = this._param.GetString(++i);
var icon = this._param.GetString(++i);
if (icon != "")
installItem.icon = icon;
var cert = this._param.GetString(++i);
installItem.cert = cert || bundle.getString("Unsigned");
installItem.signed = cert ? "true" : "false";
}
var introString = bundle.getString("itemWarningIntroSingle");
if (numItemsToInstall > 4)
introString = bundle.getFormattedString("itemWarningIntroMultiple", [numItemsToInstall / 4]);
document.getElementById("itemWarningIntro").setAttribute("value", introString);
var okButton = document.documentElement.getButton("accept");
okButton.label = bundle.getString("installButtonLabel");
okButton.focus();
}
XPInstallConfirm.onOK = function ()
{
this._param.SetInt(0, 0);
return true;
}
XPInstallConfirm.onCancel = function ()
{
this._param.SetInt(0, 1);
return true;
}
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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.org Code.
#
# The Initial Developer of the Original Code is Ben Goodger.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ben Goodger <ben@bengoodger.com> (v2.0)
#
# 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 *****

Просмотреть файл

@ -0,0 +1,67 @@
<?xml version="1.0"?>
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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.org Code.
#
# The Initial Developer of the Original Code is Ben Goodger.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ben Goodger <ben@bengoodger.com> (v2.0)
#
# 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 *****
<?xml-stylesheet href="chrome://mozapps/content/xpinstall/xpinstallConfirm.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://mozapps/skin/xpinstall/xpinstallConfirm.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://mozapps/locale/xpinstall/xpinstallConfirm.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="xpinstallConfirm" title="&dialog.title;" style="width: 30em"
onload="XPInstallConfirm.init()"
ondialogaccept="return XPInstallConfirm.onOK();"
ondialogcancel="return XPInstallConfirm.onCancel();">
<script src="chrome://mozapps/content/xpinstall/xpinstallConfirm.js"/>
<stringbundle id="xpinstallConfirmStrings"
src="chrome://mozapps/locale/xpinstall/xpinstallConfirm.properties"/>
<vbox flex="1" id="dialogContentBox">
<description id="itemWarningIntro"/>
<vbox id="itemList" flex="1" style="height: 16em; overflow: auto;"/>
<description>&warningText2.label;</description>
<description class="warning">&warningText3.label;</description>
</vbox>
</dialog>

Просмотреть файл

@ -0,0 +1,46 @@
<?xml version="1.0"?>
<!DOCTYPE bindings SYSTEM "chrome://mozapps/locale/xpinstall/xpinstallConfirm.dtd">
<bindings id="xpinstallItemBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="installitem">
<resources>
<stylesheet src="chrome://mozapps/skin/xpinstall/xpinstallConfirm.css"/>
</resources>
<content>
<xul:hbox flex="1">
<xul:vbox align="center" pack="center">
<xul:image class="xpinstallItemIcon" xbl:inherits="src=icon"/>
</xul:vbox>
<xul:vbox flex="1">
<xul:hbox class="xpinstallItemNameRow" align="center">
<xul:label class="xpinstallItemName" xbl:inherits="value=name" flex="1" crop="right"/>
<xul:label class="xpinstallItemSigned" xbl:inherits="value=cert,signed"/>
</xul:hbox>
<xul:hbox class="xpinstallItemDetailsRow" align="center">
<xul:label class="xpinstallItemFromLabel">&from.label;</xul:label>
<xul:textbox class="xpinstallItemURL" xbl:inherits="value=url" flex="1" readonly="true" crop="right"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
<implementation>
<property name="name" onset="this.setAttribute('name', val); return val;"
onget="return this.getAttribute('name');"/>
<property name="cert" onset="this.setAttribute('cert', val); return val;"
onget="return this.getAttribute('cert');"/>
<property name="signed" onset="this.setAttribute('signed', val); return val;"
onget="return this.getAttribute('signed');"/>
<property name="url" onset="this.setAttribute('url', val); return val;"
onget="return this.getAttribute('url');"/>
<property name="icon" onset="this.setAttribute('icon', val); return val;"
onget="return this.getAttribute('icon');"/>
</implementation>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,174 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Communicator client code, released March
* 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
var gManager;
var gBundle;
var gCanClose = false;
var gCancelled = false;
// implements nsIXPIProgressDialog
var progressHooks =
{
onStateChange: function( aIndex, aState, aValue )
{
const state = Components.interfaces.nsIXPIProgressDialog;
var status = document.getElementById("status"+aIndex);
var progress = document.getElementById("progress"+aIndex);
switch( aState ) {
case state.DOWNLOAD_START:
status.setAttribute("value",
gBundle.getString("progress.downloading"));
progress.setAttribute("value","0%");
break;
case state.DOWNLOAD_DONE:
status.setAttribute("value",
gBundle.getString("progress.downloaded"));
progress.setAttribute("value","100%");
break;
case state.INSTALL_START:
status.setAttribute("value",
gBundle.getString("progress.installing"));
progress.setAttribute("mode","undetermined");
break;
case state.INSTALL_DONE:
progress.setAttribute("mode","determined");
progress.hidden = true;
var msg;
try
{
msg = gBundle.getString("error"+aValue);
}
catch (e)
{
msg = gBundle.stringBundle.formatStringFromName(
"unknown.error", [aValue], 1 );
}
status.setAttribute("value",msg);
break;
case state.DIALOG_CLOSE:
// nsXPInstallManager is done with us, but we'll let users
// dismiss the dialog themselves so they can see the status
// (unless we're closing because the user cancelled)
document.getElementById("ok").disabled = false;
document.getElementById("cancel").disabled = true;
gCanClose = true;
if (gCancelled)
window.close();
break;
}
},
onProgress: function( aIndex, aValue, aMaxValue )
{
var percent = Math.round( 100 * (aValue/aMaxValue) );
var node = document.getElementById("progress"+aIndex);
node.setAttribute("value", percent);
},
QueryInterface: function( iid )
{
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIXPIProgressDialog))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
}
function onLoad()
{
doSetOKCancel(dlgOK, dlgCancel);
document.getElementById("ok").disabled = true;
document.getElementById("cancel").focus();
gBundle = document.getElementById("xpinstallBundle");
var param = window.arguments[0].QueryInterface(
Components.interfaces.nsIDialogParamBlock );
if ( !param )
dump (" error getting param block interface \n");
var i = 0;
var row = 0;
var numElements = param.GetInt(1);
while ( i < numElements )
{
var moduleName = param.GetString(i++);
var URL = param.GetString(i++);
var certName = param.GetString(i++);
addTreeItem(row++, moduleName, URL);
}
gManager = window.arguments[1];
// inform nsXPInstallManager we're open for business
gManager.observe( progressHooks, "xpinstall-progress", "open" );
}
function addTreeItem(aRow, aName, aUrl)
{
// first column is the package name
var item = document.createElement("description");
item.setAttribute("class", "packageName");
item.setAttribute("id", "package"+aRow);
item.setAttribute("value", aName);
item.setAttribute("tooltiptext", aUrl);
// second column is the status
var status = document.createElement('description');
status.setAttribute("class", "packageStatus");
status.setAttribute("id", "status"+aRow);
status.setAttribute("value", gBundle.getString("progress.queued"));
// third row is a progress meter
var progress = document.createElement("progressmeter");
progress.setAttribute("class", "packageProgress");
progress.setAttribute("id", "progress"+aRow);
progress.setAttribute("value", "0%");
// create row and add it to the grid
var row = document.createElement("row");
row.appendChild(item);
row.appendChild(status);
row.appendChild(progress);
document.getElementById("xpirows").appendChild(row);
}
function dlgOK() { return true; }
function dlgCancel()
{
gCancelled = true;
if (gManager)
gManager.observe( progressHooks, "xpinstall-progress", "cancel");
// window is closed by native impl after cleanup
return gCanClose;
}

Просмотреть файл

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<!--
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 Communicator client code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-2002 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Don Bragg (dbragg@netscape.com) 12/08/1999
Blake Ross (BlakeR1234@aol.com) 7/05/2000
Daniel Veditz <dveditz@netscape.com> 1/2002
-->
<?xml-stylesheet href="chrome://communicator/skin/xpinstall/xpinstall.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://communicator/locale/xpinstall/xpistatus.dtd" >
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&progressTitle.label;"
onload="onLoad()"
onclose="return gCanClose"
id="statusDlg"
class="dialog"
style="width: 50em"
>
<script src="chrome://communicator/content/xpinstall/xpistatus.js"/>
<keyset id="dialogKeys"/>
<stringbundle id="xpinstallBundle" src="chrome://communicator/locale/xpinstall/xpinstall.properties"/>
<vbox id="mainProgressBox" flex="1">
<groupbox id="progressGroup" orient="vertical" flex="1">
<caption id="progressCaption" label="&group.caption;"/>
<grid id="progressGrid" flex="1">
<columns>
<column id="xpiColumn" flex="3"/>
<column id="statusColumn" flex="2"/>
<column id="progressColumn"/>
</columns>
<rows id="xpirows">
</rows>
</grid>
</groupbox>
<separator class="thin"/>
<hbox id="okCancelButtonsRight"/>
</vbox>
</window>

Просмотреть файл

@ -0,0 +1,15 @@
toolkit.jar:
* content/mozapps/xpinstall/xpinstallConfirm.xul (content/xpinstallConfirm.xul)
* content/mozapps/xpinstall/xpinstallConfirm.js (content/xpinstallConfirm.js)
content/mozapps/xpinstall/xpinstallConfirm.css (content/xpinstallConfirm.css)
* content/mozapps/xpinstall/xpinstallItem.xml (content/xpinstallItem.xml)
en-US.jar:
locale/en-US/mozapps/xpinstall/xpinstallConfirm.dtd (locale/xpinstallConfirm.dtd)
locale/en-US/mozapps/xpinstall/xpinstallConfirm.properties (locale/xpinstallConfirm.properties)
classic.jar:
skin/classic/mozapps/xpinstall/xpinstallConfirm.css (skin/xpinstallConfirm.css)
skin/classic/mozapps/xpinstall/xpinstallIcon.png (skin/xpinstallIcon.png);
skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png (skin/xpinstallItemGeneric.png);

Просмотреть файл

Просмотреть файл

@ -0,0 +1,8 @@
Unsigned=Unsigned
itemWarningIntroMultiple=A web site is requesting permission to install the following %S items:
itemWarningIntroSingle=A web site is requesting permission to install the following item:
installButtonLabel=Install Now
installComplete=Software Installation is complete. You will have to restart %S for changes to take effect.
installCompleteTitle=Installation Complete

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,59 @@
#xpinstallIcon {
list-style-image: url("chrome://mozapps/skin/xpinstall/xpinstallIcon.png");
}
#itemList {
-moz-appearance: listbox;
margin: 10px 4px 10px 4px;
}
#dialogContentBox {
padding: 5px;
}
installitem {
padding: 5px 0px 5px 5px;
border-bottom: 1px dotted #C0C0C0;
margin-bottom: 5px;
}
.warning {
font-weight: bold;
}
.xpinstallItemIcon {
width: 32px;
height: 32px;
max-width: 32px !important;
max-height: 32px !important;
margin-right: 5px;
}
.xpinstallItemName {
font-weight: bold;
}
.xpinstallItemSigned {
font-style: italic;
}
.xpinstallItemSigned[signed=false] {
color: #ED1C24;
font-style: normal;
font-weight: bold;
}
.xpinstallItemNameRow {
padding-bottom: 3px;
}
.xpinstallItemURL {
-moz-appearance: none;
border: none;
background-color: Window;
}
.xpinstallItemIcon {
list-style-image: url("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png");
}

Просмотреть файл

Просмотреть файл