diff options
Diffstat (limited to 'Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp')
-rw-r--r-- | Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp b/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp index 753f761e4..85e0c64d5 100644 --- a/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp +++ b/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp @@ -30,7 +30,8 @@ #include "Range.h" #include "TextIterator.h" #include "WebKitAccessibleWrapperAtk.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> namespace WebCore { @@ -75,7 +76,19 @@ void AXObjectCache::attachWrapper(AccessibilityObject* obj) if (!document || document->childNeedsStyleRecalc()) return; - // Don't emit the signal for objects that we already know won't be exposed directly. + // Don't emit the signal when the actual object being added is not going to be exposed. + if (obj->accessibilityIsIgnoredByDefault()) + return; + + // Don't emit the signal if the object being added is not -- or not yet -- rendered, + // which can occur in nested iframes. In these instances we don't want to ignore the + // child. But if an assistive technology is listening, AT-SPI2 will attempt to create + // and cache the state set for the child upon emission of the signal. If the object + // has not yet been rendered, this will result in a crash. + if (!obj->renderer()) + return; + + // Don't emit the signal for objects whose parents won't be exposed directly. AccessibilityObject* coreParent = obj->parentObjectUnignored(); if (!coreParent || coreParent->accessibilityIsIgnoredByDefault()) return; @@ -119,8 +132,8 @@ static void notifyChildrenSelectionChange(AccessibilityObject* object) // focused object and its associated list object, as per previous // calls to this function, in order to properly decide whether to // emit some signals or not. - DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldListObject, ()); - DEFINE_STATIC_LOCAL(RefPtr<AccessibilityObject>, oldFocusedObject, ()); + static NeverDestroyed<RefPtr<AccessibilityObject>> oldListObject; + static NeverDestroyed<RefPtr<AccessibilityObject>> oldFocusedObject; // Only list boxes and menu lists supported so far. if (!object || !(object->isListBox() || object->isMenuList())) @@ -128,21 +141,19 @@ static void notifyChildrenSelectionChange(AccessibilityObject* object) // Only support HTML select elements so far (ARIA selectors not supported). Node* node = object->node(); - if (!node || !isHTMLSelectElement(node)) + if (!is<HTMLSelectElement>(node)) return; // Emit signal from the listbox's point of view first. g_signal_emit_by_name(object->wrapper(), "selection-changed"); // Find the item where the selection change was triggered from. - HTMLSelectElement* select = toHTMLSelectElement(node); - if (!select) - return; - int changedItemIndex = select->activeSelectionStartListIndex(); + HTMLSelectElement& select = downcast<HTMLSelectElement>(*node); + int changedItemIndex = select.activeSelectionStartListIndex(); AccessibilityObject* listObject = getListObject(object); if (!listObject) { - oldListObject = 0; + oldListObject.get() = nullptr; return; } @@ -154,11 +165,11 @@ static void notifyChildrenSelectionChange(AccessibilityObject* object) // Ensure the current list object is the same than the old one so // further comparisons make sense. Otherwise, just reset // oldFocusedObject so it won't be taken into account. - if (oldListObject != listObject) - oldFocusedObject = 0; + if (oldListObject.get() != listObject) + oldFocusedObject.get() = nullptr; - AtkObject* axItem = item ? item->wrapper() : 0; - AtkObject* axOldFocusedObject = oldFocusedObject ? oldFocusedObject->wrapper() : 0; + AtkObject* axItem = item ? item->wrapper() : nullptr; + AtkObject* axOldFocusedObject = oldFocusedObject.get() ? oldFocusedObject.get()->wrapper() : nullptr; // Old focused object just lost focus, so emit the events. if (axOldFocusedObject && axItem != axOldFocusedObject) { @@ -179,8 +190,8 @@ static void notifyChildrenSelectionChange(AccessibilityObject* object) } // Update pointers to the previously involved objects. - oldListObject = listObject; - oldFocusedObject = item; + oldListObject.get() = listObject; + oldFocusedObject.get() = item; } void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AXNotification notification) @@ -191,7 +202,7 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX switch (notification) { case AXCheckedStateChanged: - if (!coreObject->isCheckboxOrRadio()) + if (!coreObject->isCheckboxOrRadio() && !coreObject->isSwitch()) return; atk_object_notify_state_change(axObject, ATK_STATE_CHECKED, coreObject->isChecked()); break; @@ -212,7 +223,13 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX propertyValues.property_name = "accessible-value"; memset(&propertyValues.new_value, 0, sizeof(GValue)); +#if ATK_CHECK_VERSION(2,11,92) + double value; + atk_value_get_value_and_text(ATK_VALUE(axObject), &value, nullptr); + g_value_set_double(g_value_init(&propertyValues.new_value, G_TYPE_DOUBLE), value); +#else atk_value_get_current_value(ATK_VALUE(axObject), &propertyValues.new_value); +#endif g_signal_emit_by_name(ATK_OBJECT(axObject), "property-change::accessible-value", &propertyValues, NULL); } @@ -232,7 +249,7 @@ void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* obje if (!object || text.isEmpty()) return; - AccessibilityObject* parentObject = object->parentObjectUnignored(); + AccessibilityObject* parentObject = object->isNonNativeTextControl() ? object : object->parentObjectUnignored(); if (!parentObject) return; @@ -251,12 +268,15 @@ void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* obje // Select the right signal to be emitted CString detail; switch (textChange) { - case AXObjectCache::AXTextInserted: + case AXTextInserted: detail = "text-insert"; break; - case AXObjectCache::AXTextDeleted: + case AXTextDeleted: detail = "text-remove"; break; + case AXTextAttributesChanged: + detail = "text-attributes-changed"; + break; } String textToEmit = text; |