static COMPtr<IAccessible> findAccessibleObjectById(AccessibilityUIElement parentObject, BSTR idAttribute) { COMPtr<IAccessible> parentIAccessible = parentObject.platformUIElement(); COMPtr<IServiceProvider> serviceProvider(Query, parentIAccessible); if (!serviceProvider) return 0; COMPtr<IAccessibleComparable> comparable = comparableObject(serviceProvider); if (!comparable) return 0; _variant_t value; _bstr_t elementIdAttributeKey(L"AXDRTElementIdAttribute"); if (SUCCEEDED(comparable->get_attribute(elementIdAttributeKey, &value.GetVARIANT()))) { ASSERT(V_VT(&value) == VT_BSTR); if (VARCMP_EQ == ::VarBstrCmp(value.bstrVal, idAttribute, LOCALE_USER_DEFAULT, 0)) return parentIAccessible; } long childCount = parentObject.childrenCount(); if (!childCount) return nullptr; COMPtr<IAccessible> result; for (long i = 0; i < childCount; ++i) { AccessibilityUIElement childAtIndex = parentObject.getChildAtIndex(i); result = findAccessibleObjectById(childAtIndex, idAttribute); if (result) return result; } return nullptr; }
void AccessibilityUIElement::parentElementCallback(const CppArgumentList&, CppVariant* result) { AccessibilityUIElement* parent = m_factory->getOrCreate(accessibilityObject().parentObject()); if (!parent) { result->setNull(); return; } result->set(*(parent->getAsCppVariant())); }
static JSValueRef getIsValidCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) { AccessibilityUIElement* uiElement = toAXElement(thisObject); if (!uiElement->platformUIElement()) return JSValueMakeBoolean(context, false); // There might be other platform logic that one could check here... return JSValueMakeBoolean(context, true); }
void AccessibilityController::accessibleElementByIdGetterCallback(const CppArgumentList& arguments, CppVariant* result) { result->setNull(); if (arguments.size() < 1 || !arguments[0].isString()) return; std::string id = arguments[0].toString(); AccessibilityUIElement* foundElement = getAccessibleElementById(id); if (!foundElement) return; result->set(*(foundElement->getAsCppVariant())); }
static String attributesOfElement(AccessibilityUIElement* element) { StringBuilder builder; builder.append(String::format("%s\n", element->role()->string().utf8().data())); // For the parent we print its role and its name, if available. builder.append("AXParent: "); AccessibilityUIElement parent = element->parentElement(); if (AtkObject* atkParent = parent.platformUIElement()) { builder.append(roleToString(atk_object_get_role(atkParent))); const char* parentName = atk_object_get_name(atkParent); if (parentName && g_utf8_strlen(parentName, -1)) builder.append(String::format(": %s", parentName)); } else builder.append("(null)"); builder.append("\n"); builder.append(String::format("AXChildren: %d\n", element->childrenCount())); builder.append(String::format("AXPosition: { %f, %f }\n", element->x(), element->y())); builder.append(String::format("AXSize: { %f, %f }\n", element->width(), element->height())); String title = element->title()->string(); if (!title.isEmpty()) builder.append(String::format("%s\n", title.utf8().data())); String description = element->description()->string(); if (!description.isEmpty()) builder.append(String::format("%s\n", description.utf8().data())); String value = element->stringValue()->string(); if (!value.isEmpty()) builder.append(String::format("%s\n", value.utf8().data())); builder.append(String::format("AXFocusable: %d\n", element->isFocusable())); builder.append(String::format("AXFocused: %d\n", element->isFocused())); builder.append(String::format("AXSelectable: %d\n", element->isSelectable())); builder.append(String::format("AXSelected: %d\n", element->isSelected())); builder.append(String::format("AXMultiSelectable: %d\n", element->isMultiSelectable())); builder.append(String::format("AXEnabled: %d\n", element->isEnabled())); builder.append(String::format("AXExpanded: %d\n", element->isExpanded())); builder.append(String::format("AXRequired: %d\n", element->isRequired())); builder.append(String::format("AXChecked: %d\n", element->isChecked())); // We append the ATK specific attributes as a single line at the end. builder.append("AXPlatformAttributes: "); builder.append(getAtkAttributeSetAsString(element->platformUIElement())); return builder.toString(); }
void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& arguments, CppVariant* result) { if (!arguments.size() || !arguments[0].isNumber()) { result->setNull(); return; } AccessibilityUIElement* child = getChildAtIndex(arguments[0].toInt32()); if (!child) { result->setNull(); return; } result->set(*(child->getAsCppVariant())); }
void AccessibilityController::notificationReceived(const WebKit::WebAccessibilityObject& target, const char* notificationName) { // Call notification listeners on the element. AccessibilityUIElement* element = m_elements.getOrCreate(target); element->notificationReceived(notificationName); // Call global notification listeners. size_t callbackCount = m_notificationCallbacks.size(); for (size_t i = 0; i < callbackCount; i++) { CppVariant arguments[2]; arguments[0].set(*element->getAsCppVariant()); arguments[1].set(notificationName); CppVariant invokeResult; m_notificationCallbacks[i].invokeDefault(arguments, 2, invokeResult); } }