Bug 1659073 - Add confirmRepost to nsIPromptCollection. r=pbz,smaug
Differential Revision: https://phabricator.services.mozilla.com/D89657
This commit is contained in:
@@ -16,6 +16,61 @@ const { XPCOMUtils } = ChromeUtils.import(
|
||||
* @class PromptCollection
|
||||
*/
|
||||
class PromptCollection {
|
||||
confirmRepost(browsingContext) {
|
||||
let brandName;
|
||||
try {
|
||||
brandName = this.stringBundles.brand.GetStringFromName("brandShortName");
|
||||
} catch (exception) {
|
||||
// That's ok, we'll use a generic version of the prompt
|
||||
}
|
||||
|
||||
let message;
|
||||
let resendLabel;
|
||||
try {
|
||||
if (brandName) {
|
||||
message = this.stringBundles.app.formatStringFromName(
|
||||
"confirmRepostPrompt",
|
||||
[brandName]
|
||||
);
|
||||
} else {
|
||||
// Use a generic version of this prompt.
|
||||
message = this.stringBundles.app.GetStringFromName(
|
||||
"confirmRepostPrompt"
|
||||
);
|
||||
}
|
||||
resendLabel = this.stringBundles.app.GetStringFromName(
|
||||
"resendButton.label"
|
||||
);
|
||||
} catch (exception) {
|
||||
Cu.reportError("Failed to get strings from appstrings.properties");
|
||||
return false;
|
||||
}
|
||||
|
||||
let contentViewer = browsingContext?.docShell?.contentViewer;
|
||||
let modalType = contentViewer?.isTabModalPromptAllowed
|
||||
? Ci.nsIPromptService.MODAL_TYPE_CONTENT
|
||||
: Ci.nsIPromptService.MODAL_TYPE_WINDOW;
|
||||
let buttonFlags =
|
||||
(Ci.nsIPromptService.BUTTON_TITLE_IS_STRING *
|
||||
Ci.nsIPromptService.BUTTON_POS_0) |
|
||||
(Ci.nsIPromptService.BUTTON_TITLE_CANCEL *
|
||||
Ci.nsIPromptService.BUTTON_POS_1);
|
||||
let buttonPressed = Services.prompt.confirmExBC(
|
||||
browsingContext,
|
||||
modalType,
|
||||
null,
|
||||
message,
|
||||
buttonFlags,
|
||||
resendLabel,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{}
|
||||
);
|
||||
|
||||
return buttonPressed === 0;
|
||||
}
|
||||
|
||||
beforeUnloadCheck(browsingContext) {
|
||||
let title;
|
||||
let message;
|
||||
@@ -23,12 +78,16 @@ class PromptCollection {
|
||||
let stayLabel;
|
||||
|
||||
try {
|
||||
title = this.domBundle.GetStringFromName("OnBeforeUnloadTitle");
|
||||
message = this.domBundle.GetStringFromName("OnBeforeUnloadMessage");
|
||||
leaveLabel = this.domBundle.GetStringFromName(
|
||||
title = this.stringBundles.dom.GetStringFromName("OnBeforeUnloadTitle");
|
||||
message = this.stringBundles.dom.GetStringFromName(
|
||||
"OnBeforeUnloadMessage"
|
||||
);
|
||||
leaveLabel = this.stringBundles.dom.GetStringFromName(
|
||||
"OnBeforeUnloadLeaveButton"
|
||||
);
|
||||
stayLabel = this.domBundle.GetStringFromName("OnBeforeUnloadStayButton");
|
||||
stayLabel = this.stringBundles.dom.GetStringFromName(
|
||||
"OnBeforeUnloadStayButton"
|
||||
);
|
||||
} catch (exception) {
|
||||
Cu.reportError("Failed to get strings from dom.properties");
|
||||
return false;
|
||||
@@ -63,19 +122,27 @@ class PromptCollection {
|
||||
}
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(
|
||||
PromptCollection.prototype,
|
||||
"domBundle",
|
||||
function() {
|
||||
let bundle = Services.strings.createBundle(
|
||||
"chrome://global/locale/dom/dom.properties"
|
||||
);
|
||||
if (!bundle) {
|
||||
throw new Error("String bundle for dom not present!");
|
||||
const BUNDLES = {
|
||||
dom: "chrome://global/locale/dom/dom.properties",
|
||||
app: "chrome://global/locale/appstrings.properties",
|
||||
brand: "chrome://branding/locale/brand.properties",
|
||||
};
|
||||
|
||||
PromptCollection.prototype.stringBundles = {};
|
||||
|
||||
for (const [bundleName, bundleUrl] of Object.entries(BUNDLES)) {
|
||||
XPCOMUtils.defineLazyGetter(
|
||||
PromptCollection.prototype.stringBundles,
|
||||
bundleName,
|
||||
function() {
|
||||
let bundle = Services.strings.createBundle(bundleUrl);
|
||||
if (!bundle) {
|
||||
throw new Error("String bundle for dom not present!");
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
PromptCollection.prototype.classID = Components.ID(
|
||||
"{7913837c-9623-11ea-bb37-0242ac130002}"
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIPrivacyTransitionObserver.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIPromptCollection.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
#include "nsIReflowObserver.h"
|
||||
#include "nsIScriptChannel.h"
|
||||
@@ -11709,78 +11710,13 @@ nsresult nsDocShell::ConfirmRepost(bool* aRepost) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrompt> prompter;
|
||||
CallGetInterface(this, static_cast<nsIPrompt**>(getter_AddRefs(prompter)));
|
||||
nsCOMPtr<nsIPromptCollection> prompter =
|
||||
do_GetService("@mozilla.org/embedcomp/prompt-collection;1");
|
||||
if (!prompter) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
if (!stringBundleService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStringBundle> appBundle;
|
||||
nsresult rv = stringBundleService->CreateBundle(kAppstringsBundleURL,
|
||||
getter_AddRefs(appBundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> brandBundle;
|
||||
rv = stringBundleService->CreateBundle(kBrandBundleURL,
|
||||
getter_AddRefs(brandBundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(prompter && brandBundle && appBundle,
|
||||
"Unable to set up repost prompter.");
|
||||
|
||||
AutoTArray<nsString, 1> formatStrings;
|
||||
rv = brandBundle->GetStringFromName("brandShortName",
|
||||
*formatStrings.AppendElement());
|
||||
|
||||
nsAutoString msgString, button0Title;
|
||||
if (NS_FAILED(rv)) { // No brand, use the generic version.
|
||||
rv = appBundle->GetStringFromName("confirmRepostPrompt", msgString);
|
||||
} else {
|
||||
// Brand available - if the app has an override file with formatting, the
|
||||
// app name will be included. Without an override, the prompt will look
|
||||
// like the generic version.
|
||||
rv = appBundle->FormatStringFromName("confirmRepostPrompt", formatStrings,
|
||||
msgString);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = appBundle->GetStringFromName("resendButton.label", button0Title);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Make the repost prompt content modal to prevent malicious pages from
|
||||
// locking up the browser, see bug 1412559 for an example.
|
||||
if (nsCOMPtr<nsIWritablePropertyBag2> promptBag =
|
||||
do_QueryInterface(prompter)) {
|
||||
promptBag->SetPropertyAsUint32(u"modalType"_ns,
|
||||
nsIPrompt::MODAL_TYPE_CONTENT);
|
||||
}
|
||||
|
||||
int32_t buttonPressed;
|
||||
// The actual value here is irrelevant, but we can't pass an invalid
|
||||
// bool through XPConnect.
|
||||
bool checkState = false;
|
||||
rv = prompter->ConfirmEx(
|
||||
nullptr, msgString.get(),
|
||||
(nsIPrompt::BUTTON_POS_0 * nsIPrompt::BUTTON_TITLE_IS_STRING) +
|
||||
(nsIPrompt::BUTTON_POS_1 * nsIPrompt::BUTTON_TITLE_CANCEL),
|
||||
button0Title.get(), nullptr, nullptr, nullptr, &checkState,
|
||||
&buttonPressed);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aRepost = (buttonPressed == 0);
|
||||
return NS_OK;
|
||||
return prompter->ConfirmRepost(mBrowsingContext, aRepost);
|
||||
}
|
||||
|
||||
nsresult nsDocShell::GetPromptAndStringBundle(nsIPrompt** aPrompt,
|
||||
|
||||
@@ -22,4 +22,14 @@ interface nsIPromptCollection : nsISupports
|
||||
* @return true if the page should be allowed to navigate away
|
||||
*/
|
||||
boolean beforeUnloadCheck(in BrowsingContext aBrowsingContext);
|
||||
|
||||
/**
|
||||
* Puts up a dialog for the confirm repost prompt.
|
||||
*
|
||||
* @param aBrowsingContext
|
||||
* The browsing context the prompt should be opened for.
|
||||
*
|
||||
* @return true if the page should be allowed to repost data.
|
||||
*/
|
||||
boolean confirmRepost(in BrowsingContext aBrowsingContext);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user