@@ -47,7 +47,10 @@ bool hasXmlRoleAttribContainingValue(const map<wstring,wstring>& attribsMap, con
4747 return attribsMapIt != attribsMap.end () && attribsMapIt->second .find (roleName) != wstring::npos;
4848}
4949
50- CComPtr<IAccessible2> GeckoVBufBackend_t::getLabelElement (IAccessible2_2* element) {
50+ CComPtr<IAccessible2> GeckoVBufBackend_t::getRelationElement (
51+ LPCOLESTR ia2TargetRelation,
52+ IAccessible2_2* element
53+ ) {
5154 IUnknown** ppUnk=nullptr ;
5255 long nTargets=0 ;
5356 // We only need to request one relation target
@@ -60,7 +63,13 @@ CComPtr<IAccessible2> GeckoVBufBackend_t::getLabelElement(IAccessible2_2* elemen
6063 numRelations=0 ;
6164 }
6265 // the relation type string *must* be passed correctly as a BSTR otherwise we can see crashes in 32 bit Firefox.
63- HRESULT res=element->get_relationTargetsOfType (CComBSTR (IA2_RELATION_LABELLED_BY ),numRelations,&ppUnk,&nTargets);
66+ BSTR relationAsBSTR = CComBSTR (ia2TargetRelation);
67+ HRESULT res = element->get_relationTargetsOfType (
68+ relationAsBSTR,
69+ numRelations,
70+ &ppUnk,
71+ &nTargets
72+ );
6473 if (res!=S_OK ) return nullptr ;
6574 // Grab all the returned IUnknowns and store them as smart pointers within a smart pointer array
6675 // so that any further returns will correctly release all the objects.
@@ -71,7 +80,7 @@ CComPtr<IAccessible2> GeckoVBufBackend_t::getLabelElement(IAccessible2_2* elemen
7180 // we can now free the memory that Gecko allocated to give us the IUnknowns
7281 CoTaskMemFree (ppUnk);
7382 if (nTargets==0 ) {
74- LOG_DEBUG (L" relationTargetsOfType for IA2_RELATION_LABELLED_BY found no targets" );
83+ LOG_DEBUG (L" relationTargetsOfType for " << relationAsBSTR. m_str << L" found no targets" );
7584 return nullptr ;
7685 }
7786 return CComQIPtr<IAccessible2>(ppUnk_smart[0 ]);
@@ -267,7 +276,7 @@ using OptionalLabelInfo = optional< LabelInfo >;
267276OptionalLabelInfo GeckoVBufBackend_t::getLabelInfo (IAccessible2* pacc2) {
268277 CComQIPtr<IAccessible2_2> pacc2_2=pacc2;
269278 if (!pacc2_2) return OptionalLabelInfo ();
270- auto targetAcc= getLabelElement ( pacc2_2);
279+ auto targetAcc = getRelationElement ( IA2_RELATION_LABELLED_BY , pacc2_2);
271280 if (!targetAcc) return OptionalLabelInfo ();
272281 CComVariant child;
273282 child.vt = VT_I4 ;
@@ -279,6 +288,15 @@ OptionalLabelInfo GeckoVBufBackend_t::getLabelInfo(IAccessible2* pacc2) {
279288 return LabelInfo { isVisible, ID } ;
280289}
281290
291+ std::optional<int > GeckoVBufBackend_t::getRelationId (LPCOLESTR ia2TargetRelation, IAccessible2* pacc2) {
292+ CComQIPtr<IAccessible2_2> pacc2_2 = pacc2;
293+ if (pacc2_2 == nullptr ) return std::optional<int >();
294+ auto targetAcc = getRelationElement (ia2TargetRelation, pacc2_2);
295+ if (targetAcc == nullptr ) return std::optional<int >();
296+ auto ID = getIAccessible2UniqueID (targetAcc);
297+ return ID ;
298+ }
299+
282300long getChildCount (const bool isAriaHidden, IAccessible2 * const pacc){
283301 long rawChildCount = 0 ;
284302 if (!isAriaHidden){
@@ -1124,6 +1142,29 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
11241142 }
11251143 }
11261144
1145+
1146+ /* Set the details summary by checking for both IA2_RELATION_DETAILS and IA2_RELATION_DETAILS_FOR as one
1147+ of the nodes in the relationship will not be in the buffer yet */
1148+ std::optional<int > detailsId = getRelationId (IA2_RELATION_DETAILS , pacc);
1149+ if (detailsId) {
1150+ auto detailsControlFieldNode = buffer->getControlFieldNodeWithIdentifier (docHandle, detailsId.value ());
1151+ if (detailsControlFieldNode) {
1152+ std::wstring detailsSummary = L" " ;
1153+ detailsControlFieldNode->getTextInRange (0 , detailsControlFieldNode->getLength (), detailsSummary, false );
1154+ parentNode->addAttribute (L" detailsSummary" , detailsSummary);
1155+ }
1156+ }
1157+
1158+ std::optional<int > detailsForId = getRelationId (IA2_RELATION_DETAILS_FOR , pacc);
1159+ if (detailsForId) {
1160+ auto detailsControlFieldNode = buffer->getControlFieldNodeWithIdentifier (docHandle, detailsForId.value ());
1161+ if (detailsControlFieldNode) {
1162+ std::wstring detailsSummary = L" " ;
1163+ parentNode->getTextInRange (0 , parentNode->getLength (), detailsSummary, false );
1164+ detailsControlFieldNode->addAttribute (L" detailsSummary" , detailsSummary);
1165+ }
1166+ }
1167+
11271168 // Clean up.
11281169 if (name)
11291170 SysFreeString (name);
0 commit comments