зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1562328 - Custom element for Sync button in header of about:logins. r=fluent-reviewers,MattN,Pike,lina
Differential Revision: https://phabricator.services.mozilla.com/D38001 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6abdf8f681
Коммит
8368e23810
|
@ -25,6 +25,7 @@ login-filter {
|
|||
align-self: center;
|
||||
}
|
||||
|
||||
fxaccounts-button,
|
||||
menu-button {
|
||||
margin-inline-start: 18px;
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; object-src 'none'; script-src resource: chrome:; img-src data: blob:;"/>
|
||||
<title data-l10n-id="about-logins-page-title"></title>
|
||||
<link rel="localization" href="browser/branding/sync-brand.ftl">
|
||||
<link rel="localization" href="browser/aboutLogins.ftl">
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/confirmation-dialog.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/fxaccounts-button.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/login-filter.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/login-item.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/login-list.js"></script>
|
||||
|
@ -25,6 +27,7 @@
|
|||
<header>
|
||||
<img id="branding-logo" src="chrome://branding/content/aboutlogins.svg" alt=""/>
|
||||
<login-filter></login-filter>
|
||||
<fxaccounts-button></fxaccounts-button>
|
||||
<menu-button></menu-button>
|
||||
</header>
|
||||
<login-list></login-list>
|
||||
|
@ -51,6 +54,20 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<template id="fxaccounts-button-template">
|
||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/fxaccounts-button.css">
|
||||
<div class="logged-out-view">
|
||||
<p class="fxaccounts-extra-text" data-l10n-id="fxaccounts-sign-in-text"></p>
|
||||
<button class="fxaccounts-enable-button" data-l10n-id="fxaccounts-sign-in-button"></button>
|
||||
</div>
|
||||
<div class="logged-in-view">
|
||||
<p class="fxaccount-email"></p>
|
||||
<button class="fxaccounts-avatar-button"></button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="login-list-template">
|
||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* 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/. */
|
||||
|
||||
.logged-out-view,
|
||||
.logged-in-view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fxaccounts-extra-text {
|
||||
color: var(--in-content-deemphasized-text);
|
||||
font-size: smaller;
|
||||
width: 250px;
|
||||
text-align: end;
|
||||
margin-inline-start: 36px;
|
||||
}
|
||||
|
||||
.fxaccounts-avatar-button,
|
||||
.fxaccounts-enable-button {
|
||||
margin-inline-start: 9px;
|
||||
}
|
||||
|
||||
.fxaccount-email {
|
||||
font-weight: bold;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.fxaccounts-avatar-button {
|
||||
background-image: var(--avatar-url),
|
||||
url(chrome://browser/skin/fxa/avatar-color.svg);
|
||||
background-color: transparent;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border: 1px solid var(--in-content-border-color);
|
||||
border-radius: 1000px;
|
||||
width: 32px;
|
||||
min-width: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fxaccounts-avatar-button:hover {
|
||||
border-color: var(--in-content-border-hover);
|
||||
}
|
||||
|
||||
.fxaccounts-avatar-button:hover:active {
|
||||
border-color: var(--in-content-border-active);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* 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/. */
|
||||
|
||||
export default class FxAccountsButton extends HTMLElement {
|
||||
connectedCallback() {
|
||||
if (this.shadowRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
let template = document.querySelector("#fxaccounts-button-template");
|
||||
let shadowRoot = this.attachShadow({ mode: "open" });
|
||||
document.l10n.connectRoot(shadowRoot);
|
||||
shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
|
||||
this._avatarButton = shadowRoot.querySelector(".fxaccounts-avatar-button");
|
||||
this._extraText = shadowRoot.querySelector(".fxaccounts-extra-text");
|
||||
this._enableButton = shadowRoot.querySelector(".fxaccounts-enable-button");
|
||||
this._loggedOutView = shadowRoot.querySelector(".logged-out-view");
|
||||
this._loggedInView = shadowRoot.querySelector(".logged-in-view");
|
||||
this._emailText = shadowRoot.querySelector(".fxaccount-email");
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
this._loggedOutView.hidden = !!this._loggedIn;
|
||||
this._loggedInView.hidden = !this._loggedIn;
|
||||
this._emailText.textContent = this._email;
|
||||
this._avatarButton.style.setProperty(
|
||||
"--avatar-url",
|
||||
`url(${this._avatarURL})`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} state
|
||||
* loggedIn: {Boolean} FxAccount authentication
|
||||
* status.
|
||||
* email: {String} Email address used with FxAccount. Must
|
||||
* be empty if `loggedIn` is false.
|
||||
* avatarURL: {String} URL of account avatar. Must
|
||||
* be empty if `loggedIn` is false.
|
||||
*/
|
||||
updateState(state) {
|
||||
this._loggedIn = state.loggedIn;
|
||||
this._email = state.email;
|
||||
this._avatarURL = state.avatarURL;
|
||||
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
customElements.define("fxaccounts-button", FxAccountsButton);
|
|
@ -5,6 +5,8 @@
|
|||
browser.jar:
|
||||
content/browser/aboutlogins/components/confirmation-dialog.css (content/components/confirmation-dialog.css)
|
||||
content/browser/aboutlogins/components/confirmation-dialog.js (content/components/confirmation-dialog.js)
|
||||
content/browser/aboutlogins/components/fxaccounts-button.css (content/components/fxaccounts-button.css)
|
||||
content/browser/aboutlogins/components/fxaccounts-button.js (content/components/fxaccounts-button.js)
|
||||
content/browser/aboutlogins/components/login-filter.css (content/components/login-filter.css)
|
||||
content/browser/aboutlogins/components/login-filter.js (content/components/login-filter.js)
|
||||
content/browser/aboutlogins/components/login-item.css (content/components/login-item.css)
|
||||
|
|
|
@ -36,12 +36,18 @@ Object.defineProperty(document, "l10n", {
|
|||
getAttributes(element) {
|
||||
return {
|
||||
id: element.getAttribute("data-l10n-id"),
|
||||
args: JSON.parse(element.getAttribute("data-l10n-args")),
|
||||
args: element.getAttribute("data-l10n-args")
|
||||
? JSON.parse(element.getAttribute("data-l10n-args"))
|
||||
: {},
|
||||
};
|
||||
},
|
||||
setAttributes(element, id, args) {
|
||||
element.setAttribute("data-l10n-id", id);
|
||||
element.setAttribute("data-l10n-args", JSON.stringify(args));
|
||||
if (args) {
|
||||
element.setAttribute("data-l10n-args", JSON.stringify(args));
|
||||
} else {
|
||||
element.removeAttribute("data-l10n-args");
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@ support-files =
|
|||
aboutlogins_common.js
|
||||
|
||||
[test_confirm_delete_dialog.html]
|
||||
[test_fxaccounts_button.html]
|
||||
[test_login_filter.html]
|
||||
[test_login_item.html]
|
||||
[test_login_list.html]
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test the fxaccounts-button component
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the fxaccounts-button component</title>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="module" src="chrome://browser/content/aboutlogins/components/fxaccounts-button.js"></script>
|
||||
<script src="aboutlogins_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display">
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id="templateFrame" src="chrome://browser/content/aboutlogins/aboutLogins.html"
|
||||
sandbox="allow-same-origin"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script>
|
||||
/** Test the fxaccounts-button component **/
|
||||
|
||||
let gFxAccountsButton;
|
||||
add_task(async function setup() {
|
||||
let templateFrame = document.getElementById("templateFrame");
|
||||
let displayEl = document.getElementById("display");
|
||||
importDependencies(templateFrame, displayEl);
|
||||
|
||||
gFxAccountsButton = document.createElement("fxaccounts-button");
|
||||
displayEl.appendChild(gFxAccountsButton);
|
||||
});
|
||||
|
||||
add_task(async function test_default_state() {
|
||||
ok(gFxAccountsButton, "FxAccountsButton exists");
|
||||
ok(!isHidden(gFxAccountsButton.shadowRoot.querySelector(".logged-out-view")),
|
||||
"logged-out-view view is visible by default");
|
||||
ok(isHidden(gFxAccountsButton.shadowRoot.querySelector(".logged-in-view")),
|
||||
"logged-in-view view is hidden by default");
|
||||
});
|
||||
|
||||
add_task(async function test_logged_in_without_login_syncing() {
|
||||
gFxAccountsButton.updateState({
|
||||
loggedIn: true,
|
||||
loginSyncingEnabled: false,
|
||||
});
|
||||
|
||||
ok(isHidden(gFxAccountsButton.shadowRoot.querySelector(".logged-out-view")),
|
||||
"logged-out-view view is hidden");
|
||||
ok(!isHidden(gFxAccountsButton.shadowRoot.querySelector(".logged-in-view")),
|
||||
"logged-in-view view is visible");
|
||||
});
|
||||
|
||||
add_task(async function test_logged_in_without_login_syncing() {
|
||||
const TEST_EMAIL = "test@example.com";
|
||||
const TEST_AVATAR_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
|
||||
|
||||
gFxAccountsButton.updateState({
|
||||
loggedIn: true,
|
||||
loginSyncingEnabled: true,
|
||||
email: TEST_EMAIL,
|
||||
avatarURL: TEST_AVATAR_URL,
|
||||
});
|
||||
|
||||
ok(isHidden(gFxAccountsButton.shadowRoot.querySelector(".logged-out-view")),
|
||||
"logged-out-view view is hidden");
|
||||
ok(!isHidden(gFxAccountsButton.shadowRoot.querySelector(".logged-in-view")),
|
||||
"logged-in-view view is visible");
|
||||
is(gFxAccountsButton.shadowRoot.querySelector(".fxaccount-email").textContent,
|
||||
TEST_EMAIL,
|
||||
"email should be shown");
|
||||
info(gFxAccountsButton.shadowRoot.querySelector(".fxaccounts-avatar-button").outerHTML);
|
||||
is(gFxAccountsButton.shadowRoot.querySelector(".fxaccounts-avatar-button").style.getPropertyValue("--avatar-url"),
|
||||
`url(${TEST_AVATAR_URL})`,
|
||||
"--avatar-url should be set");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -9,6 +9,9 @@ login-filter =
|
|||
|
||||
create-login-button = Create New Login
|
||||
|
||||
fxaccounts-sign-in-text = Get your passwords on your other devices
|
||||
fxaccounts-sign-in-button = Sign in to { -sync-brand-short-name }
|
||||
|
||||
## The ⋯ menu that is in the top corner of the page
|
||||
|
||||
menu =
|
||||
|
|
Загрузка…
Ссылка в новой задаче