Bug 1659073 - Add confirmRepost to nsIPromptCollection. r=pbz,smaug

Differential Revision: https://phabricator.services.mozilla.com/D89657
This commit is contained in:
Agi Sferro
2020-09-10 22:28:15 +00:00
parent d3c2e114aa
commit 6828a8bde2
3 changed files with 97 additions and 84 deletions

View File

@@ -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}"

View File

@@ -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,

View File

@@ -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);
};