Title: [126037] releases/WebKitGTK/webkit-1.8/Source
Revision
126037
Author
[email protected]
Date
2012-08-20 09:18:36 -0700 (Mon, 20 Aug 2012)

Log Message

Merge 125321 - [GTK] Broken implementation of AtkText and AtkEditableText for password fields
https://bugs.webkit.org/show_bug.cgi?id=93621

Patch by Mario Sanchez Prada <[email protected]> on 2012-08-10
Reviewed by Chris Fleizach.

Source/WebCore:

Fix broken implementation of AtkText and AtkEditableText
interfaces in the GTK port for password input fields.

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::stringValue): Call the new
function passwordFieldValue() for password input fields.
(WebCore::AccessibilityRenderObject::text): Ditto.
(WebCore::AccessibilityRenderObject::textLength): Return the
actual length of the password in the field for GTK, return -1
otherwise (not to break current behavior in other platforms).
(WebCore::AccessibilityRenderObject::doAXStringForRange): Don't
early return for password fields in GTK (will rely on text()).
(WebCore::AccessibilityRenderObject::passwordFieldValue): New, it
returns the text being actually rendered for a password input
field (normally a masked string) in GTK. It returns String() in
the rest of platforms, to ensure we don't break anything there.
(WebCore):
* accessibility/AccessibilityRenderObject.h:
(AccessibilityRenderObject):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::passwordFieldValue): Default
implementation of this new method, returning an empty string.
(AccessibilityObject):

Ensure the 'text-insert' and 'text-remove' signals for the AtkText
interface are properly emitted for password input fields.

* accessibility/gtk/AXObjectCacheAtk.cpp:
(WebCore::AXObjectCache::nodeTextChangePlatformNotification): Make
sure we never emit the password value for an input field in plain
text when inserting or removing text. Emit the masked text instead.

Source/WebKit/gtk:

Update unit test to ensure that password input fields behave
as expected when inserting and removing characters in them.

