Bug 1525175 - Part 3: Move system message bars into HTML views r=rpl,fluent-reviewers,flod

Differential Revision: https://phabricator.services.mozilla.com/D47804

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mark Striemer 2019-11-01 16:01:38 +00:00
Родитель 2fa34a861c
Коммит 966031d6f8
9 изменённых файлов: 207 добавлений и 328 удалений

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

@ -0,0 +1,32 @@
# coding=utf8
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
from __future__ import absolute_import
import fluent.syntax.ast as FTL
from fluent.migrate.helpers import transforms_from
from fluent.migrate import COPY_PATTERN
TARGET_FILE = "toolkit/toolkit/about/aboutAddons.ftl"
SOURCE_FILE = TARGET_FILE
def migrate(ctx):
"""Bug 1525175 - Move about:addons global warnings to HTML browser, part {index}"""
ctx.add_transforms(
TARGET_FILE,
SOURCE_FILE,
transforms_from(
"""
extensions-warning-safe-mode = {COPY_PATTERN(from_path, "extensions-warning-safe-mode-label.value")}
extensions-warning-check-compatibility = {COPY_PATTERN(from_path, "extensions-warning-check-compatibility-label.value")}
extensions-warning-check-compatibility-button = {COPY_PATTERN(from_path, "extensions-warning-check-compatibility-enable.label")}
.title = {COPY_PATTERN(from_path, "extensions-warning-check-compatibility-enable.tooltiptext")}
extensions-warning-update-security = {COPY_PATTERN(from_path, "extensions-warning-update-security-label.value")}
extensions-warning-update-security-button = {COPY_PATTERN(from_path, "extensions-warning-update-security-enable.label")}
.title = {COPY_PATTERN(from_path, "extensions-warning-update-security-enable.tooltiptext")}
""",
from_path=SOURCE_FILE),
)

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

@ -227,28 +227,14 @@ extensions-view-available-updates =
## These are global warnings
extensions-warning-safe-mode-label =
.value = All add-ons have been disabled by safe mode.
extensions-warning-safe-mode-container =
.tooltiptext = { extensions-warning-safe-mode-label.value }
extensions-warning-safe-mode = All add-ons have been disabled by safe mode.
extensions-warning-check-compatibility = Add-on compatibility checking is disabled. You may have incompatible add-ons.
extensions-warning-check-compatibility-button = Enable
.title = Enable add-on compatibility checking
extensions-warning-update-security = Add-on update security checking is disabled. You may be compromised by updates.
extensions-warning-update-security-button = Enable
.title = Enable add-on update security checking
extensions-warning-check-compatibility-label =
.value = Add-on compatibility checking is disabled. You may have incompatible add-ons.
extensions-warning-check-compatibility-container =
.tooltiptext = { extensions-warning-check-compatibility-label.value }
extensions-warning-check-compatibility-enable =
.label = Enable
.tooltiptext = Enable add-on compatibility checking
extensions-warning-update-security-label =
.value = Add-on update security checking is disabled. You may be compromised by updates.
extensions-warning-update-security-container =
.tooltiptext = { extensions-warning-update-security-label.value }
extensions-warning-update-security-enable =
.label = Enable
.tooltiptext = Enable add-on update security checking
## Strings connected to add-on updates

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

@ -82,12 +82,19 @@ search-addons > search-textbox {
transform: scaleX(-1);
}
/* Plugins aren't yet disabled by safemode (bug 342333),
so don't show that warning when viewing plugins. */
#page-header[current-param="plugin"] message-bar[warning-type="safe-mode"] {
display: none;
}
#main {
margin-inline-start: 28px;
margin-bottom: 28px;
max-width: var(--section-width);
}
global-warnings,
#abuse-reports-messages {
margin-inline-start: 28px;
max-width: var(--section-width);

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

@ -57,6 +57,7 @@
</div>
</div>
</div>
<global-warnings></global-warnings>
</template>
<template name="addon-page-options">

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

