feat: add session restore checkbox when quitting the browser
(cherry picked from commit 25890584ab485be765a2e4eff47e38f903a0ae24)
This commit is contained in:
@@ -11,7 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "gTabBrowserLocalization", function () {
|
||||
return new Localization(["browser/tabbrowser.ftl"], true);
|
||||
return new Localization(["browser/tabbrowser.ftl", "browser/waterfox.ftl"], true);
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -1532,6 +1532,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.
|
||||
@@ -1585,11 +1597,14 @@ BrowserGlue.prototype = {
|
||||
checkboxLabelId = "tabbrowser-ask-close-tabs-checkbox";
|
||||
}
|
||||
|
||||
const [title, quitButtonLabel, checkboxLabel] =
|
||||
let checkboxLabelId2 = "tabbrowser-confirm-session-restore-checkbox";
|
||||
|
||||
const [title, quitButtonLabel, checkboxLabel, checkboxLabel2] =
|
||||
win.gBrowser.tabLocalization.formatMessagesSync([
|
||||
titleId,
|
||||
quitButtonLabelId,
|
||||
checkboxLabelId,
|
||||
checkboxLabelId2,
|
||||
]);
|
||||
|
||||
// Only format the "close current tab" message if needed
|
||||
@@ -1621,7 +1636,7 @@ BrowserGlue.prototype = {
|
||||
}
|
||||
|
||||
// buttonPressed will be 0 for close all, 1 for cancel (don't close/quit), 2 for close current tab
|
||||
let buttonPressed = Services.prompt.confirmEx(
|
||||
let buttonPressed = Services.prompt.confirmEx2(
|
||||
win,
|
||||
title.value,
|
||||
null,
|
||||
@@ -1630,7 +1645,9 @@ BrowserGlue.prototype = {
|
||||
null,
|
||||
showCloseCurrentTabOption ? closeTabButtonLabel.value : null,
|
||||
checkboxLabel.value,
|
||||
warnOnClose
|
||||
warnOnClose,
|
||||
checkboxLabel2.value,
|
||||
restoreSession
|
||||
);
|
||||
|
||||
// If the user has unticked the box, and has confirmed closing, stop showing
|
||||
@@ -1648,6 +1665,18 @@ BrowserGlue.prototype = {
|
||||
win.gBrowser.removeTab(win.gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
});
|
||||
ChromeUtils.defineLazyGetter(this, "tabLocalization", () => {
|
||||
return new Localization(
|
||||
["browser/tabbrowser.ftl", "branding/brand.ftl"],
|
||||
["browser/tabbrowser.ftl", "branding/brand.ftl", "browser/waterfox.ftl"],
|
||||
true
|
||||
);
|
||||
});
|
||||
@@ -3806,26 +3806,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) {
|
||||
restoreSession = { value: false };
|
||||
} else {
|
||||
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-ask-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;
|
||||
if (Services.prefs.getBoolPref("browser.tabs.warnOnCloseOtherTabs")) {
|
||||
buttonPressed = ps.confirmEx(
|
||||
window,
|
||||
title,
|
||||
null,
|
||||
@@ -3836,6 +3850,21 @@
|
||||
checkboxLabel,
|
||||
warnOnClose
|
||||
);
|
||||
} else if (Services.prefs.getBoolPref("browser.tabs.warnOnClose")) {
|
||||
buttonPressed = ps.confirmEx2(
|
||||
window,
|
||||
title,
|
||||
null,
|
||||
flags,
|
||||
button,
|
||||
null,
|
||||
null,
|
||||
checkboxLabel,
|
||||
warnOnClose,
|
||||
checkboxLabel2,
|
||||
restoreSession
|
||||
);
|
||||
}
|
||||
|
||||
var reallyClose = buttonPressed == 0;
|
||||
|
||||
@@ -3848,6 +3877,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,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,
|
||||
|
||||
@@ -95,6 +95,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"),
|
||||
@@ -140,6 +141,9 @@ function commonDialogOnLoad() {
|
||||
case "checkbox":
|
||||
Dialog.onCheckbox();
|
||||
break;
|
||||
case "checkbox2":
|
||||
Dialog.onCheckbox2();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
<div />
|
||||
<!-- spacer -->
|
||||
<xul:checkbox id="checkbox" />
|
||||
<xul:checkbox id="checkbox2" />
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
@@ -78,6 +78,28 @@ export class CommonDialog {
|
||||
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"];
|
||||
@@ -171,13 +193,35 @@ export class CommonDialog {
|
||||
let infoBody = this.ui.infoBody;
|
||||
infoBody.appendChild(infoBody.ownerDocument.createTextNode(croppedMessage));
|
||||
|
||||
// WATERFOX: Check if both labels are undefined before deciding to hide the container.
|
||||
// This first checks if both labels are undefined before hiding the container.
|
||||
// If not, it shows the container and then proceeds to render each checkbox if its corresponding label is defined.
|
||||
let label = this.args.checkLabel;
|
||||
if (label) {
|
||||
// Only show the checkbox if label has a value.
|
||||
let label2 = this.args.checkLabel2;
|
||||
|
||||
if (!label && !label2) {
|
||||
// Hide everything if both labels undefined
|
||||
this.ui.checkboxContainer.hidden = true;
|
||||
} else {
|
||||
// Show container
|
||||
this.ui.checkboxContainer.hidden = false;
|
||||
this.ui.checkboxContainer.clientTop; // style flush to assure binding is attached
|
||||
this.ui.checkboxContainer.clientTop;
|
||||
|
||||
if (label) {
|
||||
this.setLabelForNode(this.ui.checkbox, label);
|
||||
this.ui.checkbox.hidden = false;
|
||||
this.ui.checkbox.checked = this.args.checked;
|
||||
} else {
|
||||
this.ui.checkbox.hidden = true;
|
||||
}
|
||||
|
||||
if (label2) {
|
||||
this.setLabelForNode(this.ui.checkbox2, label2);
|
||||
this.ui.checkbox2.hidden = false;
|
||||
this.ui.checkbox2.checked = this.args.checked2;
|
||||
} else {
|
||||
this.ui.checkbox2.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
// set the icon
|
||||
@@ -310,6 +354,10 @@ export class CommonDialog {
|
||||
this.args.checked = this.ui.checkbox.checked;
|
||||
}
|
||||
|
||||
onCheckbox2() {
|
||||
this.args.checked2 = this.ui.checkbox2.checked;
|
||||
}
|
||||
|
||||
onButton0() {
|
||||
this.args.promptActive = false;
|
||||
this.args.ok = true;
|
||||
|
||||
@@ -312,6 +312,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
|
||||
@@ -1524,6 +1552,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");
|
||||
|
||||
@@ -363,6 +363,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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user