diff --git a/browser/metro/base/content/browser-ui.js b/browser/metro/base/content/browser-ui.js index e30d776c492..cf97327b0ea 100644 --- a/browser/metro/base/content/browser-ui.js +++ b/browser/metro/base/content/browser-ui.js @@ -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 */ diff --git a/browser/metro/base/tests/mochitest/browser_crashprompt.js b/browser/metro/base/tests/mochitest/browser_crashprompt.js index 83a3d713fbb..41951a44df1 100644 --- a/browser/metro/base/tests/mochitest/browser_crashprompt.js +++ b/browser/metro/base/tests/mochitest/browser_crashprompt.js @@ -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"); } }); diff --git a/browser/metro/locales/jar.mn b/browser/metro/locales/jar.mn index 0fde27912ce..5f93de767d2 100644 --- a/browser/metro/locales/jar.mn +++ b/browser/metro/locales/jar.mn @@ -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)