зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1655866: Part 1 - Add async version of beforeUnloadCheck prompt. r=geckoview-reviewers,Gijs,agi
Differential Revision: https://phabricator.services.mozilla.com/D88314
This commit is contained in:
Родитель
3e0a30ea57
Коммит
2d863e9e4c
|
@ -71,7 +71,7 @@ class PromptCollection {
|
|||
return buttonPressed === 0;
|
||||
}
|
||||
|
||||
beforeUnloadCheck(browsingContext) {
|
||||
beforeUnloadCheckInternal(browsingContext, sync) {
|
||||
let title;
|
||||
let message;
|
||||
let leaveLabel;
|
||||
|
@ -94,9 +94,17 @@ class PromptCollection {
|
|||
}
|
||||
|
||||
let contentViewer = browsingContext?.docShell?.contentViewer;
|
||||
let modalType = contentViewer?.isTabModalPromptAllowed
|
||||
? Ci.nsIPromptService.MODAL_TYPE_CONTENT
|
||||
: Ci.nsIPromptService.MODAL_TYPE_WINDOW;
|
||||
|
||||
// TODO: Do we really want to allow modal dialogs from inactive
|
||||
// content viewers at all, particularly for permit unload prompts?
|
||||
let modalAllowed = contentViewer
|
||||
? contentViewer.isTabModalPromptAllowed
|
||||
: browsingContext.ancestorsAreCurrent;
|
||||
|
||||
let modalType =
|
||||
Ci.nsIPromptService[
|
||||
modalAllowed ? "MODAL_TYPE_CONTENT" : "MODAL_TYPE_WINDOW"
|
||||
];
|
||||
|
||||
let buttonFlags =
|
||||
Ci.nsIPromptService.BUTTON_POS_0_DEFAULT |
|
||||
|
@ -105,20 +113,55 @@ class PromptCollection {
|
|||
(Ci.nsIPromptService.BUTTON_TITLE_IS_STRING *
|
||||
Ci.nsIPromptService.BUTTON_POS_1);
|
||||
|
||||
let buttonPressed = Services.prompt.confirmExBC(
|
||||
browsingContext,
|
||||
modalType,
|
||||
title,
|
||||
message,
|
||||
buttonFlags,
|
||||
leaveLabel,
|
||||
stayLabel,
|
||||
null,
|
||||
null,
|
||||
{}
|
||||
);
|
||||
if (sync) {
|
||||
let buttonNumClicked = Services.prompt.confirmExBC(
|
||||
browsingContext,
|
||||
modalType,
|
||||
title,
|
||||
message,
|
||||
buttonFlags,
|
||||
leaveLabel,
|
||||
stayLabel,
|
||||
null,
|
||||
null,
|
||||
{}
|
||||
);
|
||||
|
||||
return buttonPressed === 0;
|
||||
return buttonNumClicked === 0;
|
||||
}
|
||||
|
||||
return Services.prompt
|
||||
.asyncConfirmEx(
|
||||
browsingContext,
|
||||
modalType,
|
||||
title,
|
||||
message,
|
||||
buttonFlags,
|
||||
leaveLabel,
|
||||
stayLabel,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
// Tell the prompt service that this is a permit unload prompt
|
||||
// so that it can set the appropriate flag on the detail object
|
||||
// of the events it dispatches. This happens automatically for
|
||||
// the sync version of the prompt, which is always dispatched
|
||||
// from the content process, where the flag comes from the
|
||||
// content viewer which triggers the prompt.
|
||||
{ inPermitUnload: true }
|
||||
)
|
||||
.then(
|
||||
result =>
|
||||
result.QueryInterface(Ci.nsIPropertyBag2).get("buttonNumClicked") == 0
|
||||
);
|
||||
}
|
||||
|
||||
beforeUnloadCheck(browsingContext) {
|
||||
return this.beforeUnloadCheckInternal(browsingContext, /* sync */ true);
|
||||
}
|
||||
|
||||
asyncBeforeUnloadCheck(browsingContext) {
|
||||
return this.beforeUnloadCheckInternal(browsingContext, /* sync */ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,9 +187,6 @@ for (const [bundleName, bundleUrl] of Object.entries(BUNDLES)) {
|
|||
);
|
||||
}
|
||||
|
||||
PromptCollection.prototype.classID = Components.ID(
|
||||
"{7913837c-9623-11ea-bb37-0242ac130002}"
|
||||
);
|
||||
PromptCollection.prototype.QueryInterface = ChromeUtils.generateQI([
|
||||
"nsIPromptCollection",
|
||||
]);
|
||||
|
|
|
@ -68,6 +68,8 @@ interface BrowsingContext {
|
|||
|
||||
readonly attribute WindowContext? topWindowContext;
|
||||
|
||||
readonly attribute boolean ancestorsAreCurrent;
|
||||
|
||||
[SetterThrows] attribute [TreatNullAs=EmptyString] DOMString customPlatform;
|
||||
|
||||
[SetterThrows] attribute [TreatNullAs=EmptyString] DOMString customUserAgent;
|
||||
|
|
|
@ -37,11 +37,17 @@ class PromptCollection {
|
|||
const result = prompter.showPrompt(msg);
|
||||
return !!result?.allow;
|
||||
}
|
||||
}
|
||||
|
||||
PromptCollection.prototype.classID = Components.ID(
|
||||
"{3e30d2a0-9934-11ea-bb37-0242ac130002}"
|
||||
);
|
||||
asyncBeforeUnloadCheck(browsingContext) {
|
||||
return new Promise(resolve => {
|
||||
const msg = {
|
||||
type: "beforeUnload",
|
||||
};
|
||||
const prompter = new GeckoViewPrompter(browsingContext);
|
||||
prompter.asyncShowPrompt(msg, resolve);
|
||||
}).then(result => !!result?.allow);
|
||||
}
|
||||
}
|
||||
|
||||
PromptCollection.prototype.QueryInterface = ChromeUtils.generateQI([
|
||||
"nsIPromptCollection",
|
||||
|
|
|
@ -346,6 +346,7 @@ Prompter.prototype = {
|
|||
* @param {String} checkLabel - Text to appear with the checkbox.
|
||||
* Null if no checkbox.
|
||||
* @param {Boolean} checkValue - The initial checked state of the checkbox.
|
||||
* @param {Object} [extraArgs] - Extra arguments for the prompt metadata.
|
||||
* @returns {Promise<nsIPropertyBag<{ buttonNumClicked: Number, checked: Boolean }>>}
|
||||
*/
|
||||
asyncConfirmEx(browsingContext, modalType, ...promptArgs) {
|
||||
|
@ -1400,7 +1401,8 @@ class ModalPrompter {
|
|||
button1,
|
||||
button2,
|
||||
checkLabel,
|
||||
checkValue
|
||||
checkValue,
|
||||
extraArgs = {}
|
||||
) {
|
||||
if (!title) {
|
||||
title = PromptUtils.getLocalizedString("Confirm");
|
||||
|
@ -1414,6 +1416,7 @@ class ModalPrompter {
|
|||
checked: this.async ? checkValue : checkValue.value,
|
||||
ok: false,
|
||||
buttonNumClicked: 1,
|
||||
...extraArgs,
|
||||
};
|
||||
|
||||
let [
|
||||
|
|
|
@ -23,6 +23,13 @@ interface nsIPromptCollection : nsISupports
|
|||
*/
|
||||
boolean beforeUnloadCheck(in BrowsingContext aBrowsingContext);
|
||||
|
||||
/**
|
||||
* Like `beforeUnloadCheck`, but does not spin a nested event loop, and
|
||||
* instead returns a promise which resolves to true if navigation should be
|
||||
* allowed, and false if not.
|
||||
*/
|
||||
Promise asyncBeforeUnloadCheck(in BrowsingContext aBrowsingContext);
|
||||
|
||||
/**
|
||||
* Puts up a dialog for the confirm repost prompt.
|
||||
*
|
||||
|
|
|
@ -364,7 +364,8 @@ interface nsIPromptService : nsISupports
|
|||
in wstring aButton1Title,
|
||||
in wstring aButton2Title,
|
||||
in wstring aCheckMsg,
|
||||
in boolean aCheckState);
|
||||
in boolean aCheckState,
|
||||
[optional] in jsval aExtraArgs);
|
||||
/**
|
||||
* Puts up a dialog with an edit field and an optional, labeled checkbox.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче