diff --git a/browser/actors/PromptParent.sys.mjs b/browser/actors/PromptParent.sys.mjs
index 9858a2662ce12..0339c14642004 100644
--- a/browser/actors/PromptParent.sys.mjs
+++ b/browser/actors/PromptParent.sys.mjs
@@ -26,7 +26,7 @@ XPCOMUtils.defineLazyPreferenceGetter(
);
XPCOMUtils.defineLazyGetter(lazy, "gTabBrowserLocalization", function () {
- return new Localization(["browser/tabbrowser.ftl"], true);
+ return new Localization(["browser/tabbrowser.ftl", "browser/waterfox.ftl"], true);
});
/**
diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js
index e501cce8ffe0c..9da985774437f 100644
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -98,7 +98,7 @@
});
XPCOMUtils.defineLazyGetter(this, "tabLocalization", () => {
return new Localization(
- ["browser/tabbrowser.ftl", "branding/brand.ftl"],
+ ["browser/tabbrowser.ftl", "branding/brand.ftl", "browser/waterfox.ftl"],
true
);
});
@@ -3357,26 +3357,40 @@
// default to true: if it were false, we wouldn't get this far
var warnOnClose = { value: true };
+ let restoreSession;
+ let startupPref = Services.prefs.getIntPref("browser.startup.page");
+
+ // If we are set to anything other than restore session,
+ // leave its value.
+ if (startupPref != 3) {
+ console.log("Value of: " + startupPref);
+ restoreSession = { value: false };
+ } else {
+ console.log("Value of: " + startupPref);
+ restoreSession = { value: true };
+ }
+
// focus the window before prompting.
// this will raise any minimized window, which will
// make it obvious which window the prompt is for and will
// solve the problem of windows "obscuring" the prompt.
// see bug #350299 for more details
window.focus();
- const [title, button, checkbox] = this.tabLocalization.formatValuesSync([
+ const [title, button, checkbox, checkboxLabel2] = this.tabLocalization.formatValuesSync([
{
id: "tabbrowser-confirm-close-tabs-title",
args: { tabCount: tabsToClose },
},
{ id: "tabbrowser-confirm-close-tabs-button" },
{ id: "tabbrowser-confirm-close-tabs-checkbox" },
+ { id: "tabbrowser-confirm-session-restore-checkbox" }
]);
let flags =
ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0 +
ps.BUTTON_TITLE_CANCEL * ps.BUTTON_POS_1;
let checkboxLabel =
aCloseTabs == this.closingTabsEnum.ALL ? checkbox : null;
- var buttonPressed = ps.confirmEx(
+ var buttonPressed = ps.confirmEx2(
window,
title,
null,
@@ -3385,7 +3399,9 @@
null,
null,
checkboxLabel,
- warnOnClose
+ warnOnClose,
+ checkboxLabel2,
+ restoreSession
);
Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
@@ -3432,6 +3448,16 @@
Services.prefs.setBoolPref(pref, false);
}
+ if (buttonPressed == 0) {
+ if (!restoreSession.value) {
+ if (startupPref === 3) {
+ Services.prefs.setIntPref("browser.startup.page", 1);
+ }
+ } else if (restoreSession.value) {
+ Services.prefs.setIntPref("browser.startup.page", 3);
+ }
+ }
+
return reallyClose;
},
diff --git a/browser/components/BrowserGlue.sys.mjs b/browser/components/BrowserGlue.sys.mjs
index f9dad1e715c84..2107e99a5bdcd 100644
--- a/browser/components/BrowserGlue.sys.mjs
+++ b/browser/components/BrowserGlue.sys.mjs
@@ -3125,6 +3125,18 @@ BrowserGlue.prototype = {
aQuitType = "quit";
}
+ let restoreSession;
+ let startupPref = Services.prefs.getIntPref("browser.startup.page");
+
+ // If we are set to anything other than restore session,
+ if (startupPref != 3) {
+ console.log("Value of: " + startupPref);
+ restoreSession = { value: false };
+ } else {
+ console.log("Value of: " + startupPref);
+ restoreSession = { value: true };
+ }
+
let win = lazy.BrowserWindowTracker.getTopWindow();
// Our prompt for quitting is most important, so replace others.
@@ -3163,19 +3175,23 @@ BrowserGlue.prototype = {
checkboxLabelId = "tabbrowser-confirm-close-tabs-checkbox";
}
- const [title, buttonLabel, checkboxLabel] =
+ let checkboxLabelId2 = "tabbrowser-confirm-session-restore-checkbox";
+
+ const [title, buttonLabel, checkboxLabel, checkboxLabel2] =
win.gBrowser.tabLocalization.formatMessagesSync([
titleId,
buttonLabelId,
checkboxLabelId,
+ checkboxLabelId2,
]);
let warnOnClose = { value: true };
+
let flags =
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1;
// buttonPressed will be 0 for closing, 1 for cancel (don't close/quit)
- let buttonPressed = Services.prompt.confirmEx(
+ let buttonPressed = Services.prompt.confirmEx2(
win,
title.value,
null,
@@ -3184,7 +3200,9 @@ BrowserGlue.prototype = {
null,
null,
checkboxLabel.value,
- warnOnClose
+ warnOnClose,
+ checkboxLabel2.value,
+ restoreSession
);
Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
let warnCheckbox = warnOnClose.value ? "checked" : "unchecked";
@@ -3217,6 +3235,18 @@ BrowserGlue.prototype = {
}
}
+ // If we are set to anything other than restore session,
+ // leave its value.
+ if (buttonPressed == 0) {
+ if (!restoreSession.value) {
+ if (startupPref === 3) {
+ Services.prefs.setIntPref("browser.startup.page", 1);
+ }
+ } else if (restoreSession.value) {
+ Services.prefs.setIntPref("browser.startup.page", 3);
+ }
+ }
+
this._quitSource = "unknown";
aCancelQuit.data = buttonPressed != 0;
diff --git a/netwerk/base/nsIPrompt.idl b/netwerk/base/nsIPrompt.idl
index 9ceaa6b89244d..a0f31c041d708 100644
--- a/netwerk/base/nsIPrompt.idl
+++ b/netwerk/base/nsIPrompt.idl
@@ -79,6 +79,17 @@ interface nsIPrompt : nsISupports
in wstring checkMsg,
inout boolean checkValue);
+ int32_t confirmEx2(in wstring dialogTitle,
+ in wstring text,
+ in unsigned long buttonFlags,
+ in wstring button0Title,
+ in wstring button1Title,
+ in wstring button2Title,
+ in wstring checkMsg,
+ inout boolean checkValue,
+ in wstring checkMsg2,
+ inout boolean checkValue2);
+
boolean prompt(in wstring dialogTitle,
in wstring text,
inout wstring value,
diff --git a/toolkit/components/prompts/content/commonDialog.js b/toolkit/components/prompts/content/commonDialog.js
index a18b7cbd6cf57..a516bd16330fa 100644
--- a/toolkit/components/prompts/content/commonDialog.js
+++ b/toolkit/components/prompts/content/commonDialog.js
@@ -98,6 +98,7 @@ function commonDialogOnLoad() {
infoTitle: document.getElementById("infoTitle"),
infoIcon: document.getElementById("infoIcon"),
checkbox: document.getElementById("checkbox"),
+ checkbox2: document.getElementById("checkbox2"),
checkboxContainer: document.getElementById("checkboxContainer"),
button3: dialog.getButton("extra2"),
button2: dialog.getButton("extra1"),
diff --git a/toolkit/components/prompts/content/commonDialog.xhtml b/toolkit/components/prompts/content/commonDialog.xhtml
index 02e0749a9ef93..11c65e3d720a4 100644
--- a/toolkit/components/prompts/content/commonDialog.xhtml
+++ b/toolkit/components/prompts/content/commonDialog.xhtml
@@ -97,6 +97,7 @@
+
diff --git a/toolkit/components/prompts/src/CommonDialog.sys.mjs b/toolkit/components/prompts/src/CommonDialog.sys.mjs
index a0812aa8eca21..752a4ed41e49d 100644
--- a/toolkit/components/prompts/src/CommonDialog.sys.mjs
+++ b/toolkit/components/prompts/src/CommonDialog.sys.mjs
@@ -33,6 +33,7 @@ CommonDialog.prototype = {
* @param [commonDialogEl] - Dialog element from commonDialog.xhtml,
* null for TabModalPrompts.
*/
+ // eslint-disable-next-line complexity
async onLoad(commonDialogEl = null) {
let isEmbedded = !!commonDialogEl?.ownerGlobal.docShell.chromeEventHandler;
@@ -73,6 +74,28 @@ CommonDialog.prototype = {
this.iconClass = ["question-icon"];
this.soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
+ case "confirmEx2":
+ var numButtons2 = 0;
+ if (this.args.button0Label) {
+ numButtons2++;
+ }
+ if (this.args.button1Label) {
+ numButtons2++;
+ }
+ if (this.args.button2Label) {
+ numButtons2++;
+ }
+ if (this.args.button3Label) {
+ numButtons2++;
+ }
+ if (numButtons2 == 0) {
+ throw new Error("A dialog with no buttons? Can not haz.");
+ }
+ this.numButtons = numButtons2;
+ this.hasInputField = false;
+ this.iconClass = ["question-icon"];
+ this.soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
+ break;
case "prompt":
this.numButtons = 2;
this.iconClass = ["question-icon"];
@@ -190,6 +213,15 @@ CommonDialog.prototype = {
this.ui.checkbox.checked = this.args.checked;
}
+ let label2 = this.args.checkLabel2;
+ if (label2) {
+ // Only show the checkbox if label has a value.
+ this.ui.checkboxContainer.hidden = false;
+ this.ui.checkboxContainer.clientTop; // style flush to assure binding is attached
+ this.setLabelForNode(this.ui.checkbox2, label2);
+ this.ui.checkbox2.checked = this.args.checked2;
+ }
+
// set the icon
let icon = this.ui.infoIcon;
if (icon) {
@@ -336,6 +368,10 @@ CommonDialog.prototype = {
this.args.checked = this.ui.checkbox.checked;
},
+ onCheckbox2() {
+ this.args.checked2 = this.ui.checkbox2.checked;
+ },
+
onButton0() {
this.args.promptActive = false;
this.args.ok = true;
diff --git a/toolkit/components/prompts/src/Prompter.sys.mjs b/toolkit/components/prompts/src/Prompter.sys.mjs
index fe44992378240..0a7cc1b736d32 100644
--- a/toolkit/components/prompts/src/Prompter.sys.mjs
+++ b/toolkit/components/prompts/src/Prompter.sys.mjs
@@ -306,6 +306,34 @@ Prompter.prototype = {
);
},
+ confirmEx2(
+ domWin,
+ title,
+ text,
+ flags,
+ button0,
+ button1,
+ button2,
+ checkLabel,
+ checkValue,
+ checkLabel2,
+ checkValue2
+ ) {
+ let p = this.pickPrompter({ domWin });
+ return p.confirmEx2(
+ title,
+ text,
+ flags,
+ button0,
+ button1,
+ button2,
+ checkLabel,
+ checkValue,
+ checkLabel2,
+ checkValue2
+ );
+ },
+
/**
* Puts up a dialog with up to 3 buttons and an optional, labeled checkbox.
* @param {BrowsingContext} browsingContext - The browsing context the
@@ -1467,6 +1495,66 @@ class ModalPrompter {
return args.buttonNumClicked;
}
+ confirmEx2(
+ title,
+ text,
+ flags,
+ button0,
+ button1,
+ button2,
+ checkLabel,
+ checkValue,
+ checkLabel2,
+ checkValue2,
+ extraArgs = {}
+ ) {
+ if (!title) {
+ title = InternalPromptUtils.getLocalizedString("Confirm");
+ }
+
+ let args = {
+ promptType: "confirmEx2",
+ title,
+ text,
+ checkLabel,
+ checked: this.async ? checkValue : checkValue.value,
+ checkLabel2,
+ checked2: this.async ? checkValue2 : checkValue2.value,
+ ok: false,
+ buttonNumClicked: 1,
+ ...extraArgs,
+ };
+
+ let [label0, label1, label2, defaultButtonNum, isDelayEnabled] =
+ InternalPromptUtils.confirmExHelper(flags, button0, button1, button2);
+
+ args.defaultButtonNum = defaultButtonNum;
+ args.enableDelay = isDelayEnabled;
+
+ if (label0) {
+ args.button0Label = label0;
+ if (label1) {
+ args.button1Label = label1;
+ if (label2) {
+ args.button2Label = label2;
+ }
+ }
+ }
+
+ if (this.async) {
+ return this.openPromptAsync(args, result => ({
+ checked: !!result.checked,
+ checked2: !!result.checked2,
+ buttonNumClicked: result.buttonNumClicked,
+ }));
+ }
+
+ this.openPromptSync(args);
+ checkValue.value = args.checked;
+ checkValue2.value = args.checked2;
+ return args.buttonNumClicked;
+ }
+
nsIPrompt_prompt(title, text, value, checkLabel, checkValue) {
if (!title) {
title = InternalPromptUtils.getLocalizedString("Prompt");
diff --git a/toolkit/components/windowwatcher/nsIPromptService.idl b/toolkit/components/windowwatcher/nsIPromptService.idl
index 9d910e0bcedfc..881434e719f56 100644
--- a/toolkit/components/windowwatcher/nsIPromptService.idl
+++ b/toolkit/components/windowwatcher/nsIPromptService.idl
@@ -333,6 +333,67 @@ interface nsIPromptService : nsISupports
in wstring aButton2Title,
in wstring aCheckMsg,
inout boolean aCheckState);
+
+ /**
+ * Puts up a dialog with up to 3 buttons and an optional, labeled checkbox.
+ *
+ * @param aParent
+ * The parent window or null.
+ * @param aDialogTitle
+ * Text to appear in the title of the dialog.
+ * @param aText
+ * Text to appear in the body of the dialog.
+ * @param aButtonFlags
+ * A combination of Button Flags.
+ * @param aButton0Title
+ * Used when button 0 uses TITLE_IS_STRING
+ * @param aButton1Title
+ * Used when button 1 uses TITLE_IS_STRING
+ * @param aButton2Title
+ * Used when button 2 uses TITLE_IS_STRING
+ * @param aCheckMsg
+ * Text to appear with the checkbox. Null if no checkbox.
+ * @param aCheckState
+ * Contains the initial checked state of the checkbox when this method
+ * is called and the final checked state after this method returns.
+ * @param aCheckMsg2
+ * A second text to appear with the checkbox. Null if no checkbox.
+ * @param aCheckState2
+ * Contains the initial checked state of the checkbox when this method
+ * is called and the final checked state after this method returns.
+ *
+ * @return index of the button pressed.
+ *
+ * Buttons are numbered 0 - 2. The implementation can decide whether the
+ * sequence goes from right to left or left to right. Button 0 is the
+ * default button unless one of the Button Default Flags is specified.
+ *
+ * A button may use a predefined title, specified by one of the Button Title
+ * Flags values. Each title value can be multiplied by a position value to
+ * assign the title to a particular button. If BUTTON_TITLE_IS_STRING is
+ * used for a button, the string parameter for that button will be used. If
+ * the value for a button position is zero, the button will not be shown.
+ *
+ * In general, aButtonFlags is constructed per the following example:
+ *
+ * aButtonFlags = (BUTTON_POS_0) * (BUTTON_TITLE_AAA) +
+ * (BUTTON_POS_1) * (BUTTON_TITLE_BBB) +
+ * BUTTON_POS_1_DEFAULT;
+ *
+ * where "AAA" and "BBB" correspond to one of the button titles.
+ */
+ int32_t confirmEx2(in mozIDOMWindowProxy aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ in unsigned long aButtonFlags,
+ in wstring aButton0Title,
+ in wstring aButton1Title,
+ in wstring aButton2Title,
+ in wstring aCheckMsg,
+ inout boolean aCheckState,
+ in wstring aCheckMsg2,
+ inout boolean aCheckState2);
+
/**
* Like confirmEx, but with a BrowsingContext as parent.
*
diff --git a/waterfox/browser/locales/en-US/waterfox.ftl b/waterfox/browser/locales/en-US/waterfox.ftl
index 20421900f4db4..963c3e416ec3e 100644
--- a/waterfox/browser/locales/en-US/waterfox.ftl
+++ b/waterfox/browser/locales/en-US/waterfox.ftl
@@ -258,4 +258,6 @@ telemetry-page-subtitle = Waterfox does not collect telemetry about your install
telemetry-privacy-policy = Privacy Policy
onboarding-grassroots-title = Supporting the grassroots
-onboarding-grassroots-subtitle = Thank you for using Waterfox, an independent, grassroots browser. With your support, we’re building a sustainable alternative to the big players out there.
\ No newline at end of file
+onboarding-grassroots-subtitle = Thank you for using Waterfox, an independent, grassroots browser. With your support, we’re building a sustainable alternative to the big players out there.
+
+tabbrowser-confirm-session-restore-checkbox = Open previous windows and tabs
\ No newline at end of file