diff options
Diffstat (limited to 'WebCore/accessibility/gtk')
-rw-r--r-- | WebCore/accessibility/gtk/AXObjectCacheAtk.cpp | 37 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp | 6 | ||||
-rw-r--r-- | WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp | 75 |
3 files changed, 101 insertions, 17 deletions
diff --git a/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp b/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp index c30b006..a4ea87c 100644 --- a/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp +++ b/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp @@ -22,6 +22,10 @@ #include "AccessibilityObject.h" #include "AccessibilityObjectWrapperAtk.h" +#include "AccessibilityRenderObject.h" +#include "GOwnPtr.h" +#include "Range.h" +#include "TextIterator.h" namespace WebCore { @@ -50,6 +54,39 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX } } +static void emitTextChanged(AccessibilityRenderObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, unsigned count) +{ + // Get the axObject for the parent object + AtkObject* wrapper = object->parentObjectUnignored()->wrapper(); + if (!wrapper || !ATK_IS_TEXT(wrapper)) + return; + + // Select the right signal to be emitted + CString detail; + switch (textChange) { + case AXObjectCache::AXTextInserted: + detail = "text-changed::insert"; + break; + case AXObjectCache::AXTextDeleted: + detail = "text-changed::delete"; + break; + } + + if (!detail.isNull()) + g_signal_emit_by_name(wrapper, detail.data(), offset, count); +} + +void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* object, AXTextChange textChange, unsigned offset, unsigned count) +{ + // Sanity check + if (count < 1 || !object || !object->isAccessibilityRenderObject()) + return; + + Node* node = object->node(); + RefPtr<Range> range = Range::create(node->document(), Position(node->parentNode(), 0), Position(node, 0)); + emitTextChanged(toAccessibilityRenderObject(object), textChange, offset + TextIterator::rangeLength(range.get()), count); +} + void AXObjectCache::handleFocusedUIElementChanged(RenderObject* oldFocusedRender, RenderObject* newFocusedRender) { RefPtr<AccessibilityObject> oldObject = getOrCreate(oldFocusedRender); diff --git a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp index 7f9fd1a..9772b43 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp @@ -73,8 +73,12 @@ AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesO if (role == StaticTextRole) return IgnoreObject; + // Include all list items, regardless they have or not inline children + if (role == ListItemRole) + return IncludeObject; + // Bullets/numbers for list items shouldn't be exposed as AtkObjects. - if (roleValue() == ListMarkerRole) + if (role == ListMarkerRole) return IgnoreObject; return DefaultBehavior; diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp index 01dddd1..3575afe 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp @@ -55,6 +55,7 @@ #include "InlineTextBox.h" #include "IntRect.h" #include "NotImplemented.h" +#include "RenderListItem.h" #include "RenderListMarker.h" #include "RenderText.h" #include "TextEncoding.h" @@ -878,9 +879,13 @@ gchar* textForObject(AccessibilityRenderObject* accObject) g_string_append(str, "\n"); range = accObject->doAXRangeForLine(++lineNumber); } - } else if (accObject->renderer()) { + } else { + RenderObject* renderer = accObject->renderer(); + if (!renderer) + return g_string_free(str, FALSE); + // For RenderBlocks, piece together the text from the RenderText objects they contain. - for (RenderObject* obj = accObject->renderer()->firstChild(); obj; obj = obj->nextSibling()) { + for (RenderObject* obj = renderer->firstChild(); obj; obj = obj->nextSibling()) { if (obj->isBR()) { g_string_append(str, "\n"); continue; @@ -907,7 +912,17 @@ gchar* textForObject(AccessibilityRenderObject* accObject) box = box->nextTextBox(); } } + + // Insert the text of the marker for list item in the right place, if present + if (renderer->isListItem()) { + String markerText = toRenderListItem(renderer)->markerTextWithSuffix(); + if (renderer->style()->direction() == LTR) + g_string_prepend(str, markerText.utf8().data()); + else + g_string_append(str, markerText.utf8().data()); + } } + return g_string_free(str, FALSE); } @@ -939,10 +954,9 @@ static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, g // Prefix a item number/bullet if needed if (coreObject->roleValue() == ListItemRole) { RenderObject* objRenderer = static_cast<AccessibilityRenderObject*>(coreObject)->renderer(); - RenderObject* markerRenderer = objRenderer ? objRenderer->firstChild() : 0; - if (markerRenderer && markerRenderer->isListMarker()) { - String markerTxt = toRenderListMarker(markerRenderer)->text(); - ret = markerTxt.length() > 0 ? markerTxt + " " + ret : ret; + if (objRenderer && objRenderer->isListItem()) { + String markerText = toRenderListItem(objRenderer)->markerTextWithSuffix(); + ret = objRenderer->style()->direction() == LTR ? markerText + ret : ret + markerText; } } @@ -1185,8 +1199,29 @@ static AtkAttributeSet* attributeSetDifference(AtkAttributeSet* a1, AtkAttribute static guint accessibilityObjectLength(const AccessibilityObject* object) { - GOwnPtr<gchar> text(webkit_accessible_text_get_text(ATK_TEXT(object->wrapper()), 0, -1)); - return g_utf8_strlen(text.get(), -1); + // Non render objects are not taken into account + if (!object->isAccessibilityRenderObject()) + return 0; + + // For those objects implementing the AtkText interface we use the + // well known API to always get the text in a consistent way + AtkObject* atkObj = ATK_OBJECT(object->wrapper()); + if (ATK_IS_TEXT(atkObj)) { + GOwnPtr<gchar> text(webkit_accessible_text_get_text(ATK_TEXT(atkObj), 0, -1)); + return g_utf8_strlen(text.get(), -1); + } + + // Even if we don't expose list markers to Assistive + // Technologies, we need to have a way to measure their length + // for those cases when it's needed to take it into account + // separately (as in getAccessibilityObjectForOffset) + RenderObject* renderer = static_cast<const AccessibilityRenderObject*>(object)->renderer(); + if (renderer && renderer->isListMarker()) { + RenderListMarker* marker = toRenderListMarker(renderer); + return marker->text().length() + marker->suffix().length(); + } + + return 0; } static const AccessibilityObject* getAccessibilityObjectForOffset(const AccessibilityObject* object, guint offset, gint* startOffset, gint* endOffset) @@ -1321,12 +1356,7 @@ static void webkit_accessible_text_get_range_extents(AtkText* text, gint startOf static gint webkit_accessible_text_get_character_count(AtkText* text) { - AccessibilityObject* coreObject = core(text); - - if (coreObject->isTextControl()) - return coreObject->textLength(); - else - return coreObject->textUnderElement().length(); + return accessibilityObjectLength(core(text)); } static gint webkit_accessible_text_get_offset_at_point(AtkText* text, gint x, gint y, AtkCoordType coords) @@ -2026,8 +2056,21 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject) interfaceMask |= 1 << WAI_TEXT; if (!coreObject->isReadOnly()) interfaceMask |= 1 << WAI_EDITABLE_TEXT; - } else if (role != TableRole && static_cast<AccessibilityRenderObject*>(coreObject)->renderer()->childrenInline()) - interfaceMask |= 1 << WAI_TEXT; + } else { + AccessibilityRenderObject* axRenderObject = static_cast<AccessibilityRenderObject*>(coreObject); + RenderObject* renderer = axRenderObject->renderer(); + if (role != TableRole && renderer && renderer->childrenInline()) + interfaceMask |= 1 << WAI_TEXT; + else if (role == ListItemRole) { + // Add the TEXT interface for list items whose + // first accessible child has a text renderer + AccessibilityObject::AccessibilityChildrenVector children = axRenderObject->children(); + if (children.size()) { + AccessibilityObject* axRenderChild = children.at(0).get(); + interfaceMask |= getInterfaceMaskFromObject(axRenderChild); + } + } + } // Image if (coreObject->isImage()) |