Bug 1311301 - making login fields show autocomplete on autofocused inputs r?MattN
MozReview-Commit-ID: H4DJvfsgA6v
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -33,16 +33,18 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver",
"resource:///modules/FormSubmitObserver.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata",
"resource://gre/modules/PageMetadata.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AutoCompletePopup",
+ "resource://gre/modules/AutoCompletePopup.jsm");
XPCOMUtils.defineLazyGetter(this, "PageMenuChild", function() {
let tmp = {};
Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
return new tmp.PageMenuChild();
});
XPCOMUtils.defineLazyModuleGetter(this, "Feeds",
"resource:///modules/Feeds.jsm");
@@ -79,16 +81,20 @@ addEventListener("pageshow", function(ev
addEventListener("DOMAutoComplete", function(event) {
LoginManagerContent.onUsernameInput(event);
});
addEventListener("blur", function(event) {
LoginManagerContent.onUsernameInput(event);
});
var handleContentContextMenu = function (event) {
+ if (event.target instanceof Ci.nsIDOMHTMLInputElement) {
+ AutoCompletePopup.closePopup();
+ }
+
let defaultPrevented = event.defaultPrevented;
if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) {
let plugin = null;
try {
plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent);
} catch (e) {}
if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
// Don't open a context menu for plugins.
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1009,17 +1009,17 @@ var LoginManagerContent = {
recordAutofillResult(AUTOFILL_RESULT.NO_LOGINS_FIT);
return;
}
// Attach autocomplete stuff to the username field, if we have
// one. This is normally used to select from multiple accounts,
// but even with one account we should refill if the user edits.
if (usernameField)
- this._formFillService.markAsLoginManagerField(usernameField);
+ this._formFillService.markAsLoginManagerField(usernameField, userTriggered);
// Don't clobber an existing password.
if (passwordField.value && !clobberPassword) {
log("form not filled, the password field was already filled");
recordAutofillResult(AUTOFILL_RESULT.EXISTING_PASSWORD);
return;
}
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -34,16 +34,17 @@
#include "mozilla/ModuleUtils.h"
#include "nsToolkitCompsCID.h"
#include "nsEmbedCID.h"
#include "nsIDOMNSEditableElement.h"
#include "nsContentUtils.h"
#include "nsILoadContext.h"
#include "nsIFrame.h"
#include "nsIScriptSecurityManager.h"
+#include "nsFocusManager.h"
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION(nsFormFillController,
mController, mLoginManager, mFocusedPopup, mDocShells,
mPopups, mLastListener, mLastFormAutoComplete)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormFillController)
@@ -254,30 +255,42 @@ nsFormFillController::DetachFromBrowser(
mDocShells.RemoveElementAt(index);
mPopups.RemoveElementAt(index);
return NS_OK;
}
NS_IMETHODIMP
-nsFormFillController::MarkAsLoginManagerField(nsIDOMHTMLInputElement *aInput)
+nsFormFillController::MarkAsLoginManagerField(nsIDOMHTMLInputElement *aInput, bool aUserTriggered)
{
/*
* The Login Manager can supply autocomplete results for username fields,
* when a user has multiple logins stored for a site. It uses this
* interface to indicate that the form manager shouldn't handle the
* autocomplete. The form manager also checks for this tag when saving
* form history (so it doesn't save usernames).
*/
nsCOMPtr<nsINode> node = do_QueryInterface(aInput);
NS_ENSURE_STATE(node);
mPwmgrInputs.Put(node, true);
node->AddMutationObserverUnlessExists(this);
+ // Check if the element has already been focused prior to form fill being attached
+ if (!aUserTriggered) {
+ nsFocusManager *fm = nsFocusManager::GetFocusManager();
+ if (fm) {
+ nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
+ if (SameCOMIdentity(focusedContent, node)) {
+ nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(node);
+ ShowPopup();
+ }
+ }
+ }
+
if (!mLoginManager)
mLoginManager = do_GetService("@mozilla.org/login-manager;1");
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
--- a/toolkit/components/satchel/nsIFormFillController.idl
+++ b/toolkit/components/satchel/nsIFormFillController.idl
@@ -36,11 +36,12 @@ interface nsIFormFillController : nsISup
void detachFromBrowser(in nsIDocShell docShell);
/*
* Mark the specified <input> element as being managed by password manager.
* Autocomplete requests will be handed off to the password manager, and will
* not be stored in form history.
*
* @param aInput - The HTML <input> element to tag
+ * @param aUserTriggered - a bool if the user tiggered the filling
*/
- void markAsLoginManagerField(in nsIDOMHTMLInputElement aInput);
+ void markAsLoginManagerField(in nsIDOMHTMLInputElement aInput, in bool aUserTriggered);
};