Commit 6e3743ce authored by prathiksha's avatar prathiksha
Browse files

Bug 1530029 - Pressing enter on the autocomplete footer should open the...

Bug 1530029 - Pressing enter on the autocomplete footer should open the password manager dialog. r=MattN

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

--HG--
extra : moz-landing-system : lando
parent 069c5d48
......@@ -536,6 +536,7 @@ const listeners = {
"PasswordManager:autoCompleteLogins": ["LoginManagerParent"],
"PasswordManager:removeLogin": ["LoginManagerParent"],
"PasswordManager:insecureLoginFormPresent": ["LoginManagerParent"],
"PasswordManager:OpenPreferences": ["LoginManagerParent"],
// PLEASE KEEP THIS LIST IN SYNC WITH THE MOBILE LISTENERS IN BrowserCLH.js
"rtcpeer:CancelRequest": ["webrtcUI"],
"rtcpeer:Request": ["webrtcUI"],
......
......@@ -31,6 +31,7 @@ var LoginHelper = {
schemeUpgrades: null,
insecureAutofill: null,
privateBrowsingCaptureEnabled: null,
showAutoCompleteFooter: null,
init() {
// Watch for pref changes to update cached pref values.
......@@ -48,8 +49,8 @@ var LoginHelper = {
Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled");
this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
this.storeWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
this.showAutoCompleteFooter = Services.prefs.getBoolPref("signon.showAutoCompleteFooter");
this.storeWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
},
createLogger(aLogPrefix) {
......
......@@ -191,6 +191,9 @@ var LoginManagerContent = {
// Number of outstanding requests to each manager.
_managers: new Map(),
// Input element on which enter keydown event was fired.
_keyDownEnterForInput: null,
_takeRequest(msg) {
let data = msg.data;
let request = this._requests.get(data.requestId);
......@@ -235,6 +238,27 @@ var LoginManagerContent = {
return deferred.promise;
},
_onKeyDown(event) {
let focusedElement = LoginManagerContent._formFillService.focusedInput;
if (event.keyCode != event.DOM_VK_RETURN || focusedElement != event.target) {
this._keyDownEnterForInput = null;
return;
}
LoginManagerContent._keyDownEnterForInput = focusedElement;
},
_onPopupClosed(selectedRowStyle, mm) {
let focusedElement = LoginManagerContent._formFillService.focusedInput;
let eventTarget = LoginManagerContent._keyDownEnterForInput;
if (!eventTarget || eventTarget !== focusedElement ||
selectedRowStyle != "loginsFooter") {
this._keyDownEnterForInput = null;
return;
}
let hostname = eventTarget.ownerDocument.documentURIObject.host;
mm.sendAsyncMessage("PasswordManager:OpenPreferences", {hostname});
},
receiveMessage(msg, topWindow) {
if (msg.name == "PasswordManager:fillForm") {
this.fillForm({
......@@ -247,10 +271,10 @@ var LoginManagerContent = {
return;
}
let request = this._takeRequest(msg);
switch (msg.name) {
case "PasswordManager:loginsFound": {
let loginsFound = LoginHelper.vanillaObjectsToLogins(msg.data.logins);
let request = this._takeRequest(msg);
request.promise.resolve({
form: request.form,
loginsFound,
......@@ -262,9 +286,25 @@ var LoginManagerContent = {
case "PasswordManager:loginsAutoCompleted": {
let loginsFound = LoginHelper.vanillaObjectsToLogins(msg.data.logins);
let messageManager = msg.target;
let request = this._takeRequest(msg);
request.promise.resolve({ logins: loginsFound, messageManager });
break;
}
case "FormAutoComplete:PopupOpened": {
let {chromeEventHandler} = msg.target.docShell;
chromeEventHandler.addEventListener("keydown", this._onKeyDown,
true);
break;
}
case "FormAutoComplete:PopupClosed": {
this._onPopupClosed(msg.data.selectedRowStyle, msg.target);
let {chromeEventHandler} = msg.target.docShell;
chromeEventHandler.removeEventListener("keydown", this._onKeyDown,
true);
break;
}
}
},
......@@ -324,6 +364,11 @@ var LoginManagerContent = {
isPasswordField: aElement.type == "password",
};
if (LoginHelper.showAutoCompleteFooter) {
messageManager.addMessageListener("FormAutoComplete:PopupOpened", this);
messageManager.addMessageListener("FormAutoComplete:PopupClosed", this);
}
return this._sendRequest(messageManager, requestData,
"PasswordManager:autoCompleteLogins",
messageData);
......
......@@ -115,6 +115,11 @@ var LoginManagerParent = {
AutoCompletePopup.removeLogin(login);
break;
}
case "PasswordManager:OpenPreferences": {
LoginHelper.openPasswordManager(msg.target.ownerGlobal, msg.data.hostname);
break;
}
}
return undefined;
......
......@@ -21,6 +21,24 @@ function loginList() {
];
}
function openPopup(popup, browser) {
return new Promise(async (resolve) => {
let promiseShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
await SimpleTest.promiseFocus(browser);
info("content window focused");
// Focus the username field to open the popup.
await ContentTask.spawn(browser, null, function openAutocomplete() {
content.document.getElementById("form-basic-username").focus();
});
let shown = await promiseShown;
ok(shown, "autocomplete popup shown");
resolve(shown);
});
}
/**
* Initialize logins and set prefs needed for the test.
*/
......@@ -35,27 +53,50 @@ add_task(async function test_initialize() {
}
});
add_task(async function test_autocomplete_footer() {
add_task(async function test_autocomplete_footer_onclick() {
let url = TEST_HOSTNAME + BASIC_FORM_PAGE_PATH;
await BrowserTestUtils.withNewTab({
gBrowser,
url,
}, async function(browser) {
}, async function footer_onclick(browser) {
let popup = document.getElementById("PopupAutoComplete");
ok(popup, "Got popup");
let promiseShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
await openPopup(popup, browser);
await SimpleTest.promiseFocus(browser);
info("content window focused");
let footer = popup.querySelector(`[originaltype="loginsFooter"]`);
ok(footer, "Got footer richlistitem");
// Focus the username field to open the popup.
await ContentTask.spawn(browser, null, function openAutocomplete() {
content.document.getElementById("form-basic-username").focus();
});
await TestUtils.waitForCondition(() => {
return !EventUtils.isHidden(footer);
}, "Waiting for footer to become visible");
await promiseShown;
ok(promiseShown, "autocomplete shown");
EventUtils.synthesizeMouseAtCenter(footer, {});
await TestUtils.waitForCondition(() => {
return Services.wm.getMostRecentWindow("Toolkit:PasswordManager") !== null;
}, "Waiting for the password manager dialog to open");
info("Login dialog was opened");
let window = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
await TestUtils.waitForCondition(() => {
return window.document.getElementById("filter").value == "example.com";
}, "Waiting for the search string to filter logins");
window.close();
popup.hidePopup();
});
});
add_task(async function test_autocomplete_footer_keydown() {
let url = TEST_HOSTNAME + BASIC_FORM_PAGE_PATH;
await BrowserTestUtils.withNewTab({
gBrowser,
url,
}, async function footer_enter_keydown(browser) {
let popup = document.getElementById("PopupAutoComplete");
ok(popup, "Got popup");
await openPopup(popup, browser);
let footer = popup.querySelector(`[originaltype="loginsFooter"]`);
ok(footer, "Got footer richlistitem");
......@@ -64,7 +105,11 @@ add_task(async function test_autocomplete_footer() {
return !EventUtils.isHidden(footer);
}, "Waiting for footer to become visible");
EventUtils.synthesizeMouseAtCenter(footer, {});
await EventUtils.synthesizeKey("KEY_ArrowDown");
await EventUtils.synthesizeKey("KEY_ArrowDown");
await EventUtils.synthesizeKey("KEY_ArrowDown");
await EventUtils.synthesizeKey("KEY_Enter");
await TestUtils.waitForCondition(() => {
return Services.wm.getMostRecentWindow("Toolkit:PasswordManager") !== null;
}, "Waiting for the password manager dialog to open");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment