зеркало из https://github.com/mozilla/gecko-dev.git
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
This commit is contained in:
Родитель
8a746eed7d
Коммит
e0ac67769b
|
@ -539,6 +539,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"],
|
||||
|
|
|
@ -51,7 +51,7 @@ function LoginAutoCompleteResult(aSearchString, matchingLogins, {isSecure, messa
|
|||
}
|
||||
|
||||
this._showInsecureFieldWarning = (!isSecure && LoginHelper.showInsecureFieldWarning) ? 1 : 0;
|
||||
this._showAutoCompleteFooter = LoginHelper.showAutoCompleteFooter ? 1 : 0;
|
||||
this._showAutoCompleteFooter = (LoginHelper.showAutoCompleteFooter && LoginHelper.enabled) ? 1 : 0;
|
||||
this.searchString = aSearchString;
|
||||
this.logins = matchingLogins.sort(loginSort);
|
||||
this.matchCount = matchingLogins.length + this._showInsecureFieldWarning + this._showAutoCompleteFooter;
|
||||
|
|
|
@ -31,6 +31,7 @@ var LoginHelper = {
|
|||
schemeUpgrades: null,
|
||||
insecureAutofill: null,
|
||||
privateBrowsingCaptureEnabled: null,
|
||||
showAutoCompleteFooter: null,
|
||||
|
||||
init() {
|
||||
// Watch for pref changes to update cached pref values.
|
||||
|
@ -49,8 +50,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) {
|
||||
|
|
|
@ -178,6 +178,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);
|
||||
|
@ -221,6 +224,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({
|
||||
|
@ -233,10 +257,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,
|
||||
|
@ -248,9 +272,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;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -310,6 +350,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,16 @@ 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 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();
|
||||
});
|
||||
|
||||
await promiseShown;
|
||||
ok(promiseShown, "autocomplete shown");
|
||||
await openPopup(popup, browser);
|
||||
|
||||
let footer = popup.querySelector(`[originaltype="loginsFooter"]`);
|
||||
ok(footer, "Got footer richlistitem");
|
||||
|
@ -79,3 +86,41 @@ add_task(async function test_autocomplete_footer() {
|
|||
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");
|
||||
|
||||
await TestUtils.waitForCondition(() => {
|
||||
return !EventUtils.isHidden(footer);
|
||||
}, "Waiting for footer to become visible");
|
||||
|
||||
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");
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче