@@ -33,6 +33,20 @@ This license can be found at:
3333
3434using namespace std ;
3535
36+ map<wstring,wstring> createMapOfIA2AttributesFromPacc (IAccessible2* pacc) {
37+ map<wstring,wstring> IA2AttribsMap;
38+ CComBSTR IA2Attributes;
39+ if (pacc->get_attributes (&IA2Attributes) == S_OK ) {
40+ IA2AttribsToMap (IA2Attributes.m_str ,IA2AttribsMap);
41+ }
42+ return IA2AttribsMap;
43+ }
44+
45+ bool hasXmlRoleAttribContainingValue (const map<wstring,wstring>& attribsMap, const wstring roleName) {
46+ const auto attribsMapIt = attribsMap.find (L" xml-roles" );
47+ return attribsMapIt != attribsMap.end () && attribsMapIt->second .find (roleName) != wstring::npos;
48+ }
49+
3650CComPtr<IAccessible2> GeckoVBufBackend_t::getLabelElement (IAccessible2_2* element) {
3751 IUnknown** ppUnk=nullptr ;
3852 long nTargets=0 ;
@@ -422,6 +436,16 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
422436 nhAssert (parentNode); // new node must have been created
423437 previousNode=NULL ;
424438
439+ // get IA2Attributes -- IAccessible2 attributes;
440+ map<wstring,wstring>::const_iterator IA2AttribsMapIt;
441+ auto IA2AttribsMap = createMapOfIA2AttributesFromPacc (pacc);
442+ // Add all IA2 attributes on the node
443+ for (const auto & [key, val]: IA2AttribsMap) {
444+ wstring attribName = L" IAccessible2::attribute_" ;
445+ attribName += key;
446+ parentNode->addAttribute (attribName, val);
447+ }
448+
425449 // Get role -- IAccessible2 role
426450 long role=0 ;
427451 BSTR roleString=NULL ;
@@ -438,6 +462,15 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
438462 else if (varRole.vt ==VT_BSTR )
439463 roleString=varRole.bstrVal ;
440464 }
465+
466+ // Specifically force the role of ARIA treegrids from outline to table.
467+ // We do this very early on in the rendering so that all our table logic applies.
468+ if (role == ROLE_SYSTEM_OUTLINE ) {
469+ if (hasXmlRoleAttribContainingValue (IA2AttribsMap, L" treegrid" )) {
470+ role = ROLE_SYSTEM_TABLE ;
471+ }
472+ }
473+
441474 // Add role as an attrib
442475 if (roleString)
443476 s<<roleString;
@@ -495,22 +528,6 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
495528 } else
496529 parentNode->addAttribute (L" keyboardShortcut" ,L" " );
497530
498- // get IA2Attributes -- IAccessible2 attributes;
499- BSTR IA2Attributes;
500- map<wstring,wstring> IA2AttribsMap;
501- if (pacc->get_attributes (&IA2Attributes)==S_OK ) {
502- IA2AttribsToMap (IA2Attributes,IA2AttribsMap);
503- SysFreeString (IA2Attributes);
504- // Add each IA2 attribute as an attrib.
505- for (map<wstring,wstring>::const_iterator it=IA2AttribsMap.begin ();it!=IA2AttribsMap.end ();++it) {
506- s<<L" IAccessible2::attribute_" <<it->first ;
507- parentNode->addAttribute (s.str (),it->second );
508- s.str (L" " );
509- }
510- } else
511- LOG_DEBUG (L" pacc->get_attributes failed" );
512- map<wstring,wstring>::const_iterator IA2AttribsMapIt;
513-
514531 // Check IA2Attributes, and or the role etc to work out if this object is a block element
515532 bool isBlockElement=TRUE ;
516533 if (IA2States&IA2_STATE_MULTI_LINE ) {
@@ -673,9 +690,10 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
673690 } else {
674691 // If a node has children, it's visible.
675692 isVisible = width > 0 && height > 0 || childCount > 0 ;
676- if ((role == ROLE_SYSTEM_LIST && !(states & STATE_SYSTEM_READONLY ))
677- || role == ROLE_SYSTEM_OUTLINE
678- ) {
693+ // Only render the selected item for interactive lists.
694+ if (role == ROLE_SYSTEM_LIST && !(states & STATE_SYSTEM_READONLY )) {
695+ renderSelectedItemOnly = true ;
696+ } else if (role == ROLE_SYSTEM_OUTLINE ) {
679697 renderSelectedItemOnly = true ;
680698 }
681699 if (IA2TextIsUnneededSpace
0 commit comments