toolkit/components/jsdownloads/src/DownloadUIHelper.jsm

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:67130beb3f8c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /**
8 * Provides functions to handle status and messages in the user interface.
9 */
10
11 "use strict";
12
13 this.EXPORTED_SYMBOLS = [
14 "DownloadUIHelper",
15 ];
16
17 ////////////////////////////////////////////////////////////////////////////////
18 //// Globals
19
20 const Cc = Components.classes;
21 const Ci = Components.interfaces;
22 const Cu = Components.utils;
23 const Cr = Components.results;
24
25 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
26
27 XPCOMUtils.defineLazyModuleGetter(this, "OS",
28 "resource://gre/modules/osfile.jsm");
29 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
30 "resource://gre/modules/Promise.jsm");
31 XPCOMUtils.defineLazyModuleGetter(this, "Services",
32 "resource://gre/modules/Services.jsm");
33
34 const kStringBundleUrl =
35 "chrome://mozapps/locale/downloads/downloads.properties";
36
37 const kStringsRequiringFormatting = {
38 fileExecutableSecurityWarning: true,
39 cancelDownloadsOKTextMultiple: true,
40 quitCancelDownloadsAlertMsgMultiple: true,
41 quitCancelDownloadsAlertMsgMacMultiple: true,
42 offlineCancelDownloadsAlertMsgMultiple: true,
43 leavePrivateBrowsingWindowsCancelDownloadsAlertMsgMultiple: true
44 };
45
46 ////////////////////////////////////////////////////////////////////////////////
47 //// DownloadUIHelper
48
49 /**
50 * Provides functions to handle status and messages in the user interface.
51 */
52 this.DownloadUIHelper = {
53 /**
54 * Returns an object that can be used to display prompts related to downloads.
55 *
56 * The prompts may be either anchored to a specified window, or anchored to
57 * the most recently active window, for example if the prompt is displayed in
58 * response to global notifications that are not associated with any window.
59 *
60 * @param aParent
61 * If specified, should reference the nsIDOMWindow to which the prompts
62 * should be attached. If omitted, the prompts will be attached to the
63 * most recently active window.
64 *
65 * @return A DownloadPrompter object.
66 */
67 getPrompter: function (aParent)
68 {
69 return new DownloadPrompter(aParent || null);
70 },
71 };
72
73 /**
74 * Returns an object whose keys are the string names from the downloads string
75 * bundle, and whose values are either the translated strings or functions
76 * returning formatted strings.
77 */
78 XPCOMUtils.defineLazyGetter(DownloadUIHelper, "strings", function () {
79 let strings = {};
80 let sb = Services.strings.createBundle(kStringBundleUrl);
81 let enumerator = sb.getSimpleEnumeration();
82 while (enumerator.hasMoreElements()) {
83 let string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
84 let stringName = string.key;
85 if (stringName in kStringsRequiringFormatting) {
86 strings[stringName] = function () {
87 // Convert "arguments" to a real array before calling into XPCOM.
88 return sb.formatStringFromName(stringName,
89 Array.slice(arguments, 0),
90 arguments.length);
91 };
92 } else {
93 strings[stringName] = string.value;
94 }
95 }
96 return strings;
97 });
98
99 ////////////////////////////////////////////////////////////////////////////////
100 //// DownloadPrompter
101
102 /**
103 * Allows displaying prompts related to downloads.
104 *
105 * @param aParent
106 * The nsIDOMWindow to which prompts should be attached, or null to
107 * attach prompts to the most recently active window.
108 */
109 this.DownloadPrompter = function (aParent)
110 {
111 #ifdef MOZ_B2G
112 // On B2G there is no prompter implementation.
113 this._prompter = null;
114 #else
115 this._prompter = Services.ww.getNewPrompter(aParent);
116 #endif
117 }
118
119 this.DownloadPrompter.prototype = {
120 /**
121 * Constants with the different type of prompts.
122 */
123 ON_QUIT: "prompt-on-quit",
124 ON_OFFLINE: "prompt-on-offline",
125 ON_LEAVE_PRIVATE_BROWSING: "prompt-on-leave-private-browsing",
126
127 /**
128 * nsIPrompt instance for displaying messages.
129 */
130 _prompter: null,
131
132 /**
133 * Displays a warning message box that informs that the specified file is
134 * executable, and asks whether the user wants to launch it. The user is
135 * given the option of disabling future instances of this warning.
136 *
137 * @param aPath
138 * String containing the full path to the file to be opened.
139 *
140 * @return {Promise}
141 * @resolves Boolean indicating whether the launch operation can continue.
142 * @rejects JavaScript exception.
143 */
144 confirmLaunchExecutable: function (aPath)
145 {
146 const kPrefAlertOnEXEOpen = "browser.download.manager.alertOnEXEOpen";
147
148 try {
149 // Always launch in case we have no prompter implementation.
150 if (!this._prompter) {
151 return Promise.resolve(true);
152 }
153
154 try {
155 if (!Services.prefs.getBoolPref(kPrefAlertOnEXEOpen)) {
156 return Promise.resolve(true);
157 }
158 } catch (ex) {
159 // If the preference does not exist, continue with the prompt.
160 }
161
162 let leafName = OS.Path.basename(aPath);
163
164 let s = DownloadUIHelper.strings;
165 let checkState = { value: false };
166 let shouldLaunch = this._prompter.confirmCheck(
167 s.fileExecutableSecurityWarningTitle,
168 s.fileExecutableSecurityWarning(leafName, leafName),
169 s.fileExecutableSecurityWarningDontAsk,
170 checkState);
171
172 if (shouldLaunch) {
173 Services.prefs.setBoolPref(kPrefAlertOnEXEOpen, !checkState.value);
174 }
175
176 return Promise.resolve(shouldLaunch);
177 } catch (ex) {
178 return Promise.reject(ex);
179 }
180 },
181
182 /**
183 * Displays a warning message box that informs that there are active
184 * downloads, and asks whether the user wants to cancel them or not.
185 *
186 * @param aDownloadsCount
187 * The current downloads count.
188 * @param aPromptType
189 * The type of prompt notification depending on the observer.
190 *
191 * @return False to cancel the downloads and continue, true to abort the
192 * operation.
193 */
194 confirmCancelDownloads: function DP_confirmCancelDownload(aDownloadsCount,
195 aPromptType)
196 {
197 // Always continue in case we have no prompter implementation, or if there
198 // are no active downloads.
199 if (!this._prompter || aDownloadsCount <= 0) {
200 return false;
201 }
202
203 let s = DownloadUIHelper.strings;
204 let buttonFlags = (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
205 (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1);
206 let okButton = aDownloadsCount > 1 ? s.cancelDownloadsOKTextMultiple(aDownloadsCount)
207 : s.cancelDownloadsOKText;
208 let title, message, cancelButton;
209
210 switch (aPromptType) {
211 case this.ON_QUIT:
212 title = s.quitCancelDownloadsAlertTitle;
213 #ifndef XP_MACOSX
214 message = aDownloadsCount > 1
215 ? s.quitCancelDownloadsAlertMsgMultiple(aDownloadsCount)
216 : s.quitCancelDownloadsAlertMsg;
217 cancelButton = s.dontQuitButtonWin;
218 #else
219 message = aDownloadsCount > 1
220 ? s.quitCancelDownloadsAlertMsgMacMultiple(aDownloadsCount)
221 : s.quitCancelDownloadsAlertMsgMac;
222 cancelButton = s.dontQuitButtonMac;
223 #endif
224 break;
225 case this.ON_OFFLINE:
226 title = s.offlineCancelDownloadsAlertTitle;
227 message = aDownloadsCount > 1
228 ? s.offlineCancelDownloadsAlertMsgMultiple(aDownloadsCount)
229 : s.offlineCancelDownloadsAlertMsg;
230 cancelButton = s.dontGoOfflineButton;
231 break;
232 case this.ON_LEAVE_PRIVATE_BROWSING:
233 title = s.leavePrivateBrowsingCancelDownloadsAlertTitle;
234 message = aDownloadsCount > 1
235 ? s.leavePrivateBrowsingWindowsCancelDownloadsAlertMsgMultiple(aDownloadsCount)
236 : s.leavePrivateBrowsingWindowsCancelDownloadsAlertMsg;
237 cancelButton = s.dontLeavePrivateBrowsingButton;
238 break;
239 }
240
241 let rv = this._prompter.confirmEx(title, message, buttonFlags, okButton,
242 cancelButton, null, null, {});
243 return (rv == 1);
244 }
245 };

mercurial