diff options
author | George Mount <mount@google.com> | 2012-02-28 11:25:40 -0800 |
---|---|---|
committer | George Mount <mount@google.com> | 2012-02-28 13:24:07 -0800 |
commit | 5fe5f9958e40c39747144b3b454077d73415a112 (patch) | |
tree | f3eaa37da09bb683b9a9aed2edda098448d45eb4 | |
parent | 5015ffe477809860e6a9e05779afb1855aa994f2 (diff) | |
download | external_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.cpp | 10 | ||||
-rw-r--r-- | Source/WebCore/page/Settings.cpp | 6 | ||||
-rw-r--r-- | Source/WebCore/page/Settings.h | 9 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderText.cpp | 76 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderText.h | 4 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebSettings.cpp | 2 |
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); } }; |