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);
}