1/* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5"use strict"; 6 7var EXPORTED_SYMBOLS = ["PromptCollection"]; 8 9const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); 10const { XPCOMUtils } = ChromeUtils.import( 11 "resource://gre/modules/XPCOMUtils.jsm" 12); 13 14/** 15 * Implements nsIPromptCollection 16 * @class PromptCollection 17 */ 18class PromptCollection { 19 confirmRepost(browsingContext) { 20 let brandName; 21 try { 22 brandName = this.stringBundles.brand.GetStringFromName("brandShortName"); 23 } catch (exception) { 24 // That's ok, we'll use a generic version of the prompt 25 } 26 27 let message; 28 let resendLabel; 29 try { 30 if (brandName) { 31 message = this.stringBundles.app.formatStringFromName( 32 "confirmRepostPrompt", 33 [brandName] 34 ); 35 } else { 36 // Use a generic version of this prompt. 37 message = this.stringBundles.app.GetStringFromName( 38 "confirmRepostPrompt" 39 ); 40 } 41 resendLabel = this.stringBundles.app.GetStringFromName( 42 "resendButton.label" 43 ); 44 } catch (exception) { 45 Cu.reportError("Failed to get strings from appstrings.properties"); 46 return false; 47 } 48 49 let contentViewer = browsingContext?.docShell?.contentViewer; 50 let modalType = contentViewer?.isTabModalPromptAllowed 51 ? Ci.nsIPromptService.MODAL_TYPE_CONTENT 52 : Ci.nsIPromptService.MODAL_TYPE_WINDOW; 53 let buttonFlags = 54 (Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * 55 Ci.nsIPromptService.BUTTON_POS_0) | 56 (Ci.nsIPromptService.BUTTON_TITLE_CANCEL * 57 Ci.nsIPromptService.BUTTON_POS_1); 58 let buttonPressed = Services.prompt.confirmExBC( 59 browsingContext, 60 modalType, 61 null, 62 message, 63 buttonFlags, 64 resendLabel, 65 null, 66 null, 67 null, 68 {} 69 ); 70 71 return buttonPressed === 0; 72 } 73 74 async asyncBeforeUnloadCheck(browsingContext) { 75 let title; 76 let message; 77 let leaveLabel; 78 let stayLabel; 79 80 try { 81 title = this.stringBundles.dom.GetStringFromName("OnBeforeUnloadTitle"); 82 message = this.stringBundles.dom.GetStringFromName( 83 "OnBeforeUnloadMessage2" 84 ); 85 leaveLabel = this.stringBundles.dom.GetStringFromName( 86 "OnBeforeUnloadLeaveButton" 87 ); 88 stayLabel = this.stringBundles.dom.GetStringFromName( 89 "OnBeforeUnloadStayButton" 90 ); 91 } catch (exception) { 92 Cu.reportError("Failed to get strings from dom.properties"); 93 return false; 94 } 95 96 let contentViewer = browsingContext?.docShell?.contentViewer; 97 98 if ( 99 (contentViewer && !contentViewer.isTabModalPromptAllowed) || 100 !browsingContext.ancestorsAreCurrent 101 ) { 102 Cu.reportError("Can't prompt from inactive content viewer"); 103 return true; 104 } 105 106 let buttonFlags = 107 Ci.nsIPromptService.BUTTON_POS_0_DEFAULT | 108 (Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * 109 Ci.nsIPromptService.BUTTON_POS_0) | 110 (Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * 111 Ci.nsIPromptService.BUTTON_POS_1); 112 113 let result = await Services.prompt.asyncConfirmEx( 114 browsingContext, 115 Services.prompt.MODAL_TYPE_CONTENT, 116 title, 117 message, 118 buttonFlags, 119 leaveLabel, 120 stayLabel, 121 null, 122 null, 123 false, 124 // Tell the prompt service that this is a permit unload prompt 125 // so that it can set the appropriate flag on the detail object 126 // of the events it dispatches. 127 { inPermitUnload: true } 128 ); 129 130 return ( 131 result.QueryInterface(Ci.nsIPropertyBag2).get("buttonNumClicked") == 0 132 ); 133 } 134 135 confirmFolderUpload(browsingContext, directoryName) { 136 let title; 137 let message; 138 let acceptLabel; 139 140 try { 141 title = this.stringBundles.dom.GetStringFromName( 142 "FolderUploadPrompt.title" 143 ); 144 message = this.stringBundles.dom.formatStringFromName( 145 "FolderUploadPrompt.message", 146 [directoryName] 147 ); 148 acceptLabel = this.stringBundles.dom.GetStringFromName( 149 "FolderUploadPrompt.acceptButtonLabel" 150 ); 151 } catch (exception) { 152 Cu.reportError("Failed to get strings from dom.properties"); 153 return false; 154 } 155 156 let buttonFlags = 157 Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 + 158 Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 + 159 Services.prompt.BUTTON_POS_1_DEFAULT; 160 161 return ( 162 Services.prompt.confirmExBC( 163 browsingContext, 164 Services.prompt.MODAL_TYPE_TAB, 165 title, 166 message, 167 buttonFlags, 168 acceptLabel, 169 null, 170 null, 171 null, 172 {} 173 ) === 0 174 ); 175 } 176} 177 178const BUNDLES = { 179 dom: "chrome://global/locale/dom/dom.properties", 180 app: "chrome://global/locale/appstrings.properties", 181 brand: "chrome://branding/locale/brand.properties", 182}; 183 184PromptCollection.prototype.stringBundles = {}; 185 186for (const [bundleName, bundleUrl] of Object.entries(BUNDLES)) { 187 XPCOMUtils.defineLazyGetter( 188 PromptCollection.prototype.stringBundles, 189 bundleName, 190 function() { 191 let bundle = Services.strings.createBundle(bundleUrl); 192 if (!bundle) { 193 throw new Error("String bundle for dom not present!"); 194 } 195 return bundle; 196 } 197 ); 198} 199 200PromptCollection.prototype.QueryInterface = ChromeUtils.generateQI([ 201 "nsIPromptCollection", 202]); 203