* tests/testatk.c:
(testWebkitAtkTextChangedNotifications): Updated unit test to
cover the special case of password input fields.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/ChangeLog (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebCore/ChangeLog	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/ChangeLog	2012-08-20 16:18:36 UTC (rev 126037)
@@ -1,3 +1,42 @@
+2012-08-10  Mario Sanchez Prada  <[email protected]>
+
+        [GTK] Broken implementation of AtkText and AtkEditableText for password fields
+        https://bugs.webkit.org/show_bug.cgi?id=93621
+
+        Reviewed by Chris Fleizach.
+
+        Fix broken implementation of AtkText and AtkEditableText
+        interfaces in the GTK port for password input fields.
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::stringValue): Call the new
+        function passwordFieldValue() for password input fields.
+        (WebCore::AccessibilityRenderObject::text): Ditto.
+        (WebCore::AccessibilityRenderObject::textLength): Return the
+        actual length of the password in the field for GTK, return -1
+        otherwise (not to break current behavior in other platforms).
+        (WebCore::AccessibilityRenderObject::doAXStringForRange): Don't
+        early return for password fields in GTK (will rely on text()).
+        (WebCore::AccessibilityRenderObject::passwordFieldValue): New, it
+        returns the text being actually rendered for a password input
+        field (normally a masked string) in GTK. It returns String() in
+        the rest of platforms, to ensure we don't break anything there.
+        (WebCore):
+        * accessibility/AccessibilityRenderObject.h:
+        (AccessibilityRenderObject):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::passwordFieldValue): Default
+        implementation of this new method, returning an empty string.
+        (AccessibilityObject):
+
+        Ensure the 'text-insert' and 'text-remove' signals for the AtkText
+        interface are properly emitted for password input fields.
+
+        * accessibility/gtk/AXObjectCacheAtk.cpp:
+        (WebCore::AXObjectCache::nodeTextChangePlatformNotification): Make
+        sure we never emit the password value for an input field in plain
+        text when inserting or removing text. Emit the masked text instead.
+
 2012-08-09  Mario Sanchez Prada  <[email protected]>
 
         REGRESSION (r124997): Flaky crashes in two tests

Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityObject.h (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityObject.h	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityObject.h	2012-08-20 16:18:36 UTC (rev 126037)
@@ -628,6 +628,8 @@
     virtual String descriptionForMSAA() const { return String(); }
     virtual AccessibilityRole roleValueForMSAA() const { return roleValue(); }
 
+    virtual String passwordFieldValue() const { return String(); }
+
     // Used by an ARIA tree to get all its rows.
     void ariaTreeRows(AccessibilityChildrenVector&);
     // Used by an ARIA tree item to get all of its direct rows that it can disclose.

Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2012-08-20 16:18:36 UTC (rev 126037)
@@ -1154,9 +1154,12 @@
 
 String AccessibilityRenderObject::stringValue() const
 {
-    if (!m_renderer || isPasswordField())
+    if (!m_renderer)
         return String();
 
+    if (isPasswordField())
+        return passwordFieldValue();
+
     RenderBoxModelObject* cssBox = renderBoxModelObject();
 
     if (ariaRoleAttribute() == StaticTextRole) {
@@ -1975,9 +1978,12 @@
     if (ariaRoleAttribute() == StaticTextRole)
         return ariaAccessibilityDescription();
     
-    if (!isTextControl() || isPasswordField())
+    if (!isTextControl())
         return String();
 
+    if (isPasswordField())
+        return passwordFieldValue();
+
     Node* node = m_renderer->node();
     if (!node)
         return String();
@@ -1996,8 +2002,12 @@
     ASSERT(isTextControl());
     
     if (isPasswordField())
+#if PLATFORM(GTK)
+        return passwordFieldValue().length();
+#else
         return -1; // need to return something distinct from 0
-    
+#endif
+
     return text().length();
 }
 
@@ -2792,16 +2802,13 @@
 // specified by the given character range.
 String AccessibilityRenderObject::doAXStringForRange(const PlainTextRange& range) const
 {
-    if (isPasswordField())
-        return String();
-    
     if (!range.length)
         return String();
     
     if (!isTextControl())
         return String();
     
-    String elementText = text();
+    String elementText = isPasswordField() ? passwordFieldValue() : text();
     if (range.start + range.length > elementText.length())
         return String();
     
@@ -3940,6 +3947,27 @@
     return m_roleForMSAA;
 }
 
+String AccessibilityRenderObject::passwordFieldValue() const
+{
+#if !PLATFORM(GTK)
+    // It seems only GTK is interested in this at the moment.
+    return String();
+#endif
+
+    ASSERT(isPasswordField());
+
+    // Look for the RenderText object in the RenderObject tree for this input field.
+    RenderObject* renderer = node()->renderer();
+    while (renderer && !renderer->isText())
+        renderer = renderer->firstChild();
+
+    if (!renderer || !renderer->isText())
+        return String();
+
+    // Return the text that is actually being rendered in the input field.
+    return static_cast<RenderText*>(renderer)->textWithoutTranscoding();
+}
+
 ScrollableArea* AccessibilityRenderObject::getScrollableAreaIfScrollable() const
 {
     // If the parent is a scroll view, then this object isn't really scrollable, the parent ScrollView should handle the scrolling.

Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityRenderObject.h (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityRenderObject.h	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/AccessibilityRenderObject.h	2012-08-20 16:18:36 UTC (rev 126037)
@@ -258,6 +258,8 @@
     virtual String descriptionForMSAA() const;
     virtual AccessibilityRole roleValueForMSAA() const;
 
+    virtual String passwordFieldValue() const;
+
 protected:
     RenderObject* m_renderer;
     AccessibilityRole m_ariaRole;

Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp	2012-08-20 16:18:36 UTC (rev 126037)
@@ -21,6 +21,7 @@
 #include "AXObjectCache.h"
 
 #include "AccessibilityObject.h"
+#include "AccessibilityRenderObject.h"
 #include "Document.h"
 #include "Element.h"
 #include "GOwnPtr.h"
@@ -158,8 +159,11 @@
     }
 }
 
-static void emitTextChanged(AccessibilityObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, const String& text)
+void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* object, AXTextChange textChange, unsigned offset, const String& text)
 {
+    if (!object || text.isEmpty())
+        return;
+
     AccessibilityObject* parentObject = object->parentObjectUnignored();
     if (!parentObject)
         return;
@@ -168,6 +172,14 @@
     if (!wrapper || !ATK_IS_TEXT(wrapper))
         return;
 
+    Node* node = object->node();
+    if (!node)
+        return;
+
+    // Ensure document's layout is up-to-date before using TextIterator.
+    Document* document = node->document();
+    document->updateLayout();
+
     // Select the right signal to be emitted
     CString detail;
     switch (textChange) {
@@ -179,25 +191,23 @@
         break;
     }
 
-    if (!detail.isNull())
-        g_signal_emit_by_name(wrapper, detail.data(), offset, text.length(), text.utf8().data());
-}
+    String textToEmit = text;
+    unsigned offsetToEmit = offset;
 
-void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* object, AXTextChange textChange, unsigned offset, const String& text)
-{
-    if (!object || !object->isAccessibilityRenderObject() || text.isEmpty())
-        return;
+    // If the object we're emitting the signal from represents a
+    // password field, we will emit the masked text.
+    if (parentObject->isPasswordField()) {
+        String maskedText = parentObject->passwordFieldValue();
+        textToEmit = maskedText.substring(offset, text.length());
+    } else {
+        // Consider previous text objects that might be present for
+        // the current accessibility object to ensure we emit the
+        // right offset (e.g. multiline text areas).
+        RefPtr<Range> range = Range::create(document, node->parentNode(), 0, node, 0);
+        offsetToEmit = offset + TextIterator::rangeLength(range.get());
+    }
 
-    Node* node = object->node();
-    if (!node)
-        return;
-
-    // Ensure document's layout is up-to-date before using TextIterator.
-    Document* document = node->document();
-    document->updateLayout();
-
-    RefPtr<Range> range = Range::create(document, node->parentNode(), 0, node, 0);
-    emitTextChanged(object, textChange, offset + TextIterator::rangeLength(range.get()), text);
+    g_signal_emit_by_name(wrapper, detail.data(), offsetToEmit, textToEmit.length(), textToEmit.utf8().data());
 }
 
 void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject* object, AXLoadingEvent loadingEvent)

Modified: releases/WebKitGTK/webkit-1.8/Source/WebKit/gtk/ChangeLog (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebKit/gtk/ChangeLog	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebKit/gtk/ChangeLog	2012-08-20 16:18:36 UTC (rev 126037)
@@ -1,3 +1,17 @@
+2012-08-10  Mario Sanchez Prada  <[email protected]>
+
+        [GTK] Broken implementation of AtkText and AtkEditableText for password fields
+        https://bugs.webkit.org/show_bug.cgi?id=93621
+
+        Reviewed by Chris Fleizach.
+
+        Update unit test to ensure that password input fields behave
+        as expected when inserting and removing characters in them.
+
+        * tests/testatk.c:
+        (testWebkitAtkTextChangedNotifications): Updated unit test to
+        cover the special case of password input fields.
+
 2012-08-01  Martin Robinson  <[email protected]>
 
         Update the NEWS file and configure.ac in preparation for the 1.8.2 release.

Modified: releases/WebKitGTK/webkit-1.8/Source/WebKit/gtk/tests/testatk.c (126036 => 126037)


--- releases/WebKitGTK/webkit-1.8/Source/WebKit/gtk/tests/testatk.c	2012-08-20 16:18:29 UTC (rev 126036)
+++ releases/WebKitGTK/webkit-1.8/Source/WebKit/gtk/tests/testatk.c	2012-08-20 16:18:36 UTC (rev 126037)
@@ -55,7 +55,7 @@
 
 static const char* embeddedObjects = "<html><body><p>Choose: <input value='foo' type='checkbox'/>foo <input value='bar' type='checkbox'/>bar (pick one)</p><p>Choose: <select name='foo'><option>bar</option><option>baz</option></select> (pick one)</p><p><input name='foobarbutton' value='foobar' type='button'/></p></body></html>";
 
-static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>";
+static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /><input type='password' name='passwordEntry' /></form></body></html>";
 
 static const char* hypertextAndHyperlinks = "<html><body><p>A paragraph with no links at all</p><p><a href=''>A line</a> with <a href=''>a link in the middle</a> as well as at the beginning and <a href=''>at the end</a></p><ol><li>List item with a <span><a href=''>link inside a span node</a></span></li></ol></body></html>";
 
@@ -1735,6 +1735,7 @@
     AtkObject* form = atk_object_ref_accessible_child(object, 0);
     g_assert(ATK_IS_OBJECT(form));
 
+    /* First check normal text entries. */
     AtkObject* textEntry = atk_object_ref_accessible_child(form, 0);
     g_assert(ATK_IS_EDITABLE_TEXT(textEntry));
     g_assert(atk_object_get_role(ATK_OBJECT(textEntry)) == ATK_ROLE_ENTRY);
@@ -1766,10 +1767,45 @@
     g_assert_cmpstr(textChangedResult, ==, "|1|4|8|'qux quux'|");
     g_free(text);
 
+    /* Now check for password entries. */
+    AtkObject* passwordEntry = atk_object_ref_accessible_child(form, 1);
+    g_assert(ATK_IS_EDITABLE_TEXT(passwordEntry));
+    g_assert(atk_object_get_role(ATK_OBJECT(passwordEntry)) == ATK_ROLE_PASSWORD_TEXT);
+
+    g_signal_connect(passwordEntry, "text-insert",
+                     G_CALLBACK(textChangedCb),
+                     GINT_TO_POINTER(TEXT_CHANGE_INSERT));
+    g_signal_connect(passwordEntry, "text-remove",
+                     G_CALLBACK(textChangedCb),
+                     GINT_TO_POINTER(TEXT_CHANGE_REMOVE));
+
+    pos = 0;
+    atk_editable_text_insert_text(ATK_EDITABLE_TEXT(passwordEntry), "foobar", 6, &pos);
+    g_assert_cmpstr(textChangedResult, ==, "|1|0|6|'\342\200\242\342\200\242\342\200\242\342\200\242\342\200\242\342\200\242'|");
+    text = atk_text_get_text(ATK_TEXT(passwordEntry), 0, -1);
+    g_assert_cmpstr(text, ==, "\303\242\302\200\302\242\303\242\302\200\302\242");
+    g_free(text);
+
+    atk_editable_text_delete_text(ATK_EDITABLE_TEXT(passwordEntry), 2, 4);
+    g_assert_cmpstr(textChangedResult, ==, "|2|2|2|'\342\200\242\342\200\242'|");
+
+    text = atk_text_get_text(ATK_TEXT(passwordEntry), 0, -1);
+    g_assert_cmpstr(text, ==, "\303\242\302\200\302\242\303\242");
+    g_free(text);
+
+    pos = 3;
+    atk_editable_text_insert_text(ATK_EDITABLE_TEXT(passwordEntry), "qux", 3, &pos);
+    g_assert_cmpstr(textChangedResult, ==, "|1|3|3|'\342\200\242\342\200\242\342\200\242'|");
+
+    text = atk_text_get_text(ATK_TEXT(passwordEntry), 0, -1);
+    g_assert_cmpstr(text, ==, "\303\242\302\200\302\242\303\242\302\200\302\242\303\242");
+    g_free(text);
+
     g_free(textChangedResult);
 
     g_object_unref(form);
     g_object_unref(textEntry);
+    g_object_unref(passwordEntry);
     g_object_unref(webView);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to