Commit 09e4d6e7 authored by Cosmin Sabou's avatar Cosmin Sabou
Browse files

Backed out 4 changesets (bug 1570792, bug 1593358, bug 1575905) for causing...

Backed out 4 changesets (bug 1570792, bug 1593358, bug 1575905) for causing bug 1593402 to near permafail. CLOSED TREE

Backed out changeset 43490702945f (bug 1593358)
Backed out changeset cf2f28971e64 (bug 1570792)
Backed out changeset 67f284b0e4c2 (bug 1575905)
Backed out changeset 13d8e61774f1 (bug 1575905)

--HG--
extra : amend_source : 9541e3e941e7b62095715bb4859991bd48ea0489
extra : histedit_source : 51dd3724c2e8b806b2c9e531aa14119ff38f37e4
parent b1bde23d
......@@ -53,7 +53,7 @@ function assertDisabledSideloadedAddonElement(managerWindow, addonElement) {
const enableBtn = addonElement.querySelector('[action="toggle-disabled"]');
is(
doc.l10n.getAttributes(enableBtn).id,
"enable-addon-button-label",
"enable-addon-button",
"The button has the enable label"
);
}
......
......@@ -12,7 +12,9 @@ async function isExtensionLocked(win, addonID) {
await win.htmlBrowserLoaded;
return doc.querySelector(`addon-card[addon-id="${addonID}"]`);
}, `Get addon-card for "${addonID}"`);
let disableBtn = addonCard.querySelector('[action="toggle-disabled"]');
let disableBtn = addonCard.querySelector(
'panel-item[action="toggle-disabled"]'
);
let removeBtn = addonCard.querySelector('panel-item[action="remove"]');
ok(removeBtn.disabled, "Remove button should be disabled");
ok(disableBtn.hidden, "Disable button should be hidden");
......
# 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 1570792 - Add a toggle to extension cards, part {index}"""
ctx.add_transforms(
TARGET_FILE,
SOURCE_FILE,
transforms_from(
"""
disable-addon-button-label =
.aria-label = {COPY_PATTERN(from_path, "disable-addon-button")}
enable-addon-button-label =
.aria-label = {COPY_PATTERN(from_path, "enable-addon-button")}
""",
from_path=SOURCE_FILE),
)
......@@ -367,10 +367,6 @@ remove-addon-button = Remove
remove-addon-disabled-button = Can’t Be Removed <a data-l10n-name="link">Why?</a>
disable-addon-button = Disable
enable-addon-button = Enable
disable-addon-button-label =
.aria-label = Disable
enable-addon-button-label =
.aria-label = Enable
preferences-addon-button =
{ PLATFORM() ->
[windows] Options
......
......@@ -176,7 +176,6 @@ addon-card[expanded] .addon-card-message {
/* Adjust height so that the image preserves the aspect ratio from AMO.
* For details, see https://bugzilla.mozilla.org/show_bug.cgi?id=1546123 */
height: calc(var(--section-width) * 92 / 680);
object-fit: cover;
}
.card-heading-icon {
......@@ -195,6 +194,10 @@ addon-card[expanded] .addon-card-message {
flex-direction: column;
}
.card-actions {
flex-shrink: 0;
}
.addon-name-container {
/* Subtract the top line-height so the text and icon align at the top. */
margin-top: -3px;
......@@ -240,15 +243,6 @@ addon-card[expanded] .addon-card-message {
-moz-context-properties: fill;
}
.theme-enable-button {
min-width: auto;
height: auto;
font-size: 13px;
min-height: auto;
height: 24px;
margin: 0;
}
.addon-description {
font-size: 14px;
line-height: 20px;
......@@ -281,6 +275,12 @@ addon-card:not([expanded]) .addon-description {
height: 32px;
}
.more-options-menu {
/* Add some negative margin to account for the button's padding */
margin-top: -10px;
margin-inline-end: -8px;
}
/* Recommended add-ons on list views */
.recommended-heading {
margin-top: 48px;
......@@ -437,7 +437,6 @@ addon-details {
width: 24px;
height: 24px;
margin: 0;
margin-inline-start: 8px;
-moz-context-properties: fill;
fill: currentColor;
background-image: url("chrome://global/skin/icons/more.svg");
......
......@@ -14,7 +14,6 @@
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/aboutaddons.css">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/toggle-button.css">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/shortcuts.css">
<link rel="localization" href="branding/brand.ftl">
......@@ -78,6 +77,7 @@
<template name="addon-options">
<panel-list>
<panel-item action="toggle-disabled"></panel-item>
<panel-item data-l10n-id="remove-addon-button" action="remove"></panel-item>
<panel-item data-l10n-id="install-update-button" action="install-update" badged></panel-item>
<panel-item data-l10n-id="preferences-addon-button" action="preferences"></panel-item>
......@@ -119,19 +119,18 @@
data-l10n-id="addon-badge-private-browsing-allowed2"
hidden>
</a>
<div class="spacer"></div>
<button class="theme-enable-button" action="toggle-disabled" hidden></button>
<input type="checkbox" class="toggle-button extension-enable-button" action="toggle-disabled" hidden>
<button
class="more-options-button"
action="more-options"
data-l10n-id="addon-options-button"
aria-haspopup="menu"
aria-expanded="false"></button>
</div>
<!-- This ends up in the tab order when the ellipsis happens, but it isn't necessary. -->
<span class="addon-description" tabindex="-1"></span>
</div>
<div class="more-options-menu">
<button
class="more-options-button ghost-button"
action="more-options"
data-l10n-id="addon-options-button"
aria-haspopup="menu"
aria-expanded="false"></button>
</div>
</div>
<message-bar class="addon-card-message" align="center" hidden>
<span></span>
......
......@@ -84,21 +84,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
const PLUGIN_ICON_URL = "chrome://global/skin/plugins/pluginGeneric.svg";
const EXTENSION_ICON_URL =
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
const BUILTIN_THEME_PREVIEWS = new Map([
[
"default-theme@mozilla.org",
"chrome://mozapps/content/extensions/default-theme.svg",
],
[
"firefox-compact-light@mozilla.org",
"chrome://mozapps/content/extensions/firefox-compact-light.svg",
],
[
"firefox-compact-dark@mozilla.org",
"chrome://mozapps/content/extensions/firefox-compact-dark.svg",
],
]);
const PERMISSION_MASKS = {
"ask-to-activate": AddonManager.PERM_CAN_ASK_TO_ACTIVATE,
enable: AddonManager.PERM_CAN_ENABLE,
......@@ -122,13 +107,6 @@ const PRIVATE_BROWSING_PERMS = {
origins: [],
};
function shouldSkipAnimations() {
return (
document.body.hasAttribute("skip-animations") ||
window.matchMedia("(prefers-reduced-motion: reduce)").matches
);
}
const AddonCardListenerHandler = {
ADDON_EVENTS: new Set([
"onDisabled",
......@@ -441,10 +419,6 @@ function nl2br(text) {
* The URL of the best fitting screenshot, if any.
*/
function getScreenshotUrlForAddon(addon) {
if (BUILTIN_THEME_PREVIEWS.has(addon.id)) {
return BUILTIN_THEME_PREVIEWS.get(addon.id);
}
let { screenshots } = addon;
if (!screenshots || !screenshots.length) {
return null;
......@@ -1646,6 +1620,12 @@ class AddonOptions extends HTMLElement {
case "report":
el.hidden = !isAbuseReportSupported(addon);
break;
case "toggle-disabled": {
let toggleDisabledAction = addon.userDisabled ? "enable" : "disable";
document.l10n.setAttributes(el, `${toggleDisabledAction}-addon-button`);
el.hidden = !hasPermission(addon, toggleDisabledAction);
break;
}
case "install-update":
el.hidden = !updateInstall;
break;
......@@ -2437,8 +2417,6 @@ class AddonCard extends HTMLElement {
switch (action) {
case "toggle-disabled":
this.recordActionEvent(addon.userDisabled ? "enable" : "disable");
// Keep the checked state the same until the add-on's state changes.
e.target.checked = !addon.userDisabled;
if (addon.userDisabled) {
if (shouldShowPermissionsPrompt(addon)) {
await showPermissionsPrompt(addon);
......@@ -2448,6 +2426,10 @@ class AddonCard extends HTMLElement {
} else {
await addon.disable();
}
if (e.mozInputSource == MouseEvent.MOZ_SOURCE_KEYBOARD) {
// Refocus the open menu button so it's clear where the focus is.
this.querySelector('[action="more-options"]').focus();
}
break;
case "ask-to-activate":
if (hasPermission(addon, "ask-to-activate")) {
......@@ -2696,25 +2678,25 @@ class AddonCard extends HTMLElement {
card.setAttribute("active", addon.isActive);
// Set the icon or theme preview.
let iconEl = card.querySelector(".addon-icon");
// Update the icon.
let icon;
if (addon.type == "plugin") {
icon = PLUGIN_ICON_URL;
} else {
icon =
AddonManager.getPreferredIconURL(addon, 32, window) ||
EXTENSION_ICON_URL;
}
card.querySelector(".addon-icon").src = icon;
// Update the theme preview.
let preview = card.querySelector(".card-heading-image");
preview.hidden = true;
if (addon.type == "theme") {
iconEl.hidden = true;
let screenshotUrl = getScreenshotUrlForAddon(addon);
if (screenshotUrl) {
preview.src = screenshotUrl;
}
preview.hidden = !screenshotUrl;
} else {
preview.hidden = true;
iconEl.hidden = false;
if (addon.type == "plugin") {
iconEl.src = PLUGIN_ICON_URL;
} else {
iconEl.src =
AddonManager.getPreferredIconURL(addon, 32, window) ||
EXTENSION_ICON_URL;
preview.hidden = false;
}
}
......@@ -2730,25 +2712,6 @@ class AddonCard extends HTMLElement {
}
name.title = `${addon.name} ${addon.version}`;
let toggleDisabledAction = addon.userDisabled ? "enable" : "disable";
let canToggleDisabled = hasPermission(addon, toggleDisabledAction);
let toggleDisabledButton = card.querySelector('[action="toggle-disabled"]');
if (toggleDisabledButton) {
toggleDisabledButton.hidden = !canToggleDisabled;
if (addon.type === "theme") {
document.l10n.setAttributes(
toggleDisabledButton,
`${toggleDisabledAction}-addon-button`
);
} else if (addon.type === "extension") {
toggleDisabledButton.checked = !addon.userDisabled;
document.l10n.setAttributes(
toggleDisabledButton,
`${toggleDisabledAction}-addon-button-label`
);
}
}
// Set the items in the more options menu.
this.options.update(this, addon, this.updateInstall);
......@@ -2842,14 +2805,6 @@ class AddonCard extends HTMLElement {
this.card = importTemplate("card").firstElementChild;
// Remove the toggle-disabled button(s) based on type.
if (addon.type != "theme") {
this.card.querySelector(".theme-enable-button").remove();
}
if (addon.type != "extension") {
this.card.querySelector(".extension-enable-button").remove();
}
let nameContainer = this.card.querySelector(".addon-name-container");
let headingLevel = this.expanded ? "h1" : "h3";
let nameHeading = document.createElement(headingLevel);
......@@ -2868,7 +2823,7 @@ class AddonCard extends HTMLElement {
let panelType = addon.type == "plugin" ? "plugin-options" : "addon-options";
this.options = document.createElement(panelType);
this.options.render();
this.card.appendChild(this.options);
this.card.querySelector(".more-options-menu").appendChild(this.options);
this.optionsButton = this.card.querySelector(".more-options-button");
// Set the contents.
......@@ -2941,6 +2896,7 @@ class RecommendedAddonCard extends HTMLElement {
let heading = card.querySelector(".addon-name-container");
heading.textContent = "";
heading.append(importTemplate("addon-name-container-in-disco-card"));
card.querySelector(".more-options-menu").remove();
this.setCardContent(card, addon);
if (addon.type != "theme") {
......@@ -2979,14 +2935,13 @@ class RecommendedAddonCard extends HTMLElement {
// Set the theme preview.
let preview = card.querySelector(".card-heading-image");
preview.hidden = true;
if (addon.type == "theme") {
let screenshotUrl = getScreenshotUrlForAddon(addon);
if (screenshotUrl) {
preview.src = screenshotUrl;
preview.hidden = false;
}
} else {
preview.hidden = true;
}
// Set the name.
......@@ -3134,8 +3089,6 @@ class AddonList extends HTMLElement {
super();
this.sections = [];
this.pendingUninstallAddons = new Set();
this._addonsToUpdate = new Set();
this._userFocusListenersAdded = false;
}
async connectedCallback() {
......@@ -3328,7 +3281,9 @@ class AddonList extends HTMLElement {
return;
}
let insertSection = this._addonSectionIndex(addon);
let insertSection = this.sections.findIndex(({ filterFn }) =>
filterFn(addon)
);
// Don't add the add-on if it doesn't go in a section.
if (insertSection == -1) {
......@@ -3357,144 +3312,24 @@ class AddonList extends HTMLElement {
}
updateAddon(addon) {
if (!this.getCard(addon)) {
// Try to add the add-on right away.
this.addAddon(addon);
} else if (this._addonSectionIndex(addon) == -1) {
// Try to remove the add-on right away.
this._updateAddon(addon);
} else if (this.isUserFocused) {
// Queue up a change for when the focus is cleared.
this.updateLater(addon);
} else {
// Not currently focused, make the change now.
this.withCardAnimation(() => this._updateAddon(addon));
}
}
updateLater(addon) {
this._addonsToUpdate.add(addon);
this._addUserFocusListeners();
}
_addUserFocusListeners() {
if (this._userFocusListenersAdded) {
return;
}
this._userFocusListenersAdded = true;
this.addEventListener("mouseleave", this);
this.addEventListener("hidden", this, true);
this.addEventListener("focusout", this);
}
_removeUserFocusListeners() {
if (!this._userFocusListenersAdded) {
return;
}
this.removeEventListener("mouseleave", this);
this.removeEventListener("hidden", this, true);
this.removeEventListener("focusout", this);
this._userFocusListenersAdded = false;
}
get hasMenuOpen() {
return !!this.querySelector("panel-list[open]");
}
get isUserFocused() {
return this.matches(":hover, :focus-within") || this.hasMenuOpen;
}
update() {
if (this._addonsToUpdate.size) {
this.withCardAnimation(() => {
for (let addon of this._addonsToUpdate) {
this._updateAddon(addon);
}
this._addonsToUpdate = new Set();
});
}
}
_getChildCoords() {
let results = new Map();
for (let child of this.querySelectorAll("addon-card")) {
results.set(child, child.getBoundingClientRect());
}
return results;
}
withCardAnimation(changeFn) {
if (shouldSkipAnimations()) {
changeFn();
return;
}
let origChildCoords = this._getChildCoords();
changeFn();
let newChildCoords = this._getChildCoords();
let cards = this.querySelectorAll("addon-card");
let transitionCards = [];
for (let card of cards) {
let orig = origChildCoords.get(card);
let moved = newChildCoords.get(card);
let changeY = moved.y - (orig || moved).y;
let cardEl = card.firstElementChild;
if (changeY != 0) {
cardEl.style.transform = `translateY(${changeY * -1}px)`;
transitionCards.push(card);
}
}
requestAnimationFrame(() => {
for (let card of transitionCards) {
card.firstElementChild.style.transition = "transform 125ms";
}
requestAnimationFrame(() => {
for (let card of transitionCards) {
let cardEl = card.firstElementChild;
cardEl.style.transform = "";
cardEl.addEventListener("transitionend", function handler(e) {
if (e.target == cardEl && e.propertyName == "transform") {
cardEl.style.transition = "";
cardEl.removeEventListener("transitionend", handler);
}
});
}
});
});
}
_addonSectionIndex(addon) {
return this.sections.findIndex(s => s.filterFn(addon));
}
_updateAddon(addon) {
let card = this.getCard(addon);
if (card) {
let sectionIndex = this._addonSectionIndex(addon);
let sectionIndex = this.sections.findIndex(s => s.filterFn(addon));
if (sectionIndex != -1) {
// Move the card, if needed. This will allow an animation between
// page sections and provides clearer events for testing.
if (card.parentNode.getAttribute("section") != sectionIndex) {
let { activeElement } = document;
let refocus = card.contains(activeElement);
let oldSection = card.parentNode;
this.insertCardInto(card, sectionIndex);
this.updateSectionIfEmpty(oldSection);
if (refocus) {
activeElement.focus();
}
this.sendEvent("move", { id: addon.id });
}
} else {
this.removeAddon(addon);
}
} else {
// Add the add-on, this will do nothing if it shouldn't be in the list.
this.addAddon(addon);
}
}
......@@ -3593,13 +3428,6 @@ class AddonList extends HTMLElement {
this.removePendingUninstallBar(addon);
this.removeAddon(addon);
}
handleEvent(e) {
if (!this.isUserFocused || (e.type == "mouseleave" && !this.hasMenuOpen)) {
this._removeUserFocusListeners();
this.update();
}
}
}
customElements.define("addon-list", AddonList);
......
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="664" height="90" fill="#0C0C0D">
<path fill="#202340" d="M0 0h664v90H0z"/>
<path fill="#F9F9FA" d="M28 35.717V.5L156 0v35.217h508V90H0V35.217z"/>
<path fill="#0A84FF" d="M28 0h128v5H28z"/>
<rect width="76" height="5" x="54" y="18" fill="#3D3D3D" rx="2.5"/>
<rect width="76" height="5" x="182" y="18" fill="#F9F9FA" rx="2.5"/>
<rect width="533" height="29" x="82.5" y="47.5" fill="#FFF" stroke="#ADADB3" stroke-opacity=".2" rx="4"/>
<rect width="430" height="5" x="96" y="61" rx="2.5"/>
<circle cx="27" cy="63" r="7"/>
<circle cx="55" cy="63" r="7"/>
<rect width="18" height="2.667" x="630" y="54" rx="1.333"/>
<rect width="18" height="2.667" x="630" y="60.667" rx="1.333"/>
<rect width="18" height="2.667" x="630" y="67" rx="1.333"/>
</svg>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="664" height="90" fill="#F9F9FA">
<path fill="#0C0C0D" d="M0 0h664v90H0z"/>
<path fill="#323234" d="M28 35.217V0l128 .489v35.218l508-.49V90H0V35.217z"/>
<path fill="#0A84FF" d="M28 0h128v5H28z"/>
<rect width="76" height="5" x="54" y="18" rx="2.5"/>
<rect width="76" height="5" x="182" y="18" rx="2.5"/>
<rect width="533" height="29" x="82.5" y="47.5" fill="#515153" stroke="#ADADB3" stroke-opacity=".2" rx="4"/>
<rect width="430" height="5" x="96" y="61" rx="2.5"/>
<circle cx="27" cy="63" r="7"/>
<circle cx="55" cy="63" r="7"/>
<rect width="18" height="2.667" x="630" y="54" rx="1.333"/>
<rect width="18" height="2.667" x="630" y="60.667" rx="1.333"/>
<rect width="18" height="2.667" x="630" y="67.333" rx="1.333"/>
</svg>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="664" height="90" fill="#0C0C0D">
<path fill="#E1E1E5" d="M0 0h664v90H0z"/>
<path fill="#F9F9FA" d="M28 35.217V0h128v35.217h508V90H0V35.217z"/>
<path fill="#0A84FF" d="M28 0h128v5H28z"/>
<rect width="76" height="5" x="54" y="18" fill="#3D3D3D" rx="2.5"/>
<rect width="76" height="5" x="182" y="18" fill="#3D3D3D" rx="2.5"/>
<rect width="533" height="29" x="82.5" y="47.5" fill="#FFF" stroke="#ADADB3" stroke-opacity=".2" rx="4"/>
<rect width="430" height="5" x="96" y="61" rx="2.5"/>
<circle cx="27" cy="63" r="7"/>
<circle cx="55" cy="63" r="7"/>
<rect width="18" height="2.667" x="630" y="54" rx="1.333"/>
<rect width="18" height="2.667" x="630" y="60.667" rx="1.333"/>
<rect width="18" height="2.667" x="630" y="67.333" rx="1.