Title: [93656] trunk
Revision
93656
Author
[email protected]
Date
2011-08-23 16:31:44 -0700 (Tue, 23 Aug 2011)

Log Message

Added support for momentarily revealing last typed character in password input.
Code change was partially based on Apple's iOS code and Samuel Nevala's work.
https://bugs.webkit.org/show_bug.cgi?id=32509

Patch by Chang Shu <[email protected]> on 2011-08-23
Reviewed by Alexey Proskuryakov.

Source/WebCore:

* editing/InsertIntoTextNodeCommand.cpp:
(WebCore::InsertIntoTextNodeCommand::doApply):
* rendering/RenderText.cpp:
(WebCore::SecureTextTimer::SecureTextTimer):
(WebCore::SecureTextTimer::restartWithNewText):
(WebCore::SecureTextTimer::invalidate):
(WebCore::SecureTextTimer::lastTypedCharacterOffset):
(WebCore::SecureTextTimer::fired):
(WebCore::RenderText::willBeDestroyed):
(WebCore::RenderText::setTextInternal):
(WebCore::RenderText::secureText):
(WebCore::RenderText::momentarilyRevealLastTypedCharacter):
* rendering/RenderText.h:
(WebCore::RenderText::isSecure):
* testing/Internals.cpp:
(WebCore::Internals::setPasswordEchoEnabled): Fixed some silly coding in Internals.
(WebCore::Internals::setPasswordEchoDurationInSeconds):
(WebCore::Internals::reset):

LayoutTests:

Updated failed expected files.

* editing/input/password-echo-passnode-expected.txt:
* editing/input/password-echo-passnode2-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (93655 => 93656)


--- trunk/LayoutTests/ChangeLog	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/LayoutTests/ChangeLog	2011-08-23 23:31:44 UTC (rev 93656)
@@ -1,3 +1,16 @@
+2011-08-23  Chang Shu  <[email protected]>
+
+        Added support for momentarily revealing last typed character in password input.
+        Code change was partially based on Apple's iOS code and Samuel Nevala's work.
+        https://bugs.webkit.org/show_bug.cgi?id=32509
+
+        Reviewed by Alexey Proskuryakov.
+
+        Updated failed expected files.
+
+        * editing/input/password-echo-passnode-expected.txt:
+        * editing/input/password-echo-passnode2-expected.txt:
+
 2011-08-23  Ben Wells  <[email protected]>
 
         Rebaselines for bug 66442 (skia webkit-transform breaks webkit-mask)

Modified: trunk/LayoutTests/editing/input/password-echo-passnode-expected.txt (93655 => 93656)


--- trunk/LayoutTests/editing/input/password-echo-passnode-expected.txt	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/LayoutTests/editing/input/password-echo-passnode-expected.txt	2011-08-23 23:31:44 UTC (rev 93656)
@@ -1,6 +1,6 @@
 Tests if input chars are secured correctly 
 
-Error: secured right after. expected=false, actual=true
+Success: secured right after. expected=false, actual=false
 Success: secured after delay. expected=true, actual=true
-Error: secured right after. expected=false, actual=true
+Success: secured right after. expected=false, actual=false
 Success: secured after delay. expected=true, actual=true

Modified: trunk/LayoutTests/editing/input/password-echo-passnode2-expected.txt (93655 => 93656)


--- trunk/LayoutTests/editing/input/password-echo-passnode2-expected.txt	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/LayoutTests/editing/input/password-echo-passnode2-expected.txt	2011-08-23 23:31:44 UTC (rev 93656)
@@ -1,6 +1,6 @@
 Tests if input chars are secured correctly 
 
-Error: secured right after. expected=false, actual=true
+Success: secured right after. expected=false, actual=false
 Success: secured after delay. expected=true, actual=true
-Error: secured right after. expected=false, actual=true
+Success: secured right after. expected=false, actual=false
 Success: secured after delay. expected=true, actual=true

Modified: trunk/Source/WebCore/ChangeLog (93655 => 93656)