@ -5,7 +5,7 @@
/* exported hide, initialize, show */
/* import-globals-from aboutaddonsCommon.js */
/* import-globals-from abuse-reports.js */
/* global MozXULElement, windowRoot */
/* global MozXULElement, MessageBarStackElement, windowRoot */
"use strict";
@ -1150,6 +1150,96 @@ class SearchAddons extends HTMLElement {
}
customElements.define("search-addons", SearchAddons);
class GlobalWarnings extends MessageBarStackElement {
constructor() {
super();
// This won't change at runtime, but we'll want to fake it in tests.
this.inSafeMode = Services.appinfo.inSafeMode;
this.globalWarning = null;
}
connectedCallback() {
this.refresh();
this.addEventListener("click", this);
AddonManager.addManagerListener(this);
}
disconnectedCallback() {
this.removeEventListener("click", this);
AddonManager.removeManagerListener(this);
}
refresh() {
if (this.inSafeMode) {
this.setWarning("safe-mode");
} else if (
AddonManager.checkUpdateSecurityDefault &&
!AddonManager.checkUpdateSecurity
) {
this.setWarning("update-security", { action: true });
} else if (!AddonManager.checkCompatibility) {
this.setWarning("check-compatibility", { action: true });
} else {
this.removeWarning();
}
}
setWarning(type, opts) {
if (
this.globalWarning &&
this.globalWarning.getAttribute("warning-type") !== type
) {
this.removeWarning();
}
if (!this.globalWarning) {
this.globalWarning = document.createElement("message-bar");
this.globalWarning.setAttribute("warning-type", type);
let textContainer = document.createElement("span");
document.l10n.setAttributes(textContainer, `extensions-warning-${type}`);
this.globalWarning.appendChild(textContainer);
if (opts && opts.action) {
let button = document.createElement("button");
document.l10n.setAttributes(
button,
`extensions-warning-${type}-button`
);
button.setAttribute("action", type);
this.globalWarning.appendChild(button);
}
this.appendChild(this.globalWarning);
}
}
removeWarning() {
if (this.globalWarning) {
this.globalWarning.remove();
this.globalWarning = null;
}
}
handleEvent(e) {
if (e.type === "click") {
switch (e.target.getAttribute("action")) {
case "update-security":
AddonManager.checkUpdateSecurity = true;
break;
case "check-compatibility":
AddonManager.checkCompatibility = true;
break;
}
}
}
onCompatibilityModeChanged() {
this.refresh();
}
onCheckUpdateSecurityChanged() {
this.refresh();
}
}
customElements.define("global-warnings", GlobalWarnings);
class AddonPageHeader extends HTMLElement {
connectedCallback() {
if (this.childElementCount === 0) {
@ -3837,9 +3927,9 @@ function initialize(opts) {
window.addEventListener(
"unload",
() => {
// Clear out the main node so the disconnectedCallback will trigger
// Clear out the document so the disconnectedCallback will trigger
// properly and all of the custom elements can cleanup.
mainEl.textContent = "";
document.body.textContent = "";
AddonCardListenerHandler.shutdown();
},
{ once: true }

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

@ -23,32 +23,6 @@ xhtml|link {
visibility: hidden;
}
#addons-page:not([warning]) .global-warning,
#addons-page:not([warning="safemode"]) .global-warning-safemode,
#addons-page:not([warning="checkcompatibility"]) .global-warning-checkcompatibility,
#addons-page:not([warning="updatesecurity"]) .global-warning-updatesecurity {
display: none;
}
/* Plugins aren't yet disabled by safemode (bug 342333),
so don't show that warning when viewing plugins. */
#addons-page[warning="safemode"] #html-view[type="list"][param="plugin"] .global-warning-safemode,
#addons-page[warning="safemode"] .view-pane[type="plugin"] .global-warning-container,
#addons-page[warning="safemode"] #detail-view[loading="true"] .global-warning {
display: none;
}
#addons-page .view-pane:not([type="plugin"]) #plugindeprecation-notice {
display: none;
}
.html-alert-container > .message-bar {
margin-bottom: 8px;
}
.html-global-warning-button {
margin-inline: 0;
}
/* Elements in unselected richlistitems cannot be focused */
richlistitem:not([selected]) * {
-moz-user-focus: ignore;

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

@ -110,11 +110,6 @@ function initialize(event) {
return false;
});
let globalCommandSet = document.getElementById("globalCommandSet");
globalCommandSet.addEventListener("command", function(event) {
gViewController.doCommand(event.target.id);
});
let addonPage = document.getElementById("addons-page");
addonPage.addEventListener("dragenter", function(event) {
gDragDrop.onDragOver(event);
@ -445,8 +440,6 @@ var gEventManager = {
AddonManager.addManagerListener(this);
AddonManager.addInstallListener(this);
AddonManager.addAddonListener(this);
this.refreshGlobalWarning();
},
shutdown() {
@ -525,38 +518,6 @@ var gEventManager = {
}
}
},
refreshGlobalWarning() {
var page = document.getElementById("addons-page");
if (Services.appinfo.inSafeMode) {
page.setAttribute("warning", "safemode");
return;
}
if (
AddonManager.checkUpdateSecurityDefault &&
!AddonManager.checkUpdateSecurity
) {
page.setAttribute("warning", "updatesecurity");
return;
}
if (!AddonManager.checkCompatibility) {
page.setAttribute("warning", "checkcompatibility");
return;
}
page.removeAttribute("warning");
},
onCompatibilityModeChanged() {
this.refreshGlobalWarning();
},
onCheckUpdateSecurityChanged() {
this.refreshGlobalWarning();
},
};
var gViewController = {
@ -803,80 +764,6 @@ var gViewController = {
this.currentViewObj.node.dispatchEvent(event);
},
commands: {
cmd_enableCheckCompatibility: {
isEnabled() {
return true;
},
doCommand() {
AddonManager.checkCompatibility = true;
},
},
cmd_enableUpdateSecurity: {
isEnabled() {
return true;
},
doCommand() {
AddonManager.checkUpdateSecurity = true;
},
},
},
supportsCommand(aCommand) {
return aCommand in this.commands;
},
isCommandEnabled(aCommand) {
if (!this.supportsCommand(aCommand)) {
return false;
}
var addon = this.currentViewObj.getSelectedAddon();
return this.commands[aCommand].isEnabled(addon);
},
updateCommands() {
// wait until the view is initialized
if (!this.currentViewObj) {
return;
}
var addon = this.currentViewObj.getSelectedAddon();
for (let commandId in this.commands) {
this.updateCommand(commandId, addon);
}
},
updateCommand(aCommandId, aAddon) {
if (typeof aAddon == "undefined") {
aAddon = this.currentViewObj.getSelectedAddon();
}
var cmd = this.commands[aCommandId];
var cmdElt = document.getElementById(aCommandId);
cmdElt.setAttribute("disabled", !cmd.isEnabled(aAddon));
if ("getTooltip" in cmd) {
let tooltip = cmd.getTooltip(aAddon);
if (tooltip) {
cmdElt.setAttribute("tooltiptext", tooltip);
} else {
cmdElt.removeAttribute("tooltiptext");
}
}
},
doCommand(aCommand, aAddon) {
if (!this.supportsCommand(aCommand)) {
return;
}
var cmd = this.commands[aCommand];
if (!aAddon) {
aAddon = this.currentViewObj.getSelectedAddon();
}
if (!cmd.isEnabled(aAddon)) {
return;
}
cmd.doCommand(aAddon);
},
onEvent() {},
};
@ -1315,8 +1202,6 @@ var gDiscoverView = {
},
async show(aParam, aRequest, aState, aIsRefresh) {
gViewController.updateCommands();
// If we're being told to load a specific URL then just do that
if (aState && "url" in aState) {
this.loaded = true;
@ -1427,8 +1312,6 @@ var gDiscoverView = {
gViewController.lastHistoryIndex = gHistory.index;
}
gViewController.updateCommands();
// If the hostname is the same as the new location's host and either the
// default scheme is insecure or the new location is secure then continue
// with the load
@ -1510,7 +1393,6 @@ var gDiscoverView = {
} else {
// Got a successful load, make sure the browser is visible
this.node.selectedPanel = this._browser;
gViewController.updateCommands();
}
var listeners = this._loadListeners;
@ -1747,7 +1629,6 @@ function htmlView(type) {
this.node.setAttribute("type", type);
this.node.setAttribute("param", param);
await this._browser.contentWindow.show(type, param, state);
gViewController.updateCommands();
gViewController.notifyViewChanged();
},

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

@ -57,13 +57,6 @@
</menupopup>
</popupset>
<!-- global commands - these act on all addons, or affect the addons manager
in some other way -->
<commandset id="globalCommandSet">
<command id="cmd_enableCheckCompatibility"/>
<command id="cmd_enableUpdateSecurity"/>
</commandset>
<stack id="main-page-stack" flex="1">
<hbox id="main-page-content" flex="1">
<vbox id="category-box">
@ -149,47 +142,6 @@
<vbox id="headered-views" flex="1">
<deck id="headered-views-content" flex="1" selectedIndex="0">
<vbox id="html-view" flex="1">
<vbox class="alert-container html-alert-container" align="start">
<hbox class="global-warning-safemode message-bar"
data-l10n-id="extensions-warning-safe-mode-container"
align="start">
<image class="message-bar-icon"/>
<vbox class="message-container">
<description class="message-bar-description"
crop="end"
data-l10n-id="extensions-warning-safe-mode-label"/>
</vbox>
</hbox>
<hbox class="global-warning-checkcompatibility message-bar"
data-l10n-id="extensions-warning-check-compatibility-container"
align="start">
<image class="message-bar-icon"/>
<vbox class="message-container">
<description class="message-bar-description"
crop="end"
data-l10n-id="extensions-warning-check-compatibility-label"/>
<hbox>
<button class="html-global-warning-button"
data-l10n-id="extensions-warning-check-compatibility-enable"
command="cmd_enableCheckCompatibility"/>
</hbox>
</vbox>
</hbox>
<hbox class="global-warning-updatesecurity message-bar"
data-l10n-id="extensions-warning-update-security-container">
<image class="message-bar-icon"/>
<vbox class="message-container">
<description class="message-bar-description"
crop="end"
data-l10n-id="extensions-warning-update-security-label"/>
<hbox>
<button class="html-global-warning-button"
data-l10n-id="extensions-warning-update-security-enable"
command="cmd_enableUpdateSecurity"/>
</hbox>
</vbox>
</hbox>
</vbox>
<browser id="html-view-browser" type="content" flex="1" disablehistory="true"/>
</vbox>
</deck>

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

@ -4,17 +4,47 @@
// Bug 566194 - safe mode / security & compatibility check status are not exposed in new addon manager UI
async function loadDetail(aWindow, id) {
let loaded = wait_for_view_load(aWindow, undefined, true);
async function loadDetail(win, id) {
let loaded = waitForViewLoad(win);
// Check the detail view.
let browser = await aWindow.getHtmlBrowser();
let card = browser.contentDocument.querySelector(
`addon-card[addon-id="${id}"]`
);
EventUtils.synthesizeMouseAtCenter(card, {}, browser.contentWindow);
let card = win.document.querySelector(`addon-card[addon-id="${id}"]`);
EventUtils.synthesizeMouseAtCenter(card, {}, win);
await loaded;
}
function checkMessageShown(win, type, hasButton) {
let stack = win.document.querySelector("global-warnings");
is(stack.childElementCount, 1, "There is one message");
let messageBar = stack.firstElementChild;
ok(messageBar, "There is a message bar");
is(messageBar.localName, "message-bar", "The message bar is a message-bar");
is_element_visible(messageBar, "Message bar is visible");
is(messageBar.getAttribute("warning-type"), type);
if (hasButton) {
let button = messageBar.querySelector("button");
is_element_visible(button, "Button is visible");
is(button.getAttribute("action"), type, "Button action is set");
}
}
function checkNoMessages(win) {
let stack = win.document.querySelector("global-warnings");
if (stack.childElementCount) {
// The safe mode message is hidden in CSS on the plugin list.
for (let child of stack.children) {
is_element_hidden(child, "The message is hidden");
}
} else {
is(stack.childElementCount, 0, "There are no message bars");
}
}
function clickMessageAction(win) {
let stack = win.document.querySelector("global-warnings");
let button = stack.firstElementChild.querySelector("button");
EventUtils.synthesizeMouseAtCenter(button, {}, win);
}
add_task(async function checkCompatibility() {
info("Testing compatibility checking warning");
@ -28,62 +58,33 @@ add_task(async function checkCompatibility() {
});
await extension.startup();
let aWindow = await open_manager("addons://list/extension");
let hbox = aWindow.document.querySelector(
"#html-view .global-warning-checkcompatibility"
);
let button = aWindow.document.querySelector(
"#html-view .global-warning-checkcompatibility button"
);
function checkMessage(visible) {
if (visible) {
is_element_visible(
hbox,
"Check Compatibility warning hbox should be visible"
);
is_element_visible(
button,
"Check Compatibility warning button should be visible"
);
} else {
is_element_hidden(
hbox,
"Check Compatibility warning hbox should be hidden"
);
is_element_hidden(
button,
"Check Compatibility warning button should be hidden"
);
}
}
let win = await loadInitialView("extension");
// Check the extension list view.
checkMessage(true);
checkMessageShown(win, "check-compatibility", true);
// Check the detail view.
await loadDetail(aWindow, id);
checkMessage(true);
await loadDetail(win, id);
checkMessageShown(win, "check-compatibility", true);
// Check other views.
let views = ["plugin", "theme"];
let categoryUtilities = new CategoryUtilities(aWindow);
for (let view of views) {
await categoryUtilities.openType(view);
checkMessage(true);
await switchView(win, view);
checkMessageShown(win, "check-compatibility", true);
}
// Check the button works.
info("Clicking 'Enable' button");
EventUtils.synthesizeMouse(button, 2, 2, {}, aWindow);
clickMessageAction(win);
is(
AddonManager.checkCompatibility,
true,
"Check Compatibility pref should be cleared"
);
checkMessage(false);
checkNoMessages(win);
await close_manager(aWindow);
await closeView(win);
await extension.unload();
});
@ -101,62 +102,33 @@ add_task(async function checkSecurity() {
});
await extension.startup();
let aWindow = await open_manager("addons://list/extension");
let hbox = aWindow.document.querySelector(
"#html-view .global-warning-updatesecurity"
);
let button = aWindow.document.querySelector(
"#html-view .global-warning-updatesecurity button"
);
function checkMessage(visible) {
if (visible) {
is_element_visible(
hbox,
"Check Update Security warning hbox should be visible"
);
is_element_visible(
button,
"Check Update Security warning button should be visible"
);
} else {
is_element_hidden(
hbox,
"Check Update Security warning hbox should be hidden"
);
is_element_hidden(
button,
"Check Update Security warning button should be hidden"
);
}
}
let win = await loadInitialView("extension");
// Check extension list view.
checkMessage(true);
checkMessageShown(win, "update-security", true);
// Check detail view.
await loadDetail(aWindow, id);
checkMessage(true);
await loadDetail(win, id);
checkMessageShown(win, "update-security", true);
// Check other views.
let views = ["plugin", "theme"];
let categoryUtilities = new CategoryUtilities(aWindow);
for (let view of views) {
await categoryUtilities.openType(view);
checkMessage(true);
await switchView(win, view);
checkMessageShown(win, "update-security", true);
}
// Check the button works.
info("Clicking 'Enable' button");
EventUtils.synthesizeMouse(button, 2, 2, {}, aWindow);
clickMessageAction(win);
is(
Services.prefs.prefHasUserValue(pref),
false,
"Check Update Security pref should be cleared"
);
checkMessage(false);
checkNoMessages(win);
await close_manager(aWindow);
await closeView(win);
await extension.unload();
});
@ -170,41 +142,25 @@ add_task(async function checkSafeMode() {
});
await extension.startup();
let aWindow = await open_manager("addons://list/extension");
let hbox = aWindow.document.querySelector(
"#html-view .global-warning-safemode"
);
function checkMessage(visible) {
if (visible) {
is_element_visible(
hbox,
"Check safe mode warning hbox should be visible"
);
} else {
is_element_hidden(hbox, "Check safe mode warning hbox should be hidden");
}
}
let win = await loadInitialView("extension");
// Check extension list view hidden.
checkMessage(false);
checkNoMessages(win);
// Mock safe mode by setting the page attribute.
aWindow.document
.getElementById("addons-page")
.setAttribute("warning", "safemode");
let globalWarnings = win.document.querySelector("global-warnings");
globalWarnings.inSafeMode = true;
globalWarnings.refresh();
// Check detail view.
await loadDetail(aWindow, id);
checkMessage(true);
await loadDetail(win, id);
checkMessageShown(win, "safe-mode");
// Check other views.
let categoryUtilities = new CategoryUtilities(aWindow);
await categoryUtilities.openType("theme");
checkMessage(true);
await categoryUtilities.openType("plugin");
checkMessage(false);
await switchView(win, "theme");
checkMessageShown(win, "safe-mode");
await switchView(win, "plugin");
checkNoMessages(win);
await close_manager(aWindow);
await closeView(win);
await extension.unload();
});