Bug 376668 - making login fields show autocomplete on focus r?MattN
MozReview-Commit-ID: Avzp5FaAgHQ
--- a/toolkit/components/passwordmgr/test/browser/browser_context_menu.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_context_menu.js
@@ -42,16 +42,38 @@ add_task(function* test_context_menu_pop
checkMenu(popupMenu, 2);
let contextMenu = document.getElementById("contentAreaContextMenu");
contextMenu.hidePopup();
});
});
/**
+ * Check if clicking the edge doesn't show both autocomplete and context menu
+ */
+add_task(function* test_context_menu_doesnt_overlap_with_autocomplete() {
+ Services.prefs.setBoolPref("signon.schemeUpgrades", false);
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH,
+ }, function* (browser) {
+ let passwordInput = browser.contentWindow.document.getElementById("test-password-1");
+
+ // Synthesize a right mouse click over the password input element.
+ let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown");
+ let eventDetails = {type: "contextmenu", button: 2};
+ BrowserTestUtils.synthesizeMouseAtCenter(passwordInput, eventDetails, browser);
+ yield contextMenuShownPromise;
+
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ contextMenu.hidePopup();
+ });
+});
+
+/**
* Check if the context menu is populated with the right
* menuitems for the target password input field.
*/
add_task(function* test_context_menu_populate_password_schemeUpgrades() {
Services.prefs.setBoolPref("signon.schemeUpgrades", true);
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH,
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
@@ -797,12 +797,36 @@ add_task(function* test_form12_formless(
// Trigger autocomplete
doKey("down");
checkACForm("", ""); // value shouldn't update
let processedPromise = promiseFormsProcessed();
doKey("return"); // not "enter"!
yield processedPromise;
checkACForm("testuser", "testpass");
});
+
+add_task(function* test_form12_open_on_trusted_focus() {
+ uname = $_(12, "uname");
+ pword = $_(12, "pword");
+ uname.value = "";
+ pword.value = "";
+
+ checkACForm("", "");
+ const firePrivEventPromise = new Promise((resolve) => {
+ uname.addEventListener("click", (e) => {
+ ok(e.isTrusted, "Ensure event is trusted");
+ resolve();
+ });
+ });
+ const shownPromise = promiseACShown();
+ synthesizeMouseAtCenter(uname, {});
+ yield firePrivEventPromise;
+ yield shownPromise;
+ doKey("down");
+ const processedPromise = promiseFormsProcessed();
+ doKey("return"); // not "enter"!
+ yield processedPromise;
+ checkACForm("testuser", "testpass");
+});
</script>
</pre>
</body>
</html>
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -849,16 +849,18 @@ nsFormFillController::HandleEvent(nsIDOM
}
if (type.EqualsLiteral("compositionend")) {
NS_ASSERTION(mController, "should have a controller!");
if (mController && mFocusedInput)
mController->HandleEndComposition();
return NS_OK;
}
if (type.EqualsLiteral("contextmenu")) {
+ if (mFocusedInput)
+ StopControllingInput();
if (mFocusedPopup)
mFocusedPopup->ClosePopup();
return NS_OK;
}
if (type.EqualsLiteral("pagehide")) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(
aEvent->InternalDOMEvent()->GetTarget());
@@ -924,16 +926,22 @@ nsFormFillController::MaybeStartControll
}
nsresult
nsFormFillController::Focus(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(
aEvent->InternalDOMEvent()->GetTarget());
MaybeStartControllingInput(input);
+
+ // if we have a password manager field auto show the popup
+ if (mPwmgrInputs.Get(mFocusedInputNode)) {
+ ShowPopup();
+ }
+
return NS_OK;
}
nsresult
nsFormFillController::KeyPress(nsIDOMEvent* aEvent)
{
NS_ASSERTION(mController, "should have a controller!");
if (!mFocusedInput || !mController)
@@ -1056,16 +1064,21 @@ nsFormFillController::MouseDown(nsIDOMEv
if (!targetInput)
return NS_OK;
int16_t button;
mouseEvent->GetButton(&button);
if (button != 0)
return NS_OK;
+ return ShowPopup();
+}
+
+nsresult
+nsFormFillController::ShowPopup() {
bool isOpen = false;
GetPopupOpen(&isOpen);
if (isOpen) {
return SetPopupOpen(false);
}
nsCOMPtr<nsIAutoCompleteInput> input;
mController->GetInput(getter_AddRefs(input));
--- a/toolkit/components/satchel/nsFormFillController.h
+++ b/toolkit/components/satchel/nsFormFillController.h
@@ -72,16 +72,17 @@ protected:
*/
void MaybeStartControllingInput(nsIDOMHTMLInputElement* aElement);
nsresult PerformInputListAutoComplete(const nsAString& aSearch,
nsIAutoCompleteResult** aResult);
void RevalidateDataList();
bool RowMatch(nsFormHistory *aHistory, uint32_t aIndex, const nsAString &aInputName, const nsAString &aInputValue);
+ nsresult ShowPopup();
inline nsIDocShell *GetDocShellForInput(nsIDOMHTMLInputElement *aInput);
inline nsPIDOMWindowOuter *GetWindowForDocShell(nsIDocShell *aDocShell);
inline int32_t GetIndexOfDocShell(nsIDocShell *aDocShell);
void MaybeRemoveMutationObserver(nsINode* aNode);
void RemoveForDocument(nsIDocument* aDoc);