--- trunk/Source/WebCore/ChangeLog	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/Source/WebCore/ChangeLog	2011-08-23 23:31:44 UTC (rev 93656)
@@ -1,3 +1,30 @@
+2011-08-23  Chang Shu  <[email protected]>
+
+        Added support for momentarily revealing last typed character in password input.
+        Code change was partially based on Apple's iOS code and Samuel Nevala's work.
+        https://bugs.webkit.org/show_bug.cgi?id=32509
+
+        Reviewed by Alexey Proskuryakov.
+
+        * editing/InsertIntoTextNodeCommand.cpp:
+        (WebCore::InsertIntoTextNodeCommand::doApply):
+        * rendering/RenderText.cpp:
+        (WebCore::SecureTextTimer::SecureTextTimer):
+        (WebCore::SecureTextTimer::restartWithNewText):
+        (WebCore::SecureTextTimer::invalidate):
+        (WebCore::SecureTextTimer::lastTypedCharacterOffset):
+        (WebCore::SecureTextTimer::fired):
+        (WebCore::RenderText::willBeDestroyed):
+        (WebCore::RenderText::setTextInternal):
+        (WebCore::RenderText::secureText):
+        (WebCore::RenderText::momentarilyRevealLastTypedCharacter):
+        * rendering/RenderText.h:
+        (WebCore::RenderText::isSecure):
+        * testing/Internals.cpp:
+        (WebCore::Internals::setPasswordEchoEnabled): Fixed some silly coding in Internals.
+        (WebCore::Internals::setPasswordEchoDurationInSeconds):
+        (WebCore::Internals::reset):
+
 2011-08-23  Dmitry Lomov  <Dmitry Lomov ([email protected])>
 
         https://bugs.webkit.org/show_bug.cgi?id=66751 

Modified: trunk/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp (93655 => 93656)


--- trunk/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp	2011-08-23 23:31:44 UTC (rev 93656)
@@ -28,6 +28,8 @@
 
 #include "AXObjectCache.h"
 #include "Document.h"
+#include "RenderText.h"
+#include "Settings.h"
 #include "Text.h"
 
 namespace WebCore {
@@ -47,7 +49,13 @@
 {
     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);
 

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (93655 => 93656)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2011-08-23 23:31:44 UTC (rev 93656)
@@ -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"
@@ -52,6 +53,37 @@
 
 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())
@@ -192,6 +224,9 @@
 
 void RenderText::willBeDestroyed()
 {
+    if (SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->take(this) : 0)
+        delete secureTextTimer;
+
     removeAndDestroyTextBoxes();
     RenderObject::willBeDestroyed();
 }
@@ -1258,13 +1293,13 @@
         case TSNONE:
             break;
         case TSCIRCLE:
-            m_text.fill(whiteBullet);
+            secureText(whiteBullet);
             break;
         case TSDISC:
-            m_text.fill(bullet);
+            secureText(bullet);
             break;
         case TSSQUARE:
-            m_text.fill(blackSquare);
+            secureText(blackSquare);
         }
     }
 
@@ -1274,6 +1309,28 @@
     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.fill(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);
@@ -1726,4 +1783,17 @@
 
 #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

Modified: trunk/Source/WebCore/rendering/RenderText.h (93655 => 93656)


--- trunk/Source/WebCore/rendering/RenderText.h	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/Source/WebCore/rendering/RenderText.h	2011-08-23 23:31:44 UTC (rev 93656)
@@ -115,6 +115,9 @@
 
     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 @@
     void updateNeedsTranscoding();
 
     inline void transformText(String&) const;
+    void secureText(UChar mask);
 
     float m_minWidth; // here to minimize padding in 64-bit.
 

Modified: trunk/Source/WebCore/testing/Internals.cpp (93655 => 93656)


--- trunk/Source/WebCore/testing/Internals.cpp	2011-08-23 23:24:44 UTC (rev 93655)
+++ trunk/Source/WebCore/testing/Internals.cpp	2011-08-23 23:31:44 UTC (rev 93656)
@@ -226,7 +226,7 @@
     }
 
     if (!passwordEchoEnabledBackedUp) {
-        passwordEchoEnabledBackup = enabled;
+        passwordEchoEnabledBackup = document->settings()->passwordEchoEnabled();
         passwordEchoEnabledBackedUp = true;
     }
     document->settings()->setPasswordEchoEnabled(enabled);
@@ -240,7 +240,7 @@
     }
 
     if (!passwordEchoDurationInSecondsBackedUp) {
-        passwordEchoDurationInSecondsBackup = durationInSeconds;
+        passwordEchoDurationInSecondsBackup = document->settings()->passwordEchoDurationInSeconds();
         passwordEchoDurationInSecondsBackedUp = true;
     }
     document->settings()->setPasswordEchoDurationInSeconds(durationInSeconds);
@@ -251,12 +251,16 @@
     if (!document || !document->settings())
         return;
 
-    if (passwordEchoDurationInSecondsBackedUp)
+    if (passwordEchoDurationInSecondsBackedUp) {
         document->settings()->setPasswordEchoDurationInSeconds(passwordEchoDurationInSecondsBackup);
+        passwordEchoDurationInSecondsBackedUp = false;
+    }
 
-    if (passwordEchoEnabledBackedUp)
-        document->settings()->setPasswordEchoDurationInSeconds(passwordEchoEnabledBackup);
+    if (passwordEchoEnabledBackedUp) {
+        document->settings()->setPasswordEchoEnabled(passwordEchoEnabledBackup);
+        passwordEchoEnabledBackedUp = false;
+    }
 }
 
+}
 
-}
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to