зеркало из https://github.com/mozilla/gecko-dev.git
- Add DOMAutoComplete event, fired on a form input element when the user
selects a completion from the popup. - Listen for DOMAutoComplete and Blur events instead of Change events to trigger prefilling the password field. - Fix an off-by-one error in the multi-user password change confirmation (the stored password was being changed for the wrong entry). - Fix skipping multiple logins when reading the signon file. - Add missing license for Makefile.in.
This commit is contained in:
Родитель
58876decc1
Коммит
96c99c1a4a
|
@ -179,7 +179,7 @@ NS_INTERFACE_MAP_BEGIN(nsPasswordManager)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFormSubmitObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFormListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFocusListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPasswordManager)
|
||||
|
@ -586,7 +586,8 @@ nsPasswordManager::OnStateChange(nsIWebProgress* aWebProgress,
|
|||
|
||||
// We can auto-prefill the username and password if there is only
|
||||
// one stored login that matches the username and password field names
|
||||
// on the form in question.
|
||||
// on the form in question. Note that we only need to worry about a
|
||||
// single login per form.
|
||||
|
||||
for (PRUint32 i = 0; i < formCount; ++i) {
|
||||
nsCOMPtr<nsIDOMNode> formNode;
|
||||
|
@ -613,12 +614,13 @@ nsPasswordManager::OnStateChange(nsIWebProgress* aWebProgress,
|
|||
|
||||
if (firstMatch) {
|
||||
// We've found more than one possible signon for this form.
|
||||
// Attach an onchange handler to the username field so that we can
|
||||
// attempt to prefill the password after the user has
|
||||
// Listen for blur and autocomplete events on the username field so
|
||||
// that we can attempt to prefill the password after the user has
|
||||
// entered the username.
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(userField);
|
||||
targ->AddEventListener(NS_LITERAL_STRING("change"), this, PR_FALSE);
|
||||
targ->AddEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE);
|
||||
targ->AddEventListener(NS_LITERAL_STRING("DOMAutoComplete"), this, PR_FALSE);
|
||||
firstMatch = nsnull;
|
||||
break; // on to the next form
|
||||
} else {
|
||||
|
@ -634,6 +636,10 @@ nsPasswordManager::OnStateChange(nsIWebProgress* aWebProgress,
|
|||
|
||||
DecryptData(firstMatch->passValue, buffer);
|
||||
passField->SetValue(buffer);
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(userField);
|
||||
targ->AddEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE);
|
||||
targ->AddEventListener(NS_LITERAL_STRING("DOMAutoComplete"), this, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,7 +903,7 @@ nsPasswordManager::Notify(nsIContent* aFormNode,
|
|||
|
||||
if (confirm && selection >= 0) {
|
||||
changeEntry = entry;
|
||||
for (PRInt32 m = 1; m < selection; ++m)
|
||||
for (PRInt32 m = 0; m < selection; ++m)
|
||||
changeEntry = changeEntry->next;
|
||||
}
|
||||
|
||||
|
@ -942,98 +948,26 @@ nsPasswordManager::Notify(nsIContent* aFormNode,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIDOMFormListener implementation
|
||||
// nsIDOMFocusListener implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPasswordManager::Submit(nsIDOMEvent* aEvent)
|
||||
{
|
||||
// Note, form submission is not handled here (to do so would mean
|
||||
// hooking up an event listener to each form as it's created).
|
||||
// See ::Notify().
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPasswordManager::Reset(nsIDOMEvent* aEvent)
|
||||
nsPasswordManager::Focus(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPasswordManager::Change(nsIDOMEvent* aEvent)
|
||||
nsPasswordManager::Blur(nsIDOMEvent* aEvent)
|
||||
{
|
||||
// Try to prefill the password for the just-changed username.
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
aEvent->GetTarget(getter_AddRefs(target));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> userField = do_QueryInterface(target);
|
||||
if (!userField)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> fieldContent = do_QueryInterface(userField);
|
||||
nsIDocument* doc = fieldContent->GetDocument();
|
||||
|
||||
nsCOMPtr<nsIURI> documentURL;
|
||||
doc->GetDocumentURL(getter_AddRefs(documentURL));
|
||||
|
||||
nsCAutoString realm;
|
||||
documentURL->GetPrePath(realm);
|
||||
|
||||
nsAutoString userValue;
|
||||
userField->GetValue(userValue);
|
||||
|
||||
nsAutoString fieldName;
|
||||
userField->GetName(fieldName);
|
||||
|
||||
SignonHashEntry* hashEnt;
|
||||
if (!mSignonTable.Get(realm, &hashEnt))
|
||||
return NS_OK;
|
||||
|
||||
SignonDataEntry* foundEntry;
|
||||
FindPasswordEntryInternal(hashEnt->head, userValue, nsString(),
|
||||
fieldName, &foundEntry);
|
||||
|
||||
if (!foundEntry)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formEl;
|
||||
userField->GetForm(getter_AddRefs(formEl));
|
||||
if (!formEl)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIForm> form = do_QueryInterface(formEl);
|
||||
nsCOMPtr<nsISupports> foundNode;
|
||||
form->ResolveName(foundEntry->passField, getter_AddRefs(foundNode));
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> passField = do_QueryInterface(foundNode);
|
||||
if (!passField)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString passValue;
|
||||
DecryptData(foundEntry->passValue, passValue);
|
||||
passField->SetValue(passValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPasswordManager::Select(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPasswordManager::Input(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
return FillPassword(aEvent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPasswordManager::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
return FillPassword(aEvent);
|
||||
}
|
||||
|
||||
|
||||
// internal methods
|
||||
|
||||
/*
|
||||
|
@ -1109,13 +1043,15 @@ nsPasswordManager::ReadSignonFile()
|
|||
break;
|
||||
|
||||
case STATE_USERFIELD:
|
||||
|
||||
// Commit any completed entry
|
||||
if (entry)
|
||||
AddSignonData(realm, entry);
|
||||
|
||||
// If the line is a ., we've reached the end of this realm's entries.
|
||||
if (buffer.Equals(NS_LITERAL_STRING("."))) {
|
||||
if (entry) {
|
||||
AddSignonData(realm, entry);
|
||||
entry = nsnull;
|
||||
state = STATE_REALM;
|
||||
}
|
||||
entry = nsnull;
|
||||
state = STATE_REALM;
|
||||
} else {
|
||||
entry = new SignonDataEntry();
|
||||
entry->userField.Assign(buffer);
|
||||
|
@ -1375,6 +1311,65 @@ nsPasswordManager::FindPasswordEntryInternal(const SignonDataEntry* aEntry,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPasswordManager::FillPassword(nsIDOMEvent* aEvent)
|
||||
{
|
||||
// Try to prefill the password for the just-changed username.
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
aEvent->GetTarget(getter_AddRefs(target));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> userField = do_QueryInterface(target);
|
||||
if (!userField)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> fieldContent = do_QueryInterface(userField);
|
||||
nsIDocument* doc = fieldContent->GetDocument();
|
||||
|
||||
nsCOMPtr<nsIURI> documentURL;
|
||||
doc->GetDocumentURL(getter_AddRefs(documentURL));
|
||||
|
||||
nsCAutoString realm;
|
||||
documentURL->GetPrePath(realm);
|
||||
|
||||
nsAutoString userValue;
|
||||
userField->GetValue(userValue);
|
||||
|
||||
if (userValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString fieldName;
|
||||
userField->GetName(fieldName);
|
||||
|
||||
SignonHashEntry* hashEnt;
|
||||
if (!mSignonTable.Get(realm, &hashEnt))
|
||||
return NS_OK;
|
||||
|
||||
SignonDataEntry* foundEntry;
|
||||
FindPasswordEntryInternal(hashEnt->head, userValue, nsString(),
|
||||
fieldName, &foundEntry);
|
||||
|
||||
if (!foundEntry)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formEl;
|
||||
userField->GetForm(getter_AddRefs(formEl));
|
||||
if (!formEl)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIForm> form = do_QueryInterface(formEl);
|
||||
nsCOMPtr<nsISupports> foundNode;
|
||||
form->ResolveName(foundEntry->passField, getter_AddRefs(foundNode));
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> passField = do_QueryInterface(foundNode);
|
||||
if (!passField)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString passValue;
|
||||
DecryptData(foundEntry->passValue, passValue);
|
||||
passField->SetValue(passValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// nsSingleSignonPrompt
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "nsIPrompt.h"
|
||||
#include "nsIFormSubmitObserver.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
|
||||
/* 360565c4-2ef3-4f6a-bab9-94cca891b2a7 */
|
||||
#define NS_PASSWORDMANAGER_CID \
|
||||
|
@ -71,7 +71,7 @@ class nsPasswordManager : public nsIPasswordManager,
|
|||
public nsIObserver,
|
||||
public nsIFormSubmitObserver,
|
||||
public nsIWebProgressListener,
|
||||
public nsIDOMFormListener,
|
||||
public nsIDOMFocusListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
|
@ -118,12 +118,9 @@ public:
|
|||
nsIURI* aActionURL,
|
||||
PRBool* aCancelSubmit);
|
||||
|
||||
// nsIDOMFormListener
|
||||
NS_IMETHOD Submit(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Reset(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Change(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Select(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Input(nsIDOMEvent* aEvent);
|
||||
// nsIDOMFocusListener
|
||||
NS_IMETHOD Focus(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Blur(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
@ -141,6 +138,8 @@ protected:
|
|||
SignonDataEntry** aResult);
|
||||
|
||||
|
||||
nsresult FillPassword(nsIDOMEvent* aEvent);
|
||||
|
||||
static PLDHashOperator PR_CALLBACK FindEntryEnumerator(const nsACString& aKey,
|
||||
SignonHashEntry* aEntry,
|
||||
void* aUserData);
|
||||
|
|
|
@ -1,3 +1,40 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Mozilla Browser code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2003
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Brian Ryner <bryner@brianryner.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsFormFillController)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFormFillController)
|
||||
|
@ -419,6 +420,25 @@ nsFormFillController::OnSearchComplete()
|
|||
NS_IMETHODIMP
|
||||
nsFormFillController::OnTextEntered(PRBool *_retval)
|
||||
{
|
||||
// Fire off a DOMAutoComplete event
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mFocusedInput->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
|
||||
nsCOMPtr<nsIDOMDocumentEvent> doc = do_QueryInterface(domDoc);
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
doc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
|
||||
if (!event) {
|
||||
NS_ERROR("Could not create DOM Event");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
event->InitEvent(NS_LITERAL_STRING("DOMAutoComplete"), PR_TRUE, PR_TRUE);
|
||||
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(mFocusedInput);
|
||||
|
||||
PRBool noDefault;
|
||||
targ->DispatchEvent(event, &noDefault);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче