Bug 1578736 - Wrong context menu is displayed when right click on the website's link r=jaws

Differential Revision: https://phabricator.services.mozilla.com/D62842

--HG--
extra : moz-landing-system : lando
This commit is contained in:
mcrawford@mozilla.com 2020-02-25 20:42:03 +00:00
Родитель ee067a4465
Коммит 71dcb2ac84
6 изменённых файлов: 29 добавлений и 60 удалений

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

@ -133,12 +133,6 @@ class AboutLoginsChild extends JSWindowActorChild {
this.sendAsyncMessage("AboutLogins:OpenPreferences");
break;
}
case "AboutLoginsOpenSite": {
this.sendAsyncMessage("AboutLogins:OpenSite", {
login: event.detail,
});
break;
}
case "AboutLoginsRecordTelemetryEvent": {
let { method, object, extra = {} } = event.detail;

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

@ -313,23 +313,6 @@ class AboutLoginsParent extends JSWindowActorParent {
ownerGlobal.openPreferences("privacy-logins");
break;
}
case "AboutLogins:OpenSite": {
let guid = message.data.login.guid;
let logins = LoginHelper.searchLoginsWithObject({ guid });
if (logins.length != 1) {
log.warn(
`AboutLogins:OpenSite: expected to find a login for guid: ${guid} but found ${
logins.length
}`
);
return;
}
ownerGlobal.openWebLinkIn(logins[0].origin, "tab", {
relatedToCurrent: true,
});
break;
}
case "AboutLogins:MasterPasswordRequest": {
// This does no harm if master password isn't set.
let tokendb = Cc["@mozilla.org/security/pk11tokendb;1"].createInstance(

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

@ -186,11 +186,11 @@
size on page load since it always starts readonly. -->
<input type="url"
name="origin"
class="origin-input"
required
data-l10n-id="login-item-origin"
dir="auto"
readonly/>
<a class="origin-input" dir="auto" target="_blank" rel="noreferrer" name="origin" href=""></a>
</label>
</div>
<div class="detail-row">

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

@ -51,6 +51,9 @@ export default class LoginItem extends HTMLElement {
);
this._form = this.shadowRoot.querySelector("form");
this._originInput = this.shadowRoot.querySelector("input[name='origin']");
this._originDisplayInput = this.shadowRoot.querySelector(
"a[name='origin']"
);
this._usernameInput = this.shadowRoot.querySelector(
"input[name='username']"
);
@ -100,6 +103,7 @@ export default class LoginItem extends HTMLElement {
this._originInput.addEventListener("click", this);
this._originInput.addEventListener("mousedown", this, true);
this._originInput.addEventListener("auxclick", this);
this._originDisplayInput.addEventListener("click", this);
this._revealCheckbox.addEventListener("click", this);
window.addEventListener("AboutLoginsInitialLoginSelected", this);
window.addEventListener("AboutLoginsLoadInitialFavicon", this);
@ -169,6 +173,11 @@ export default class LoginItem extends HTMLElement {
this._title.textContent = this._login.title;
this._title.title = this._login.title;
this._originInput.defaultValue = this._login.origin || "";
if (this._login.origin) {
// Creates anchor element with origin URL
this._originDisplayInput.href = this._login.origin || "";
this._originDisplayInput.innerText = this._login.origin || "";
}
this._usernameInput.defaultValue = this._login.username || "";
if (this._login.password) {
// We use .value instead of .defaultValue since the latter updates the
@ -205,6 +214,7 @@ export default class LoginItem extends HTMLElement {
: "login-item-save-changes-button"
);
this._updatePasswordRevealState();
this._updateOriginDisplayState();
}
setBreaches(breachesByLoginGUID) {
@ -680,13 +690,6 @@ export default class LoginItem extends HTMLElement {
}
_handleOriginClick() {
document.dispatchEvent(
new CustomEvent("AboutLoginsOpenSite", {
bubbles: true,
detail: this._login,
})
);
this._recordTelemetryEvent({
object: "existing_login",
method: "open_site",
@ -811,5 +814,15 @@ export default class LoginItem extends HTMLElement {
this._passwordInput.remove();
}
}
_updateOriginDisplayState() {
// Switches between the origin input and anchor tag depending
// if a new login is being created.
if (this.dataset.editing) {
this._originDisplayInput.replaceWith(this._originInput);
} else {
this._originInput.replaceWith(this._originDisplayInput);
}
}
}
customElements.define("login-item", LoginItem);

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

@ -30,7 +30,7 @@ add_task(async function test_launch_login_item() {
"discard-changes confirmation-dialog should be hidden before opening the site"
);
let originInput = loginItem.shadowRoot.querySelector(".origin-input");
let originInput = loginItem.shadowRoot.querySelector("a[name='origin']");
let EventUtils = ContentTaskUtils.getEventUtils(content);
// Use synthesizeMouseAtCenter to generate an event that more closely resembles the
// properties of the event object that will be seen when the user clicks the element

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

@ -70,7 +70,7 @@ add_task(async function setup() {
add_task(async function test_empty_item() {
ok(gLoginItem, "loginItem exists");
is(gLoginItem.shadowRoot.querySelector("input[name='origin']").value, "", "origin should be blank");
is(gLoginItem.shadowRoot.querySelector("a[name='origin']").getAttribute("href"), "", "origin should be blank");
is(gLoginItem.shadowRoot.querySelector("input[name='username']").value, "", "username should be blank");
is(gLoginItem._passwordInput.value, "", "password should be blank");
ok(!gLoginItem._passwordInput.isConnected, "Real password input should be disconnected");
@ -87,8 +87,8 @@ add_task(async function test_set_login() {
ok(!gLoginItem.dataset.editing, "loginItem should not be in 'edit' mode");
ok(!gLoginItem.dataset.isNewLogin, "loginItem should not be in 'isNewLogin' mode");
let originInput = gLoginItem.shadowRoot.querySelector("input[name='origin']");
is(originInput.value, TEST_LOGIN_1.origin, "origin should be populated");
let originLink = gLoginItem.shadowRoot.querySelector("a[name='origin']");
is(originLink.getAttribute("href"), TEST_LOGIN_1.origin, "origin should be populated");
let usernameInput = gLoginItem.shadowRoot.querySelector("input[name='username']");
is(usernameInput.value, TEST_LOGIN_1.username, "username should be populated");
is(document.l10n.getAttributes(usernameInput).id, "about-logins-login-item-username", "username field should have default placeholder when not editing");
@ -107,27 +107,6 @@ add_task(async function test_set_login() {
let copyButtons = [...gLoginItem.shadowRoot.querySelectorAll(".copy-button")];
ok(copyButtons.every(button => !isHidden(button)), "The copy buttons should be visible when viewing a login");
let openSiteEventDispatched = false;
document.addEventListener("AboutLoginsOpenSite", event => {
is(event.detail.guid, TEST_LOGIN_1.guid, "event should include guid");
openSiteEventDispatched = true;
}, {once: true});
originInput.click();
ok(openSiteEventDispatched, "Clicking the .origin-input should dispatch the AboutLoginsOpenSite event");
openSiteEventDispatched = false;
document.addEventListener("AboutLoginsOpenSite", event => {
is(event.detail.guid, TEST_LOGIN_1.guid, "event should include guid");
openSiteEventDispatched = true;
}, {once: true});
synthesizeMouseAtCenter(originInput, {button: 1});
ok(openSiteEventDispatched, "Middle-clicking the .origin-input should dispatch the AboutLoginsOpenSite event");
document.addEventListener("AboutLoginsOpenSite", event => {
ok(false, "right-clicking the .origin-input should not trigger the AboutLoginsOpenSite event");
}, {once: true});
synthesizeMouseAtCenter(originInput, {button: 2});
let loginNoUsername = Object.assign({}, TEST_LOGIN_1, {username: ""});
gLoginItem.setLogin(loginNoUsername);
ok(!gLoginItem.dataset.editing, "loginItem should not be in 'edit' mode");
@ -154,7 +133,7 @@ add_task(async function test_update_breaches() {
let correspondingBreach = TEST_BREACHES_MAP.get(gLoginItem._login.guid);
let breachAlert = gLoginItem.shadowRoot.querySelector(".breach-alert");
ok(!isHidden(breachAlert), "Breach alert should be visible");
is(breachAlert.querySelector(".breach-alert-link").href, correspondingBreach.breachAlertURL, "Breach alert link should be equal to the correspondingBreach.breachAlertURL.");
is(breachAlert.querySelector(".breach-alert-link").getAttribute("href"), correspondingBreach.breachAlertURL, "Breach alert link should be equal to the correspondingBreach.breachAlertURL.");
});
add_task(async function test_breach_alert_is_correctly_hidden() {
@ -329,7 +308,7 @@ add_task(async function test_different_login_modified() {
gLoginItem.loginModified(otherLogin);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector("input[name='origin']").value, TEST_LOGIN_1.origin, "origin should be unchanged");
is(gLoginItem.shadowRoot.querySelector("a[name='origin']").getAttribute("href"), TEST_LOGIN_1.origin, "origin should be unchanged");
is(gLoginItem.shadowRoot.querySelector("input[name='username']").value, TEST_LOGIN_1.username, "username should be unchanged");
is(gLoginItem._passwordInput.value, TEST_LOGIN_1.password, "password should be unchanged");
ok(!gLoginItem._passwordInput.hasAttribute("value"), "Password shouldn't be exposed in @value");
@ -347,7 +326,7 @@ add_task(async function test_different_login_removed() {
gLoginItem.loginRemoved(otherLogin);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector("input[name='origin']").value, TEST_LOGIN_1.origin, "origin should be unchanged");
is(gLoginItem.shadowRoot.querySelector("a[name='origin']").getAttribute("href"), TEST_LOGIN_1.origin, "origin should be unchanged");
is(gLoginItem.shadowRoot.querySelector("input[name='username']").value, TEST_LOGIN_1.username, "username should be unchanged");
is(gLoginItem._passwordInput.value, TEST_LOGIN_1.password, "password should be unchanged");
ok(!gLoginItem._passwordInput.hasAttribute("value"), "Password shouldn't be exposed in @value");
@ -364,7 +343,7 @@ add_task(async function test_login_modified() {
gLoginItem.loginModified(modifiedLogin);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector("input[name='origin']").value, modifiedLogin.origin, "origin should be updated");
is(gLoginItem.shadowRoot.querySelector("a[name='origin']").getAttribute("href"), modifiedLogin.origin, "origin should be updated");
is(gLoginItem.shadowRoot.querySelector("input[name='username']").value, modifiedLogin.username, "username should be updated");
is(gLoginItem._passwordInput.value, modifiedLogin.password, "password should be updated");
ok(!gLoginItem._passwordInput.hasAttribute("value"), "Password shouldn't be exposed in @value");