зеркало из https://github.com/mozilla/gecko-dev.git
bug 514212 - Typed letters in password fields become asterisks immediately r=neil
This commit is contained in:
Родитель
b964b108d4
Коммит
53dbbd3e6b
|
@ -63,6 +63,8 @@
|
|||
#include "nsILookAndFeel.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "DeleteTextTxn.h"
|
||||
#include "nsNodeIterator.h"
|
||||
#include "nsIDOMNodeFilter.h"
|
||||
|
||||
// for IBMBIDI
|
||||
#include "nsIPresShell.h"
|
||||
|
@ -659,8 +661,32 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
|
|||
|
||||
if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
|
||||
{
|
||||
res = EchoInsertionToPWBuff(start, end, outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// manage the password buffer
|
||||
mPasswordText.Insert(*outString, start);
|
||||
|
||||
nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID);
|
||||
if (lookAndFeel->GetEchoPassword()) {
|
||||
if (mPasswordText.Length() > outString->Length()) {
|
||||
HideLastPWInput();
|
||||
}
|
||||
mLastStart = start;
|
||||
mLastLength = outString->Length();
|
||||
if (mTimer)
|
||||
{
|
||||
mTimer->Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1", &res);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
mTimer->InitWithCallback(this, 600, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = FillBufWithPWChars(outString, outString->Length());
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
|
||||
// get the (collapsed) selection location
|
||||
|
@ -1367,14 +1393,51 @@ nsTextEditRules::RemoveIMETextFromPWBuf(PRUint32 &aStart, nsAString *aIMEString)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditRules::Notify(class nsITimer *) {
|
||||
return HideLastPWInput();
|
||||
}
|
||||
|
||||
nsresult nsTextEditRules::HideLastPWInput() {
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
PRInt32 selOffset;
|
||||
PRUint32 start, end;
|
||||
nsresult res = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = mEditor->GetTextSelectionOffsets(selection, start, end);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = mEditor->GetStartNodeAndOffset(selection, address_of(selNode), &selOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!mEditor->IsTextNode(selNode)) {
|
||||
// Get an nsINode from the nsIDOMNode
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(selNode);
|
||||
// if node is null, return NS_OK because there's no text to hide
|
||||
if (!node) return NS_OK;
|
||||
// This should be the root node, walk the tree looking for text nodes
|
||||
nsNodeIterator iter(node, nsIDOMNodeFilter::SHOW_TEXT, nsnull, PR_TRUE);
|
||||
while (!mEditor->IsTextNode(selNode)) {
|
||||
if (NS_FAILED(res = iter.NextNode(getter_AddRefs(selNode))) ||
|
||||
selNode == nsnull) {
|
||||
return NS_SUCCEEDED(res) ? NS_ERROR_NULL_POINTER : res;
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMCharacterData> nodeAsText(do_QueryInterface(selNode));
|
||||
if (!nodeAsText) return NS_ERROR_FAILURE;
|
||||
nsAutoString hiddenText;
|
||||
FillBufWithPWChars(&hiddenText, mLastLength);
|
||||
nodeAsText->ReplaceData(mLastStart, mLastLength, hiddenText);
|
||||
selection->Collapse(selNode, start);
|
||||
if (start != end)
|
||||
selection->Extend(selNode, end);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::EchoInsertionToPWBuff(PRInt32 aStart, PRInt32 aEnd, nsAString *aOutString)
|
||||
nsTextEditRules::FillBufWithPWChars(nsAString *aOutString, PRInt32 aLength)
|
||||
{
|
||||
if (!aOutString) {return NS_ERROR_NULL_POINTER;}
|
||||
|
||||
// manage the password buffer
|
||||
mPasswordText.Insert(*aOutString, aStart);
|
||||
|
||||
// change the output to the platform password character
|
||||
PRUnichar passwordChar = PRUnichar('*');
|
||||
nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID);
|
||||
|
@ -1383,13 +1446,10 @@ nsTextEditRules::EchoInsertionToPWBuff(PRInt32 aStart, PRInt32 aEnd, nsAString *
|
|||
passwordChar = lookAndFeel->GetPasswordCharacter();
|
||||
}
|
||||
|
||||
PRInt32 length = aOutString->Length();
|
||||
PRInt32 i;
|
||||
aOutString->Truncate();
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
for (i=0; i < aLength; i++)
|
||||
aOutString->Append(passwordChar);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsIDOMNode.h"
|
||||
|
||||
#include "nsEditRules.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
/** Object that encapsulates HTML text-specific editing rules.
|
||||
*
|
||||
|
@ -56,11 +57,12 @@
|
|||
* 2. Selection must not be explicitly set by the rule method.
|
||||
* Any manipulation of Selection must be done by the editor.
|
||||
*/
|
||||
class nsTextEditRules : public nsIEditRules
|
||||
class nsTextEditRules : public nsIEditRules, public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsTextEditRules)
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTextEditRules, nsIEditRules)
|
||||
|
||||
nsTextEditRules();
|
||||
virtual ~nsTextEditRules();
|
||||
|
@ -186,7 +188,7 @@ protected:
|
|||
|
||||
/** Echo's the insertion text into the password buffer, and converts
|
||||
insertion text to '*'s */
|
||||
nsresult EchoInsertionToPWBuff(PRInt32 aStart, PRInt32 aEnd, nsAString *aOutString);
|
||||
nsresult FillBufWithPWChars(nsAString *aOutString, PRInt32 aLength);
|
||||
|
||||
/** Remove IME composition text from password buffer */
|
||||
nsresult RemoveIMETextFromPWBuf(PRUint32 &aStart, nsAString *aIMEString);
|
||||
|
@ -199,6 +201,8 @@ protected:
|
|||
nsIEditor::EDirection aAction,
|
||||
PRBool *aCancel);
|
||||
|
||||
nsresult HideLastPWInput();
|
||||
|
||||
// data members
|
||||
nsPlaintextEditor *mEditor; // note that we do not refcount the editor
|
||||
nsString mPasswordText; // a buffer we use to store the real value of password editors
|
||||
|
@ -216,6 +220,9 @@ protected:
|
|||
// adjacent to the caret without
|
||||
// moving the caret first.
|
||||
PRInt32 mTheAction; // the top level editor action
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
PRUint32 mLastStart, mLastLength;
|
||||
|
||||
// friends
|
||||
friend class nsAutoLockRulesSniffing;
|
||||
|
||||
|
|
|
@ -371,6 +371,15 @@ public:
|
|||
return PRUnichar('*');
|
||||
}
|
||||
|
||||
virtual PRBool GetEchoPassword()
|
||||
{
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
return PR_TRUE;
|
||||
#else
|
||||
return PR_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHOD LookAndFeelChanged() = 0;
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче