Bug 1729534 - Change Customize window theme picker to a button that points to about:addons#themes. r=dao,fluent-reviewers,flod

Differential Revision: https://phabricator.services.mozilla.com/D125120
This commit is contained in:
Harry Twyford 2021-09-14 14:11:47 +00:00
Родитель 0c3899b477
Коммит 3519e40d46
8 изменённых файлов: 70 добавлений и 465 удалений

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

@ -4,7 +4,7 @@
"use strict";
var EXPORTED_SYMBOLS = ["CustomizeMode", "_defaultImportantThemes"];
var EXPORTED_SYMBOLS = ["CustomizeMode"];
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
const kPaletteId = "customization-palette";
@ -84,20 +84,6 @@ XPCOMUtils.defineLazyGetter(this, "log", () => {
return new scope.ConsoleAPI(consoleOptions);
});
const DEFAULT_THEME_ID = "default-theme@mozilla.org";
const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
const ALPENGLOW_THEME_ID = "firefox-alpenglow@mozilla.org";
const MONOCHROMATIC_PURPLE_THEME_ID =
"firefox-monochromatic-purple@mozilla.org";
const _defaultImportantThemes = [
DEFAULT_THEME_ID,
LIGHT_THEME_ID,
DARK_THEME_ID,
ALPENGLOW_THEME_ID,
];
var gDraggingInToolbars;
var gTab;
@ -1413,8 +1399,7 @@ CustomizeMode.prototype = {
}
},
openAddonsManagerThemes(aEvent) {
aEvent.target.parentNode.parentNode.hidePopup();
openAddonsManagerThemes() {
AMTelemetry.recordLinkEvent({ object: "customize", value: "manageThemes" });
this.window.BrowserOpenAddonsMgr("addons://list/theme");
},
@ -1544,108 +1529,6 @@ CustomizeMode.prototype = {
this._onUIChange();
},
async onThemesMenuShowing(aEvent) {
const MAX_THEME_COUNT = 6;
this._clearThemesMenu(aEvent.target);
let onThemeSelected = panel => {
// This causes us to call _onUIChange when the LWT actually changes,
// so the restore defaults / undo reset button is updated correctly.
this._nextThemeChangeUserTriggered = true;
panel.hidePopup();
};
let doc = this.document;
function buildToolbarButton(aTheme) {
let tbb = doc.createXULElement("toolbarbutton");
tbb.theme = aTheme;
tbb.setAttribute("label", aTheme.name);
tbb.setAttribute(
"image",
aTheme.iconURL || "chrome://mozapps/skin/extensions/themeGeneric.svg"
);
if (aTheme.description) {
tbb.setAttribute("tooltiptext", aTheme.description);
}
tbb.setAttribute("tabindex", "0");
tbb.classList.add("customization-lwtheme-menu-theme");
let isActive = aTheme.isActive;
tbb.setAttribute("aria-checked", isActive);
tbb.setAttribute("role", "menuitemradio");
if (isActive) {
tbb.setAttribute("active", "true");
}
return tbb;
}
let themes = await AddonManager.getAddonsByTypes(["theme"]);
let currentTheme = themes.find(theme => theme.isActive);
// Move the current theme (if any) and the default themes to the start:
let importantThemes = new Set(_defaultImportantThemes);
if (
Services.prefs.getBoolPref(
"browser.theme.temporary.monochromatic.enabled",
false
)
) {
importantThemes.add(MONOCHROMATIC_PURPLE_THEME_ID);
}
if (currentTheme) {
importantThemes.add(currentTheme.id);
}
let importantList = [];
for (let importantTheme of importantThemes) {
importantList.push(
...themes.splice(
themes.findIndex(theme => theme.id == importantTheme),
1
)
);
}
// Sort the remainder alphabetically:
themes.sort((a, b) => a.name.localeCompare(b.name));
themes = importantList.concat(themes);
if (themes.length > MAX_THEME_COUNT) {
themes.length = MAX_THEME_COUNT;
}
let footer = doc.getElementById("customization-lwtheme-menu-footer");
let panel = footer.parentNode;
for (let theme of themes) {
let button = buildToolbarButton(theme);
button.addEventListener("command", async () => {
onThemeSelected(panel);
await button.theme.enable();
AMTelemetry.recordActionEvent({
object: "customize",
action: "enable",
extra: { type: "theme", addonId: theme.id },
});
});
panel.insertBefore(button, footer);
}
},
_clearThemesMenu(panel) {
let footer = this.$("customization-lwtheme-menu-footer");
let element = footer;
while (
element.previousElementSibling &&
element.previousElementSibling.localName == "toolbarbutton"
) {
element.previousElementSibling.remove();
}
// Workaround for bug 1059934
panel.removeAttribute("height");
},
_onUIChange() {
this._changed = true;
if (!this.resetting) {

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

@ -32,26 +32,6 @@
<button id="customization-toolbar-visibility-button" class="customizationmode-button" type="menu" data-l10n-id="customize-mode-toolbars">
<menupopup id="customization-toolbar-menu" onpopupshowing="onViewToolbarsPopupShowing(event)"/>
</button>
<button id="customization-lwtheme-button" data-l10n-id="customize-mode-lwthemes" class="customizationmode-button" type="menu">
<panel type="arrow" id="customization-lwtheme-menu"
orient="vertical"
onpopupshowing="gCustomizeMode.onThemesMenuShowing(event);"
position="topleft bottomleft"
flip="none"
role="menu">
<label id="customization-lwtheme-menu-header" data-l10n-id="customize-mode-lwthemes-my-themes"/>
<hbox id="customization-lwtheme-menu-footer">
<toolbarbutton class="customization-lwtheme-menu-footeritem"
data-l10n-id="customize-mode-lwthemes-menu-manage"
tabindex="0"
oncommand="gCustomizeMode.openAddonsManagerThemes(event);"/>
<toolbarbutton class="customization-lwtheme-menu-footeritem"
data-l10n-id="customize-mode-lwthemes-menu-get-more"
tabindex="0"
oncommand="gCustomizeMode.getMoreThemes(event);"/>
</hbox>
</panel>
</button>
<button id="customization-uidensity-button"
data-l10n-id="customize-mode-uidensity"
class="customizationmode-button"
@ -103,6 +83,10 @@
#endif
</panel>
</button>
<button id="customization-lwtheme-button"
data-l10n-id="customize-mode-lwthemes-button"
oncommand="gCustomizeMode.openAddonsManagerThemes();"
class="customizationmode-button" />
<button id="whimsy-button"
type="checkbox"

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

@ -121,8 +121,6 @@ skip-if = verify
[browser_996364_registerArea_different_properties.js]
[browser_996635_remove_non_widgets.js]
[browser_1003588_no_specials_in_panel.js]
[browser_1007336_lwthemes_in_customize_mode.js]
skip-if = os == "linux" # crashing on Linux due to bug 1271683
[browser_1008559_anchor_undo_restore.js]
[browser_1042100_default_placements_update.js]
[browser_1058573_showToolbarsDropdown.js]
@ -145,6 +143,7 @@ skip-if = verify
[browser_currentset_post_reset.js]
[browser_customizemode_contextmenu_menubuttonstate.js]
skip-if = os == "win" && bits == 64 # 1526429
[browser_customizemode_lwthemes.js]
[browser_customizemode_uidensity.js]
[browser_disable_commands_customize.js]
[browser_drag_outside_palette.js]

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

@ -1,278 +0,0 @@
/* 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/. */
"use strict";
const DEFAULT_THEME_ID = "default-theme@mozilla.org";
const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
const ALPENGLOW_THEME_ID = "firefox-alpenglow@mozilla.org";
const MAX_THEME_COUNT = 6; // Not exposed from CustomizeMode.jsm
const { _defaultImportantThemes } = ChromeUtils.import(
"resource:///modules/CustomizeMode.jsm"
);
async function installTheme(id) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
applications: { gecko: { id } },
manifest_version: 2,
name: "Theme " + id,
description: "wow. such theme.",
author: "Pixel Pusher",
version: "1",
theme: {},
},
useAddonManager: "temporary",
});
await extension.startup();
return extension;
}
add_task(async function() {
await startCustomizing();
// Check restore defaults button is disabled.
ok(
document.getElementById("customization-reset-button").disabled,
"Reset button should start out disabled"
);
let themesButton = document.getElementById("customization-lwtheme-button");
let themesButtonIcon = themesButton.icon;
let iconURL = themesButtonIcon.style.backgroundImage;
// If we've run other tests before, we might have set the image to the
// default theme's icon explicitly, otherwise it might be empty, in which
// case the icon is determined by CSS (which will be the default
// theme's icon).
if (iconURL) {
ok(
/default/i.test(themesButtonIcon.style.backgroundImage),
`Button should show default theme thumbnail - was: "${iconURL}"`
);
} else {
is(
iconURL,
"",
`Button should show default theme thumbnail (empty string) - was: "${iconURL}"`
);
}
let popup = document.getElementById("customization-lwtheme-menu");
let popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button");
await popupShownPromise;
// close current tab and re-open Customize menu to confirm correct number of Themes
await endCustomizing();
info("Exited customize mode");
await startCustomizing();
info("Started customizing a second time");
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button a second time");
await popupShownPromise;
let header = document.getElementById("customization-lwtheme-menu-header");
let footer = document.getElementById("customization-lwtheme-menu-footer");
let menu = document.getElementById("customization-lwtheme-menu");
let themeMenuItems = menu.querySelectorAll(
"toolbarbutton.customization-lwtheme-menu-theme"
);
is(
themeMenuItems.length,
_defaultImportantThemes.length,
"There should only be four themes (default, light, dark, alpenglow) in the 'My Themes' section by default"
);
// Note that we use our own theme ID constants in the
// following tests because we want to test things are
// displayed in the proper order, not just in the order
// that constants in the code happens to be in.
is(
themeMenuItems[0].theme.id,
DEFAULT_THEME_ID,
"The first theme should be the default theme"
);
is(
themeMenuItems[1].theme.id,
LIGHT_THEME_ID,
"The second theme should be the light theme"
);
is(
themeMenuItems[2].theme.id,
DARK_THEME_ID,
"The third theme should be the dark theme"
);
is(
themeMenuItems[3].theme.id,
ALPENGLOW_THEME_ID,
"The fourth theme should be the alpenglow theme"
);
let themeChangedPromise = promiseObserverNotified(
"lightweight-theme-styling-update"
);
header.nextElementSibling.nextElementSibling.doCommand(); // Select light theme
info("Clicked on light theme");
await themeChangedPromise;
let button = document.getElementById("customization-reset-button");
await TestUtils.waitForCondition(() => !button.disabled);
// Check restore defaults button is enabled.
ok(!button.disabled, "Reset button should not be disabled anymore");
ok(
themesButtonIcon.style.backgroundImage === "",
`Button should still show no theme - was: "${themesButtonIcon.style.backgroundImage}"`
);
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button a third time");
await popupShownPromise;
let activeThemes = popup.querySelectorAll(
"toolbarbutton.customization-lwtheme-menu-theme[active]"
);
is(activeThemes.length, 1, "Exactly 1 theme should be selected");
if (activeThemes.length) {
is(
activeThemes[0].theme.id,
LIGHT_THEME_ID,
"Light theme should be selected"
);
}
popup.hidePopup();
// Install 5 themes:
let addons = [];
for (let n = 1; n <= 5; n++) {
addons.push(await installTheme("my-theme-" + n + "@example.com"));
}
addons = await Promise.all(addons);
ok(
!themesButtonIcon.style.backgroundImage,
`Button should show fallback theme thumbnail - was: "${themesButtonIcon.style.backgroundImage}"`
);
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button a fourth time");
await popupShownPromise;
activeThemes = popup.querySelectorAll(
"toolbarbutton.customization-lwtheme-menu-theme[active]"
);
is(activeThemes.length, 1, "Exactly 1 theme should be selected");
if (activeThemes.length) {
is(
activeThemes[0].theme.id,
"my-theme-5@example.com",
"Last installed theme should be selected"
);
}
let firstLWTheme = footer.previousElementSibling;
let firstLWThemeId = firstLWTheme.theme.id;
themeChangedPromise = promiseObserverNotified(
"lightweight-theme-styling-update"
);
firstLWTheme.doCommand();
info("Clicked on first theme");
await themeChangedPromise;
await new Promise(executeSoon);
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button");
await popupShownPromise;
activeThemes = popup.querySelectorAll(
"toolbarbutton.customization-lwtheme-menu-theme[active]"
);
is(activeThemes.length, 1, "Exactly 1 theme should be selected");
if (activeThemes.length) {
is(
activeThemes[0].theme.id,
firstLWThemeId,
"First theme should be selected"
);
}
is(
header.nextElementSibling.theme.id,
DEFAULT_THEME_ID,
"The first theme should be the Default theme"
);
let themeCount = 0;
let iterNode = header;
while (iterNode.nextElementSibling && iterNode.nextElementSibling.theme) {
themeCount++;
iterNode = iterNode.nextElementSibling;
}
is(
themeCount,
MAX_THEME_COUNT,
"There should be the max number of themes in the 'My Themes' section"
);
let defaultTheme = header.nextElementSibling;
defaultTheme.doCommand();
await new Promise(SimpleTest.executeSoon);
// ensure current theme isn't set to "Default"
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button a sixth time");
await popupShownPromise;
// check that "Restore Defaults" button resets theme
await gCustomizeMode.reset();
defaultTheme = await AddonManager.getAddonByID(DEFAULT_THEME_ID);
is(defaultTheme.isActive, true, "Current theme reset to default");
await endCustomizing();
await startCustomizing();
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button a seventh time");
await popupShownPromise;
header = document.getElementById("customization-lwtheme-menu-header");
is(header.hidden, false, "Header should never be hidden");
let themeNode = header.nextElementSibling;
is(
themeNode.theme.id,
DEFAULT_THEME_ID,
"The first theme should be the Default theme"
);
is(themeNode.hidden, false, "The default theme should never be hidden");
themeNode = themeNode.nextElementSibling;
is(
themeNode.theme.id,
LIGHT_THEME_ID,
"The second theme should be the Light theme"
);
is(themeNode.hidden, false, "The light theme should never be hidden");
themeNode = themeNode.nextElementSibling;
is(
themeNode.theme.id,
DARK_THEME_ID,
"The third theme should be the Dark theme"
);
is(themeNode.hidden, false, "The dark theme should never be hidden");
await Promise.all(addons.map(a => a.unload()));
});
add_task(async function asyncCleanup() {
await endCustomizing();
});

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

