зеркало из https://github.com/mozilla/gecko-dev.git
bug 866304 DialogUI "modals" cleanup patch. Removes the "modals" portions of DialogUI. Converts the crash reporter prompt to use nsIPromptService.confirmEx instead of DialogUI.importModal. r=mbrubeck
The crash reporter prompt is the only consumer of DialogUI.importModal and related code. The "modals" concept that DialogUI implements should go away in favor of tab-modal dialogs and tab-agnostic notifications (e.g. flyouts). I don't think that the crash reporter prompt should be a tab modal dialog; I'd prefer to see it become an about: page or perhaps a flyout. Making it a tab-modal prompt was just the easiest thing to do in this set of patches.
This commit is contained in:
Родитель
808e8c5722
Коммит
cd4d6bb8fa
|
@ -258,23 +258,49 @@ var BrowserUI = {
|
|||
return;
|
||||
}
|
||||
let lastCrashID = this.lastCrashID;
|
||||
|
||||
if (!lastCrashID || !lastCrashID.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let shouldReport = Services.prefs.getBoolPref("app.crashreporter.autosubmit");
|
||||
let didPrompt = Services.prefs.getBoolPref("app.crashreporter.prompted");
|
||||
|
||||
if (!shouldReport && !didPrompt) {
|
||||
// We have a crash to submit, we haven't prompted for approval yet,
|
||||
// and the auto-submit pref is false, prompt. The dialog will call
|
||||
// startupCrashCheck again if the user approves.
|
||||
let crashBundle = Services.strings.createBundle("chrome://browser/locale/crashprompt.properties");
|
||||
let title = crashBundle.GetStringFromName("crashprompt.dialog.title");
|
||||
let acceptbutton = crashBundle.GetStringFromName("crashprompt.dialog.acceptbutton");
|
||||
let refusebutton = crashBundle.GetStringFromName("crashprompt.dialog.refusebutton");
|
||||
let bodyText = crashBundle.GetStringFromName("crashprompt.dialog.statement1");
|
||||
|
||||
let buttonPressed =
|
||||
Services.prompt.confirmEx(
|
||||
null,
|
||||
title,
|
||||
bodyText,
|
||||
Ci.nsIPrompt.BUTTON_POS_0 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING
|
||||
+ Ci.nsIPrompt.BUTTON_POS_1 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING
|
||||
+ Ci.nsIPrompt.BUTTON_POS_1_DEFAULT,
|
||||
acceptbutton,
|
||||
refusebutton,
|
||||
null,
|
||||
null,
|
||||
{ value: false });
|
||||
|
||||
Services.prefs.setBoolPref("app.crashreporter.prompted", true);
|
||||
DialogUI.importModal(document, "chrome://browser/content/prompt/crash.xul");
|
||||
return;
|
||||
|
||||
if (buttonPressed == 0) {
|
||||
Services.prefs.setBoolPref('app.crashreporter.autosubmit', true);
|
||||
BrowserUI.crashReportingPrefChanged(true);
|
||||
shouldReport = true;
|
||||
} else {
|
||||
Services.prefs.setBoolPref('app.crashreporter.autosubmit', false);
|
||||
BrowserUI.crashReportingPrefChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
// We've already prompted, return if the user doesn't want to report.
|
||||
if (!shouldReport && didPrompt) {
|
||||
if (!shouldReport) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -734,11 +760,6 @@ var BrowserUI = {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check open modal elements
|
||||
if (DialogUI.modals.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check open panel
|
||||
if (PanelUI.isVisible) {
|
||||
PanelUI.hide();
|
||||
|
@ -1109,7 +1130,6 @@ var StartUI = {
|
|||
if (section.init)
|
||||
section.init();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
|
@ -1315,66 +1335,6 @@ var DialogUI = {
|
|||
window.addEventListener("mousedown", this, true);
|
||||
},
|
||||
|
||||
/*******************************************
|
||||
* Modal popups
|
||||
*/
|
||||
|
||||
get modals() {
|
||||
return document.getElementsByClassName("modal-block");
|
||||
},
|
||||
|
||||
importModal: function importModal(aParent, aSrc, aArguments) {
|
||||
// load the dialog with a synchronous XHR
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
|
||||
xhr.open("GET", aSrc, false);
|
||||
xhr.overrideMimeType("text/xml");
|
||||
xhr.send(null);
|
||||
if (!xhr.responseXML)
|
||||
return null;
|
||||
|
||||
let currentNode;
|
||||
let nodeIterator = xhr.responseXML.createNodeIterator(xhr.responseXML, NodeFilter.SHOW_TEXT, null, false);
|
||||
while (!!(currentNode = nodeIterator.nextNode())) {
|
||||
let trimmed = currentNode.nodeValue.replace(/^\s\s*/, "").replace(/\s\s*$/, "");
|
||||
if (!trimmed.length)
|
||||
currentNode.parentNode.removeChild(currentNode);
|
||||
}
|
||||
|
||||
let doc = xhr.responseXML.documentElement;
|
||||
|
||||
let dialog = null;
|
||||
|
||||
// we need to insert before context-container if we want allow pasting (using
|
||||
// the context menu) into dialogs
|
||||
let contentMenuContainer = document.getElementById("context-container");
|
||||
let parentNode = contentMenuContainer.parentNode;
|
||||
|
||||
// emit DOMWillOpenModalDialog event
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("DOMWillOpenModalDialog", true, false);
|
||||
let dispatcher = aParent || getBrowser();
|
||||
dispatcher.dispatchEvent(event);
|
||||
|
||||
// create a full-screen semi-opaque box as a background or reuse
|
||||
// the existing one.
|
||||
let back = document.getElementById("dialog-modal-block");
|
||||
if (!back) {
|
||||
back = document.createElement("box");
|
||||
} else {
|
||||
while (back.hasChildNodes()) {
|
||||
back.removeChild(back.firstChild);
|
||||
}
|
||||
}
|
||||
back.setAttribute("class", "modal-block");
|
||||
back.setAttribute("id", "dialog-modal-block");
|
||||
dialog = back.appendChild(document.importNode(doc, true));
|
||||
parentNode.insertBefore(back, contentMenuContainer);
|
||||
|
||||
dialog.arguments = aArguments;
|
||||
dialog.parent = aParent;
|
||||
return dialog;
|
||||
},
|
||||
|
||||
/*******************************************
|
||||
* Popups
|
||||
*/
|
||||
|
|
|
@ -30,6 +30,7 @@ var newFactory = {
|
|||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
|
||||
};
|
||||
|
||||
let oldPrompt;
|
||||
function initMockAppInfo() {
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
gAppInfoClassID = registrar.contractIDToCID(CONTRACT_ID);
|
||||
|
@ -38,6 +39,8 @@ function initMockAppInfo() {
|
|||
var components = [MockAppInfo];
|
||||
registrar.registerFactory(gAppInfoClassID, "", CONTRACT_ID, newFactory);
|
||||
gIncOldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
|
||||
|
||||
oldPrompt = Services.prompt;
|
||||
}
|
||||
|
||||
function cleanupMockAppInfo() {
|
||||
|
@ -47,6 +50,8 @@ function cleanupMockAppInfo() {
|
|||
registrar.registerFactory(gAppInfoClassID, "", CONTRACT_ID, gIncOldFactory);
|
||||
}
|
||||
gIncOldFactory = null;
|
||||
|
||||
Services.prompt = oldPrompt;
|
||||
}
|
||||
|
||||
MockAppInfo.prototype = {
|
||||
|
@ -74,80 +79,72 @@ gTests.push({
|
|||
set promptedPref(aValue) {
|
||||
Services.prefs.setBoolPref('app.crashreporter.prompted', aValue);
|
||||
},
|
||||
get dialog() {
|
||||
return document.getElementById("crash-prompt-dialog");
|
||||
},
|
||||
|
||||
run: function() {
|
||||
MockAppInfo.crashid = "testid";
|
||||
|
||||
// never prompted, autosubmit off. We should prompt.
|
||||
// For the first set of tests, we want to be able to simulate that a
|
||||
// specific button of the crash reporter prompt was pressed
|
||||
Services.prompt = {
|
||||
confirmEx: function() {
|
||||
return this.retVal;
|
||||
}
|
||||
};
|
||||
|
||||
// Test 1:
|
||||
// Pressing cancel button on the crash reporter prompt
|
||||
|
||||
// Set the crash reporter prefs to indicate that the prompt should appear
|
||||
this.autosubmitPref = false;
|
||||
this.promptedPref = false;
|
||||
|
||||
// We will simulate that "button 1" (which should be the cancel button)
|
||||
// was pressed
|
||||
Services.prompt.retVal = 1;
|
||||
|
||||
BrowserUI.startupCrashCheck();
|
||||
|
||||
yield waitForMs(100);
|
||||
|
||||
ok(this.dialog, "prompt dialog exists");
|
||||
ok(!this.dialog.hidden, "prompt dialog is visible");
|
||||
|
||||
// user refuses crash reporting opt-in
|
||||
let refuseButton = document.getElementById("crash-button-refuse");
|
||||
sendElementTap(window, refuseButton, 20, 20);
|
||||
|
||||
yield waitForCondition(() => this.dialog == null);
|
||||
|
||||
ok(!this.autosubmitPref, "auto submit disabled?");
|
||||
ok(this.promptedPref, "prompted should be true");
|
||||
|
||||
// never prompted, autosubmit off. We should prompt.
|
||||
|
||||
// Test 2:
|
||||
// Pressing 'ok' button on the crash reporter prompt
|
||||
|
||||
// Set the crash reporter prefs to indicate that the prompt should appear
|
||||
this.autosubmitPref = false;
|
||||
this.promptedPref = false;
|
||||
|
||||
// should query on the first call to startupCrashCheck
|
||||
gMockAppInfoQueried = false;
|
||||
|
||||
// We will simulate that "button 0" (which should be the OK button)
|
||||
// was pressed
|
||||
Services.prompt.retVal = 0;
|
||||
|
||||
BrowserUI.startupCrashCheck();
|
||||
|
||||
yield waitForMs(100);
|
||||
|
||||
ok(this.dialog, "prompt dialog exists");
|
||||
ok(!this.dialog.hidden, "prompt dialog is visible");
|
||||
ok(gMockAppInfoQueried, "id queried");
|
||||
|
||||
// should query again when the user submits
|
||||
gMockAppInfoQueried = false;
|
||||
|
||||
// user accepts crash reporting opt-in
|
||||
let submitButton = document.getElementById("crash-button-accept");
|
||||
sendElementTap(window, submitButton, 20, 20);
|
||||
|
||||
yield waitForCondition(() => this.dialog == null);
|
||||
|
||||
ok(this.autosubmitPref, "auto submit enabled?");
|
||||
ok(this.promptedPref, "prompted should be true");
|
||||
ok(gMockAppInfoQueried, "id queried");
|
||||
|
||||
// prompted, auto-submit off. We shouldn't prompt.
|
||||
|
||||
// For the remaining tests, attempting to launch the crash reporter
|
||||
// prompt would be incorrect behavior
|
||||
Services.prompt.confirmEx = function() {
|
||||
ok(false, "Should not attempt to launch crash reporter prompt");
|
||||
};
|
||||
|
||||
// Test 3:
|
||||
// Prompt should not appear if pref indicates that user has already
|
||||
// been prompted
|
||||
this.autosubmitPref = false;
|
||||
this.promptedPref = true;
|
||||
|
||||
BrowserUI.startupCrashCheck();
|
||||
|
||||
yield waitForMs(100);
|
||||
|
||||
ok(!this.dialog, "prompt dialog does not exists");
|
||||
|
||||
// never prompted, autosubmit *on*. We shouldn't prompt.
|
||||
// Test 4:
|
||||
// Prompt should not appear if pref indicates that autosubmit is on
|
||||
this.autosubmitPref = true;
|
||||
this.promptedPref = false;
|
||||
|
||||
BrowserUI.startupCrashCheck();
|
||||
|
||||
yield waitForMs(100);
|
||||
|
||||
ok(!this.dialog, "prompt dialog does not exists");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
locale/browser/sync.properties (%chrome/sync.properties)
|
||||
locale/browser/passwordmgr.properties (%chrome/passwordmgr.properties)
|
||||
locale/browser/phishing.dtd (%chrome/phishing.dtd)
|
||||
locale/browser/crashprompt.dtd (%chrome/crashprompt.dtd)
|
||||
locale/browser/crashprompt.properties (%chrome/crashprompt.properties)
|
||||
locale/browser/aboutAddons.dtd (%chrome/aboutAddons.dtd)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче