summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2012-02-28 11:25:40 -0800
committerGeorge Mount <mount@google.com>2012-02-28 13:24:07 -0800
commit5fe5f9958e40c39747144b3b454077d73415a112 (patch)
treef3eaa37da09bb683b9a9aed2edda098448d45eb4
parent5015ffe477809860e6a9e05779afb1855aa994f2 (diff)
downloadexternal_webkit-5fe5f9958e40c39747144b3b454077d73415a112.zip
external_webkit-5fe5f9958e40c39747144b3b454077d73415a112.tar.gz
external_webkit-5fe5f9958e40c39747144b3b454077d73415a112.tar.bz2
Merge webkit change to reveal last character in password.
Bug 6083915 cherry pick of webkit 93656 http://trac.webkit.org/changeset/93656 Change-Id: I1f979a3b2b9916736f3785ab2d5998b958b55cd2
-rw-r--r--Source/WebCore/editing/InsertIntoTextNodeCommand.cpp10
-rw-r--r--Source/WebCore/page/Settings.cpp6
-rw-r--r--Source/WebCore/page/Settings.h9
-rw-r--r--Source/WebCore/rendering/RenderText.cpp76
-rw-r--r--Source/WebCore/rendering/RenderText.h4
-rw-r--r--Source/WebKit/android/jni/WebSettings.cpp2
6 files changed, 103 insertions, 4 deletions
diff --git a/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp b/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
index b1a455b..bd6fb60 100644
--- a/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
+++ b/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
@@ -28,6 +28,8 @@
#include "AXObjectCache.h"
#include "Text.h"
+#include "RenderText.h"
+#include "Settings.h"
namespace WebCore {
@@ -46,7 +48,13 @@ void InsertIntoTextNodeCommand::doApply()
{
if (!m_node->rendererIsEditable())
return;
-
+
+ if (document()->settings() && document()->settings()->passwordEchoEnabled()) {
+ RenderText* renderText = toRenderText(m_node->renderer());
+ if (renderText && renderText->isSecure())
+ renderText->momentarilyRevealLastTypedCharacter(m_offset + m_text.length() - 1);
+ }
+
ExceptionCode ec;
m_node->insertData(m_offset, m_text, ec);
diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp
index e2312a9..c26a0fc 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -98,6 +98,7 @@ Settings::Settings(Page* page)
#ifdef ANDROID_LAYOUT
, m_layoutAlgorithm(kLayoutFitColumnToScreen)
#endif
+ , m_passwordEchoDurationInSeconds(1)
, m_isSpatialNavigationEnabled(false)
, m_isJavaEnabled(false)
, m_loadsImagesAutomatically(false)
@@ -192,6 +193,11 @@ Settings::Settings(Page* page)
#ifdef ANDROID_PLUGINS
, m_pluginsOnDemand(false)
#endif
+#if OS(SYMBIAN)
+ , m_passwordEchoEnabled(true)
+#else
+ , m_passwordEchoEnabled(false)
+#endif
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h
index 31a5ad9..2bb222d 100644
--- a/Source/WebCore/page/Settings.h
+++ b/Source/WebCore/page/Settings.h
@@ -458,6 +458,12 @@ namespace WebCore {
void setShouldInjectUserScriptsInInitialEmptyDocument(bool flag) { m_shouldInjectUserScriptsInInitialEmptyDocument = flag; }
bool shouldInjectUserScriptsInInitialEmptyDocument() { return m_shouldInjectUserScriptsInInitialEmptyDocument; }
+ void setPasswordEchoEnabled(bool flag) { m_passwordEchoEnabled = flag; }
+ bool passwordEchoEnabled() const { return m_passwordEchoEnabled; }
+
+ void setPasswordEchoDurationInSeconds(double durationInSeconds) { m_passwordEchoDurationInSeconds = durationInSeconds; }
+ double passwordEchoDurationInSeconds() const { return m_passwordEchoDurationInSeconds; }
+
#if ENABLE(WEB_AUTOFILL)
void setAutoFillEnabled(bool flag) { m_autoFillEnabled = flag; }
bool autoFillEnabled() { return m_autoFillEnabled; }
@@ -511,6 +517,8 @@ namespace WebCore {
#ifdef ANDROID_LAYOUT
LayoutAlgorithm m_layoutAlgorithm;
#endif
+ double m_passwordEchoDurationInSeconds;
+
bool m_isSpatialNavigationEnabled : 1;
bool m_isJavaEnabled : 1;
bool m_loadsImagesAutomatically : 1;
@@ -617,6 +625,7 @@ namespace WebCore {
#ifdef ANDROID_PLUGINS
bool m_pluginsOnDemand : 1;
#endif
+ bool m_passwordEchoEnabled : 1;
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index b35820a..6f4d3b7 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -37,6 +37,7 @@
#include "RenderCombineText.h"
#include "RenderLayer.h"
#include "RenderView.h"
+#include "Settings.h"
#include "Text.h"
#include "TextBreakIterator.h"
#include "TextResourceDecoder.h"
@@ -53,6 +54,37 @@ using namespace Unicode;
namespace WebCore {
+class SecureTextTimer;
+typedef HashMap<RenderText*, SecureTextTimer*> SecureTextTimerMap;
+static SecureTextTimerMap* gSecureTextTimers = 0;
+
+class SecureTextTimer : public TimerBase {
+public:
+ SecureTextTimer(RenderText* renderText)
+ : m_renderText(renderText)
+ , m_lastTypedCharacterOffset(-1)
+ {
+ }
+
+ void restartWithNewText(unsigned lastTypedCharacterOffset)
+ {
+ m_lastTypedCharacterOffset = lastTypedCharacterOffset;
+ startOneShot(m_renderText->document()->settings()->passwordEchoDurationInSeconds());
+ }
+ void invalidate() { m_lastTypedCharacterOffset = -1; }
+ unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; }
+
+private:
+ virtual void fired()
+ {
+ ASSERT(gSecureTextTimers->contains(m_renderText));
+ m_renderText->setText(m_renderText->text(), true /* forcing setting text as it may be masked later */);
+ }
+
+ RenderText* m_renderText;
+ int m_lastTypedCharacterOffset;
+};
+
static void makeCapitalized(String* string, UChar previous)
{
if (string->isNull())
@@ -196,6 +228,9 @@ void RenderText::removeAndDestroyTextBoxes()
void RenderText::destroy()
{
+ if (SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->take(this) : 0)
+ delete secureTextTimer;
+
removeAndDestroyTextBoxes();
RenderObject::destroy();
}
@@ -1140,13 +1175,13 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
case TSNONE:
break;
case TSCIRCLE:
- m_text.makeSecure(whiteBullet);
+ secureText(whiteBullet);
break;
case TSDISC:
- m_text.makeSecure(bullet);
+ secureText(bullet);
break;
case TSSQUARE:
- m_text.makeSecure(blackSquare);
+ secureText(blackSquare);
}
}
@@ -1156,6 +1191,28 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
m_isAllASCII = m_text.containsOnlyASCII();
}
+void RenderText::secureText(UChar mask)
+{
+ if (!m_text.length())
+ return;
+
+ int lastTypedCharacterOffsetToReveal = -1;
+ String revealedText;
+ SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->get(this) : 0;
+ if (secureTextTimer && secureTextTimer->isActive()) {
+ lastTypedCharacterOffsetToReveal = secureTextTimer->lastTypedCharacterOffset();
+ if (lastTypedCharacterOffsetToReveal >= 0)
+ revealedText.append(m_text[lastTypedCharacterOffsetToReveal]);
+ }
+
+ m_text.makeSecure(mask);
+ if (lastTypedCharacterOffsetToReveal >= 0) {
+ m_text.replace(lastTypedCharacterOffsetToReveal, 1, revealedText);
+ // m_text may be updated later before timer fires. We invalidate the lastTypedCharacterOffset to avoid inconsistency.
+ secureTextTimer->invalidate();
+ }
+}
+
void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
{
ASSERT(text);
@@ -1590,4 +1647,17 @@ void RenderText::checkConsistency() const
#endif
+void RenderText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset)
+{
+ if (!gSecureTextTimers)
+ gSecureTextTimers = new SecureTextTimerMap;
+
+ SecureTextTimer* secureTextTimer = gSecureTextTimers->get(this);
+ if (!secureTextTimer) {
+ secureTextTimer = new SecureTextTimer(this);
+ gSecureTextTimers->add(this, secureTextTimer);
+ }
+ secureTextTimer->restartWithNewText(lastTypedCharacterOffset);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderText.h b/Source/WebCore/rendering/RenderText.h
index 2008dad..f89a762 100644
--- a/Source/WebCore/rendering/RenderText.h
+++ b/Source/WebCore/rendering/RenderText.h
@@ -117,6 +117,9 @@ public:
bool containsReversedText() const { return m_containsReversedText; }
+ bool isSecure() const { return style()->textSecurity() != TSNONE; }
+ void momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset);
+
InlineTextBox* findNextInlineTextBox(int offset, int& pos) const;
bool allowTabs() const { return !style()->collapseWhiteSpace(); }
@@ -158,6 +161,7 @@ private:
void updateNeedsTranscoding();
inline void transformText(String&) const;
+ void secureText(UChar mask);
float m_minWidth; // here to minimize padding in 64-bit.
diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp
index 1a1cc33..59ade52 100644
--- a/Source/WebKit/android/jni/WebSettings.cpp
+++ b/Source/WebKit/android/jni/WebSettings.cpp
@@ -584,6 +584,8 @@ public:
// has no style attached to it. http://trac.webkit.org/changeset/79799
s->setDeveloperExtrasEnabled(true);
s->setSpatialNavigationEnabled(true);
+
+ s->setPasswordEchoEnabled(true);
}
};