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:
Jared Wein 2019-07-30 22:44:26 +00:00
Родитель 6abdf8f681
Коммит 8368e23810
9 изменённых файлов: 220 добавлений и 2 удалений

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

@ -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 =