@ -6,8 +6,12 @@
requestLongerTimeout(2);
// Restoring default should reset theme and show an "undo" option which undoes the restoring operation.
// Restoring default should reset density and show an "undo" option which undoes
// the restoring operation.
add_task(async function() {
await SpecialPowers.pushPrefEnv({
set: [["browser.compactmode.show", true]],
});
let stopReloadButtonId = "stop-reload-button";
CustomizableUI.removeWidgetFromArea(stopReloadButtonId);
await startCustomizing();
@ -22,40 +26,50 @@ add_task(async function() {
);
is(undoResetButton.hidden, true, "The undo button is hidden before reset");
let themesButton = document.getElementById("customization-lwtheme-button");
let popup = document.getElementById("customization-lwtheme-menu");
let densityButton = document.getElementById("customization-uidensity-button");
let popup = document.getElementById("customization-uidensity-menu");
let popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(themesButton, {});
info("Clicked on themes button");
EventUtils.synthesizeMouseAtCenter(densityButton, {});
info("Clicked on density button");
await popupShownPromise;
let header = document.getElementById("customization-lwtheme-menu-header");
let firstLWTheme = header.nextElementSibling.nextElementSibling;
let firstLWThemeId = firstLWTheme.theme.id;
let themeChangedPromise = promiseObserverNotified(
"lightweight-theme-styling-update"
let compactModeItem = document.getElementById(
"customization-uidensity-menuitem-compact"
);
firstLWTheme.doCommand();
info("Clicked on first theme");
await themeChangedPromise;
let win = document.getElementById("main-window");
let densityChangedPromise = new Promise(resolve => {
let observer = new MutationObserver(() => {
if (win.getAttribute("uidensity") == "compact") {
resolve();
observer.disconnect();
}
});
observer.observe(win, {
attributes: true,
attributeFilter: ["uidensity"],
});
});
let theme = await AddonManager.getAddonByID(firstLWThemeId);
is(theme.isActive, true, "Theme changed to first option");
compactModeItem.doCommand();
info("Clicked on compact density");
await densityChangedPromise;
await gCustomizeMode.reset();
ok(CustomizableUI.inDefaultState, "In default state after reset");
is(undoResetButton.hidden, false, "The undo button is visible after reset");
theme = await AddonManager.getAddonByID("default-theme@mozilla.org");
is(theme.isActive, true, "Theme reset to default");
is(
win.hasAttribute("uidensity"),
false,
"The window has been restored to normal density."
);
await gCustomizeMode.undoReset();
theme = await AddonManager.getAddonByID(firstLWThemeId);
is(
theme.isActive,
true,
"Theme has been reset from default to original choice"
win.getAttribute("uidensity"),
"compact",
"Density has been reset to compact."
);
ok(!CustomizableUI.inDefaultState, "Not in default state after undo-reset");
is(
@ -70,6 +84,7 @@ add_task(async function() {
);
await gCustomizeMode.reset();
await SpecialPowers.popPrefEnv();
});
// Performing an action after a reset will hide the undo button.

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

@ -0,0 +1,22 @@
/* 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/. */
"use strict";
add_task(async function() {
await startCustomizing();
let themesButton = document.querySelector("#customization-lwtheme-button");
ok(!themesButton.hidden, "Customize Theme button is visible.");
let aboutAddonsPromise = BrowserTestUtils.waitForNewTab(
gBrowser,
"about:addons"
);
themesButton.click();
await aboutAddonsPromise;
// Removing about:addons tab.
BrowserTestUtils.removeTab(gBrowser.selectedTab);
await endCustomizing();
// Removing tab that held the customize window.
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

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

@ -15,10 +15,9 @@ add_task(async function testCustomize() {
await startCustomizing();
// Find the footer buttons to test.
let footerRow = document.getElementById("customization-lwtheme-menu-footer");
let [manageButton, getMoreButton] = footerRow.childNodes;
let manageButton = document.getElementById("customization-lwtheme-button");
// Check the manage button, it should open about:addons.
// Check the manage themes button, it should open about:addons.
let waitForNewTab = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
manageButton.click();
let addonsTab = await waitForNewTab;
@ -26,14 +25,6 @@ add_task(async function testCustomize() {
is(gBrowser.currentURI.spec, "about:addons", "Manage opened about:addons");
BrowserTestUtils.removeTab(addonsTab);
// Check the get more button, we mocked it to open getMoreURL.
waitForNewTab = BrowserTestUtils.waitForNewTab(gBrowser, getMoreURL);
getMoreButton.click();
addonsTab = await waitForNewTab;
is(gBrowser.currentURI.spec, getMoreURL, "Get more opened AMO");
BrowserTestUtils.removeTab(addonsTab);
let snapshot = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
true
@ -56,10 +47,7 @@ add_task(async function testCustomize() {
// Events are now [method, object, value, extra] as expected.
Assert.deepEqual(
relatedEvents,
[
["link", "customize", "manageThemes"],
["link", "customize", "getThemes"],
],
[["link", "customize", "manageThemes"]],
"The events are recorded correctly"
);

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

@ -10,9 +10,6 @@ customize-mode-uidensity =
.label = Density
customize-mode-done =
.label = Done
customize-mode-lwthemes-menu-manage =
.label = Manage
.accesskey = M
customize-mode-toolbars =
.label = Toolbars
customize-mode-titlebar =
@ -23,8 +20,6 @@ customize-mode-uidensity-menu-touch =
.tooltiptext = Touch
customize-mode-uidensity-auto-touch-mode-checkbox =
.label = Use Touch for Tablet Mode
customize-mode-lwthemes =
.label = Themes
customize-mode-overflow-list-description = Drag and drop items here to keep them within reach but out of your toolbar…
customize-mode-uidensity-menu-normal =
.label = Normal
@ -34,13 +29,10 @@ customize-mode-uidensity-menu-compact-unsupported =
.label = Compact (not supported)
.accesskey = C
.tooltiptext = Compact (not supported)
customize-mode-lwthemes-menu-get-more =
.label = Get More Themes
.accesskey = G
customize-mode-undo-cmd =
.label = Undo
customize-mode-lwthemes-my-themes =
.value = My Themes
customize-mode-lwthemes-button =
.label = Manage Themes
customize-mode-touchbar-cmd =
.label = Customize Touch Bar…
customize-mode-downloads-button-autohide =