Bug 1840488 - Change from classes to a state attribute for the migration wizard progress icon. r=tgiles,desktop-theme-reviewers,dao

Differential Revision: https://phabricator.services.mozilla.com/D182274
This commit is contained in:
Mike Conley 2023-06-28 16:46:19 +00:00
Родитель e0fc545cbc
Коммит a40dcbf105
11 изменённых файлов: 148 добавлений и 131 удалений

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

@ -992,7 +992,7 @@ class MigrationUtils {
if (!importedAddonIDs.length) {
return [
lazy.MigrationWizardConstants.PROGRESS_VALUE.ERROR,
lazy.MigrationWizardConstants.PROGRESS_VALUE.WARNING,
importedAddonIDs,
];
}

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

@ -431,7 +431,7 @@ export class MigrationWizardParent extends JSWindowActorParent {
extraArgs.extensions =
lazy.MigrationWizardConstants.EXTENSIONS_IMPORT_RESULT.NONE_MATCHED;
progress[foundResourceTypeName] = {
value: lazy.MigrationWizardConstants.PROGRESS_VALUE.ERROR,
value: lazy.MigrationWizardConstants.PROGRESS_VALUE.WARNING,
message: await lazy.gFluentStrings.formatValue(
"migration-wizard-progress-no-matched-extensions"
),
@ -487,7 +487,7 @@ export class MigrationWizardParent extends JSWindowActorParent {
progress[foundResourceTypeName] = {
value: success
? lazy.MigrationWizardConstants.PROGRESS_VALUE.SUCCESS
: lazy.MigrationWizardConstants.PROGRESS_VALUE.ERROR,
: lazy.MigrationWizardConstants.PROGRESS_VALUE.WARNING,
message: await this.#getStringForImportQuantity(
migrationDetails.key,
foundResourceTypeName

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

@ -34,7 +34,7 @@ export const MigrationWizardConstants = Object.freeze({
PROGRESS_VALUE: Object.freeze({
LOADING: 1,
SUCCESS: 2,
ERROR: 3,
WARNING: 3,
INFO: 4,
}),

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

@ -704,7 +704,6 @@ export class MigrationWizard extends HTMLElement {
);
}
}
progressIcon.classList.remove("completed", "error");
successText.textContent = "";
if (extensionsSuccessLink) {
extensionsSuccessLink.textContent = "";
@ -721,7 +720,7 @@ export class MigrationWizard extends HTMLElement {
progressIcon,
"migration-wizard-progress-icon-in-progress"
);
progressIcon.classList.remove("completed");
progressIcon.setAttribute("state", "loading");
successText.textContent = "";
if (extensionsSuccessLink) {
extensionsSuccessLink.textContent = "";
@ -739,7 +738,7 @@ export class MigrationWizard extends HTMLElement {
progressIcon,
"migration-wizard-progress-icon-completed"
);
progressIcon.classList.add("completed");
progressIcon.setAttribute("state", "success");
successText.textContent = state.progress[resourceType].message;
if (
resourceType ==
@ -753,13 +752,12 @@ export class MigrationWizard extends HTMLElement {
remainingProgressGroups--;
break;
}
case MigrationWizardConstants.PROGRESS_VALUE.ERROR: {
case MigrationWizardConstants.PROGRESS_VALUE.WARNING: {
document.l10n.setAttributes(
progressIcon,
"migration-wizard-progress-icon-completed"
);
progressIcon.classList.add("completed");
progressIcon.classList.add("error-icon");
progressIcon.setAttribute("state", "warning");
successText.textContent = state.progress[resourceType].message;
supportLink.textContent = state.progress[resourceType].linkText;
supportLink.href = state.progress[resourceType].linkURL;
@ -771,7 +769,7 @@ export class MigrationWizard extends HTMLElement {
progressIcon,
"migration-wizard-progress-icon-completed"
);
progressIcon.classList.add("completed");
progressIcon.setAttribute("state", "info");
successText.textContent = state.progress[resourceType].message;
supportLink.textContent = state.progress[resourceType].linkText;
supportLink.href = state.progress[resourceType].linkURL;
@ -863,7 +861,7 @@ export class MigrationWizard extends HTMLElement {
progressIcon,
"migration-wizard-progress-icon-in-progress"
);
progressIcon.classList.remove("completed");
progressIcon.setAttribute("state", "loading");
successText.textContent = "";
// With no status text, we re-insert the   so that the status
// text area does not fully collapse.
@ -875,22 +873,27 @@ export class MigrationWizard extends HTMLElement {
progressIcon,
"migration-wizard-progress-icon-completed"
);
progressIcon.classList.add("completed");
progressIcon.setAttribute("state", "success");
successText.textContent = state.progress[resourceType].message;
remainingProgressGroups--;
break;
}
case MigrationWizardConstants.PROGRESS_VALUE.ERROR: {
case MigrationWizardConstants.PROGRESS_VALUE.WARNING: {
document.l10n.setAttributes(
progressIcon,
"migration-wizard-progress-icon-completed"
);
progressIcon.classList.add("completed");
progressIcon.classList.add("error-icon");
progressIcon.setAttribute("state", "warning");
successText.textContent = state.progress[resourceType].message;
remainingProgressGroups--;
break;
}
default: {
console.error(
"Unrecognized state for file migration: ",
progressValue
);
}
}
}
@ -938,10 +941,10 @@ export class MigrationWizard extends HTMLElement {
// progress elements as custom parts that the MigrationWizard story
// can style on its own.
this.#shadowRoot.querySelectorAll(".progress-icon").forEach(progressEl => {
if (progressEl.classList.contains("completed")) {
progressEl.removeAttribute("part");
} else {
if (progressEl.getAttribute("state") == "loading") {
progressEl.setAttribute("part", "progress-spinner");
} else {
progressEl.removeAttribute("part");
}
});
}

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

@ -20,8 +20,6 @@ let gFluentStrings = new Localization([
* @param {object} description
* An object to express more details of how the resource group should be
* displayed.
* @param {string[]} description.progressIconClasses
* The CSS classes that are expected to be applied to the progress icon.
* @param {string} description.message
* The message that should be displayed for the resource group. This message
* maybe be contained in different elements depending on the state.
@ -47,18 +45,12 @@ function assertExtensionsProgressState(wizard, state, description) {
);
let progressIcon = progressGroup.querySelector(".progress-icon");
for (let iconClass of description.progressIconClasses) {
Assert.ok(
progressIcon.classList.contains(iconClass),
`Progress icon should have class ${iconClass}`
);
}
let successText = progressGroup.querySelector("span.success-text");
let supportLink = progressGroup.querySelector(".support-text");
let extensionsSuccessLink = progressGroup.querySelector("a.success-text");
if (state == MigrationWizardConstants.PROGRESS_VALUE.SUCCESS) {
Assert.stringMatches(progressIcon.getAttribute("state"), "success");
Assert.stringMatches(successText.textContent, "");
Assert.stringMatches(extensionsSuccessLink.href, "about:addons");
@ -67,11 +59,13 @@ function assertExtensionsProgressState(wizard, state, description) {
description.message
);
Assert.stringMatches(supportLink.textContent, "");
} else if (state == MigrationWizardConstants.PROGRESS_VALUE.ERROR) {
} else if (state == MigrationWizardConstants.PROGRESS_VALUE.WARNING) {
Assert.stringMatches(progressIcon.getAttribute("state"), "warning");
Assert.stringMatches(successText.textContent, description.message);
Assert.stringMatches(supportLink.textContent, description.linkText);
Assert.stringMatches(supportLink.href, description.linkURL);
} else if (state == MigrationWizardConstants.PROGRESS_VALUE.INFO) {
Assert.stringMatches(progressIcon.getAttribute("state"), "info");
Assert.stringMatches(extensionsSuccessLink.href, description.linkURL);
Assert.stringMatches(
extensionsSuccessLink.textContent,
@ -109,9 +103,8 @@ add_task(async function test_extension_migration_no_matched_extensions() {
await wizardDone;
assertExtensionsProgressState(
wizard,
MigrationWizardConstants.PROGRESS_VALUE.ERROR,
MigrationWizardConstants.PROGRESS_VALUE.WARNING,
{
progressIconClasses: ["completed", "error-icon"],
message: await gFluentStrings.formatValue(
"migration-wizard-progress-no-matched-extensions"
),
@ -160,7 +153,6 @@ add_task(
wizard,
MigrationWizardConstants.PROGRESS_VALUE.INFO,
{
progressIconClasses: ["completed"],
message: await gFluentStrings.formatValue(
"migration-wizard-progress-partial-success-extensions",
{
@ -211,7 +203,6 @@ add_task(async function test_extension_migration_fully_matched_extensions() {
wizard,
MigrationWizardConstants.PROGRESS_VALUE.SUCCESS,
{
progressIconClasses: ["completed"],
message: await gFluentStrings.formatValue(
"migration-wizard-progress-success-extensions",
{

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

@ -174,8 +174,9 @@ add_task(async function test_file_migration() {
SUCCESS_STATE[progressGroup.dataset.resourceType];
if (expectedSuccessText) {
let progressIcon = progressGroup.querySelector(".progress-icon");
Assert.ok(
progressIcon.classList.contains("completed"),
Assert.stringMatches(
progressIcon.getAttribute("state"),
"success",
"Should be showing completed state."
);

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

@ -390,9 +390,10 @@ function assertQuantitiesShown(wizard, expectedResourceTypes) {
let successText =
progressGroup.querySelector(".success-text").textContent;
Assert.ok(
progressIcon.classList.contains("completed"),
"Should be showing completed state."
Assert.notEqual(
progressIcon.getAttribute("state"),
"loading",
"Should no longer be in the loading state."
);
if (

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

@ -485,8 +485,9 @@
);
ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible");
let progressIcon = bookmarksGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -506,8 +507,9 @@
);
ok(!isHidden(historyGroup), "History group should be visible");
progressIcon = historyGroup.querySelector(".progress-icon");
ok(
!progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"loading",
"Progress should be still be underway"
);
is(historyGroup.querySelector(".success-text").textContent.trim(), "");
@ -516,9 +518,10 @@
let extensionsGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS);
ok(!isHidden(extensionsGroup), "Extensions group should be visible");
progressIcon = extensionsGroup.querySelector(".progress-icon");
ok(
!progressIcon.classList.contains("completed"),
"Progress should still be underway"
is(
progressIcon.getAttribute("state"),
"loading",
"Progress should be still be underway"
);
is(extensionsGroup.querySelector("a.success-text").textContent.trim(), "");
is(extensionsGroup.querySelector("span.success-text").textContent.trim(), "");
@ -529,8 +532,9 @@
);
ok(!isHidden(formDataGroup), "Form data group should be visible");
progressIcon = formDataGroup.querySelector(".progress-icon");
ok(
!progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"loading",
"Progress should be still be underway"
);
is(formDataGroup.querySelector(".success-text").textContent.trim(), "");
@ -596,8 +600,9 @@
);
ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible");
let progressIcon = bookmarksGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -611,8 +616,9 @@
);
ok(!isHidden(passwordsGroup), "Passwords group should be visible");
progressIcon = passwordsGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -630,8 +636,9 @@
let extensionsDataGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS);
ok(!isHidden(extensionsDataGroup), "Extensions data group should be visible");
progressIcon = extensionsDataGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -648,8 +655,9 @@
);
ok(!isHidden(formDataGroup), "Form data group should be visible");
progressIcon = formDataGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -700,9 +708,10 @@
let extensionsGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS);
ok(!isHidden(extensionsGroup), "Extensions group should be visible");
let progressIcon = extensionsGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
"Progress should be completed"
is(
progressIcon.getAttribute("state"),
"info",
"Progress should be completed, in info state"
);
is(
extensionsGroup.querySelector("a.success-text").textContent,
@ -747,7 +756,7 @@
key: "chrome",
progress: {
[MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: {
value: MigrationWizardConstants.PROGRESS_VALUE.ERROR,
value: MigrationWizardConstants.PROGRESS_VALUE.WARNING,
message: EXTENSIONS_ERROR_STRING,
linkText: EXTENSIONS_SUPPORT_STRING,
linkURL: EXTENSIONS_SUPPORT_HREF,
@ -763,14 +772,7 @@
let extensionsGroup = getResourceGroup(MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS);
ok(!isHidden(extensionsGroup), "Extensions group should be visible");
let progressIcon = extensionsGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
"Progress should be completed"
);
ok(
progressIcon.classList.contains("error-icon"),
"Error icon should be showing"
)
is(progressIcon.getAttribute("state"), "warning");
is(
extensionsGroup.querySelector("a.success-text").textContent,
""
@ -839,8 +841,9 @@
);
ok(!isHidden(passwordsFromFileGroup), "Passwords from file group should be visible");
let progressIcon = passwordsFromFileGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -858,8 +861,9 @@
);
ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible");
progressIcon = passwordsNewGroup.querySelector(".progress-icon");
ok(
!progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"loading",
"Progress should be still be underway"
);
is(passwordsNewGroup.querySelector(".success-text").textContent.trim(), "");
@ -908,8 +912,9 @@
);
ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible");
let progressIcon = passwordsNewGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -922,8 +927,9 @@
);
ok(!isHidden(passwordsUpdatedGroup), "Passwords updated group should be visible");
progressIcon = passwordsUpdatedGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -1217,8 +1223,9 @@
);
ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible");
let progressIcon = bookmarksGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -1238,9 +1245,10 @@
});
ok(!isHidden(bookmarksGroup), "Bookmarks group should be visible");
ok(
!progressIcon.classList.contains("completed"),
"Progress should still be underway"
is(
progressIcon.getAttribute("state"),
"loading",
"Progress should be still be underway"
);
is(
bookmarksGroup.querySelector(".success-text").textContent.trim(),
@ -1274,8 +1282,9 @@
);
ok(!isHidden(passwordsGroup), "Passwords group should be visible");
let progressIcon = passwordsGroup.querySelector(".progress-icon");
ok(
progressIcon.classList.contains("completed"),
is(
progressIcon.getAttribute("state"),
"success",
"Progress should be completed"
);
is(
@ -1295,9 +1304,10 @@
});
ok(!isHidden(passwordsGroup), "Passwords group should be visible");
ok(
!progressIcon.classList.contains("completed"),
"Progress should still be underway"
is(
progressIcon.getAttribute("state"),
"loading",
"Progress should be still be underway"
);
is(
passwordsGroup.querySelector(".success-text").textContent.trim(),

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

@ -353,7 +353,7 @@ ExtensionsImportFailure.args = {
message: "From the last 180 days",
},
[MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.EXTENSIONS]: {
value: MigrationWizardConstants.PROGRESS_VALUE.ERROR,
value: MigrationWizardConstants.PROGRESS_VALUE.WARNING,
message: "No matching extensions",
linkText: "Browse extensions for Firefox",
linkURL: "https://addons.mozilla.org/",

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

@ -229,16 +229,68 @@ summary {
grid-area: support;
}
/**
* Workaround for bug 1671784, which shows a slight outline around the
* rotating masked element.
*/
.progress-icon-parent {
border-radius: 0.01px;
overflow: hidden;
display: flex;
align-items: center;
}
.progress-icon {
display: inline-block;
width: 16px;
height: 16px;
content: url("chrome://browser/skin/migration/success.svg");
-moz-context-properties: fill;
fill: var(--in-content-success-icon-color);
margin-inline-end: 8px;
}
/**
* For now, both the success and info icon states appear the same.
*/
.progress-icon[state="success"],
.progress-icon[state="info"] {
content: url("chrome://browser/skin/migration/success.svg");
fill: var(--in-content-success-icon-color);
}
.progress-icon[state="warning"] {
content: url("chrome://global/skin/icons/warning.svg");
fill: var(--in-content-warning-icon-color);
}
@media (prefers-reduced-motion: reduce) {
.progress-icon[state="loading"] {
content: url("chrome://browser/skin/tabbrowser/hourglass.svg");
fill: var(--text-color-deemphasized);
}
}
@media (prefers-reduced-motion: no-preference) {
.progress-icon[state="loading"] {
content: "";
background-image: conic-gradient(rgba(255, 255, 255, 0.31) 0%, rgba(255, 189, 79, 0.57) 38%, rgba(255, 74, 162, 0.79) 70%, rgb(144, 89, 255) 100%);
mask: url("chrome://browser/skin/migration/progress-mask.svg");
mask-composite: exclude;
animation-name: rotate;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.error-icon {
content: url("chrome://global/skin/icons/error.svg");
-moz-context-properties: fill;
@ -290,17 +342,6 @@ div[name="page-selection"]:not([file-import-error]) .file-import-error {
display: none;
}
/**
* Workaround for bug 1671784, which shows a slight outline around the
* rotating masked element.
*/
.progress-icon-parent {
border-radius: 0.01px;
overflow: hidden;
display: flex;
align-items: center;
}
div[name="page-selection"][show-import-all] .resource-selection-details {
padding-inline-start: 8px;
}
@ -312,35 +353,3 @@ div[name="page-selection"][show-import-all] .resource-selection-details {
"c b";
margin-block: 16px 0;
}
@media (prefers-reduced-motion: reduce) {
.progress-icon:not(.completed) {
content: url("chrome://browser/skin/tabbrowser/hourglass.svg");
fill: var(--text-color-deemphasized);
}
}
@media (prefers-reduced-motion: no-preference) {
.progress-icon:not(.completed) {
content: "";
background-image: conic-gradient(rgba(255, 255, 255, 0.31) 0%, rgba(255, 189, 79, 0.57) 38%, rgba(255, 74, 162, 0.79) 70%, rgb(144, 89, 255) 100%);
mask: url("chrome://browser/skin/migration/progress-mask.svg");
mask-composite: exclude;
}
.progress-icon:not(.completed) {
animation-name: rotate;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

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

@ -27,6 +27,7 @@
--in-content-border-invalid: var(--red-50);
--in-content-border-color: #d7d7db;
--in-content-error-text-color: #c50042;
--in-content-warning-icon-color: #ffa436;
--in-content-success-icon-color: #2ac3a2;
--in-content-link-color: var(--in-content-primary-button-background);
--in-content-link-color-hover: var(--in-content-primary-button-background-hover);
@ -144,6 +145,7 @@
--in-content-border-invalid: rgb(255,132,139);
--in-content-error-text-color: #FF9AA2;
--in-content-warning-icon-color: #ffbd4f;
--in-content-success-icon-color: #54FFBD;
--in-content-icon-color: rgb(251,251,254);