Bug 1694229 - Update slow script warning visuals r=florian

This patch removes the wait button on the slow script warning, on the suspicion
that it is confusing to the user since it's redundant with the close button. It
also changes the text of the notification to blame the hanging tab.

Differential Revision: https://phabricator.services.mozilla.com/D106015
This commit is contained in:
Doug Thayer 2021-02-27 18:22:32 +00:00
Родитель 52910b99c8
Коммит db50f52ea7
4 изменённых файлов: 85 добавлений и 27 удалений

Просмотреть файл

@ -62,7 +62,7 @@ add_task(async function test_slow_content_script() {
ok(text.includes("\u201cSlow Script Extension\u201d"), "Label is correct");
let stopButton = notification.querySelector("[label='Stop It']");
let stopButton = notification.querySelector("[label='Stop']");
stopButton.click();
BrowserTestUtils.removeTab(gBrowser.selectedTab);

Просмотреть файл

@ -693,17 +693,19 @@ dataReportingNotification.button.label = Choose What I Share
dataReportingNotification.button.accessKey = C
# Process hang reporter
processHang.label = A web page is slowing down your browser. What would you like to do?
# LOCALIZATION NOTE (processHang.nonspecific_tab.label): %1$S is the name of the product (e.g., Firefox)
processHang.nonspecific_tab.label = A web page is slowing down %1$S. To speed up your browser, stop that page.
# LOCALIZATION NOTE (processHang.specific_tab.label): %1$S is the title of the tab.
# %2$S is the name of the product (e.g., Firefox)
processHang.specific_tab.label = “%1$S” is slowing down %2$S. To speed up your browser, stop that page.
# LOCALIZATION NOTE (processHang.add-on.label): %1$S is the name of the
# extension. %2$S is the name of the product (e.g., Firefox)
processHang.add-on.label = A script in the extension “%1$S” is causing %2$S to slow down.
processHang.add-on.learn-more.text = Learn more
processHang.button_stop.label = Stop It
processHang.button_stop.label2 = Stop
processHang.button_stop.accessKey = S
processHang.button_stop_sandbox.label = Temporarily Disable Extension on Page
processHang.button_stop_sandbox.accessKey = A
processHang.button_wait.label = Wait
processHang.button_wait.accessKey = W
processHang.button_debug.label = Debug Script
processHang.button_debug.accessKey = D

Просмотреть файл

@ -12,6 +12,40 @@ const { AppConstants } = ChromeUtils.import(
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
/**
* Elides the middle of a string by replacing it with an elipsis if it is
* longer than `threshold` characters. Does its best to not break up grapheme
* clusters.
*/
function elideMiddleOfString(str, threshold) {
const searchDistance = 5;
const stubLength = threshold / 2 - searchDistance;
if (str.length <= threshold || stubLength < searchDistance) {
return str;
}
function searchElisionPoint(position) {
let unsplittableCharacter = c => /[\p{M}\uDC00-\uDFFF]/u.test(c);
for (let i = 0; i < searchDistance; i++) {
if (!unsplittableCharacter(str[position + i])) {
return position + i;
}
if (!unsplittableCharacter(str[position - i])) {
return position - i;
}
}
return position;
}
let elisionStart = searchElisionPoint(stubLength);
let elisionEnd = searchElisionPoint(str.length - stubLength);
if (elisionStart < elisionEnd) {
str = str.slice(0, elisionStart) + "\u2026" + str.slice(elisionEnd);
}
return str;
}
/**
* This JSM is responsible for observing content process hang reports
* and asking the user what to do about them. See nsIHangReport for
@ -528,35 +562,29 @@ var ProcessHangMonitor = {
"https://support.mozilla.org/kb/warning-unresponsive-script#w_other-causes",
},
{
label: bundle.getString("processHang.button_stop.label"),
label: bundle.getString("processHang.button_stop.label2"),
accessKey: bundle.getString("processHang.button_stop.accessKey"),
callback() {
ProcessHangMonitor.stopIt(win);
},
},
{
label: bundle.getString("processHang.button_wait.label"),
accessKey: bundle.getString("processHang.button_wait.accessKey"),
callback() {
ProcessHangMonitor.waitLonger(win);
},
},
];
let message = bundle.getString("processHang.label");
let message;
let doc = win.document;
let brandShortName = doc
.getElementById("bundle_brand")
.getString("brandShortName");
if (report.addonId) {
let aps = Cc["@mozilla.org/addons/policy-service;1"].getService(
Ci.nsIAddonPolicyService
);
let doc = win.document;
let brandBundle = doc.getElementById("bundle_brand");
let addonName = aps.getExtensionName(report.addonId);
message = bundle.getFormattedString("processHang.add-on.label", [
addonName,
brandBundle.getString("brandShortName"),
brandShortName,
]);
buttons.unshift({
@ -568,6 +596,24 @@ var ProcessHangMonitor = {
ProcessHangMonitor.stopGlobal(win);
},
});
} else {
let scriptBrowser = report.scriptBrowser;
let tab = scriptBrowser?.ownerGlobal.gBrowser?.getTabForBrowser(
scriptBrowser
);
if (!tab) {
message = bundle.getFormattedString(
"processHang.nonspecific_tab.label",
[brandShortName]
);
} else {
let title = tab.getAttribute("label");
title = elideMiddleOfString(title, 60);
message = bundle.getFormattedString("processHang.specific_tab.label", [
title,
brandShortName,
]);
}
}
if (AppConstants.MOZ_DEV_EDITION && report.hangType == report.SLOW_SCRIPT) {
@ -585,7 +631,12 @@ var ProcessHangMonitor = {
"process-hang",
"chrome://browser/content/aboutRobots-icon.png",
win.gHighPriorityNotificationBox.PRIORITY_WARNING_HIGH,
buttons
buttons,
event => {
if (event == "dismissed") {
ProcessHangMonitor.waitLonger(win);
}
}
);
},

Просмотреть файл

@ -125,7 +125,7 @@ TestHangReport.prototype = {
};
// on dev edition we add a button for js debugging of hung scripts.
let buttonCount = AppConstants.MOZ_DEV_EDITION ? 3 : 2;
let buttonCount = AppConstants.MOZ_DEV_EDITION ? 2 : 1;
add_task(async function setup() {
// Create a fake WebExtensionPolicy that we can use for
@ -162,13 +162,13 @@ add_task(async function terminateScriptTest() {
let buttons = notification.currentNotification.getElementsByTagName("button");
is(buttons.length, buttonCount, "proper number of buttons");
// Click the "Stop It" button, we should get a terminate script callback
// Click the "Stop" button, we should get a terminate script callback
buttons[0].click();
let action = await hangReport.promise;
is(
action,
TEST_ACTION_TERMSCRIPT,
"Clicking 'Stop It' should have terminated the script."
"Clicking 'Stop' should have terminated the script."
);
});
@ -184,6 +184,11 @@ add_task(async function waitForScriptTest() {
let buttons = notification.currentNotification.getElementsByTagName("button");
is(buttons.length, buttonCount, "proper number of buttons");
let toolbarbuttons = notification.currentNotification.getElementsByTagName(
"toolbarbutton"
);
is(toolbarbuttons.length, 1, "proper number of toolbarbuttons");
let closeButton = toolbarbuttons[0];
await pushPrefs(["browser.hangNotification.waitPeriod", 1000]);
@ -206,7 +211,7 @@ add_task(async function waitForScriptTest() {
});
// Click the "Wait" button this time, we shouldn't get a callback at all.
buttons[1].click();
closeButton.click();
// send another hang pulse, we should not get a notification here
Services.obs.notifyObservers(hangReport, "process-hang-report");
@ -256,17 +261,17 @@ add_task(async function terminatePluginTest() {
let notification = await promise;
let buttons = notification.currentNotification.getElementsByTagName("button");
// Plugin hangs only ever show 2 buttons in the notification - even in
// Plugin hangs only ever show 1 button in the notification - even in
// DevEdition.
is(buttons.length, 2, "proper number of buttons");
is(buttons.length, 1, "proper number of buttons");
// Click the "Stop It" button, we should get a terminate script callback
// Click the "Stop" button, we should get a terminate script callback
buttons[0].click();
let action = await hangReport.promise;
is(
action,
TEST_ACTION_TERMPLUGIN,
"Expected the 'Stop it' button to terminate the plug-in"
"Expected the 'Stop' button to terminate the plug-in"
);
});