@@ -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,12 @@ 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+ HRESULT res = element->get_relationTargetsOfType (
67+ CComBSTR (ia2TargetRelation),
68+ numRelations,
69+ &ppUnk,
70+ &nTargets
71+ );
6472 if (res!=S_OK ) return nullptr ;
6573 // Grab all the returned IUnknowns and store them as smart pointers within a smart pointer array
6674 // so that any further returns will correctly release all the objects.
@@ -71,7 +79,10 @@ CComPtr<IAccessible2> GeckoVBufBackend_t::getLabelElement(IAccessible2_2* elemen
7179 // we can now free the memory that Gecko allocated to give us the IUnknowns
7280 CoTaskMemFree (ppUnk);
7381 if (nTargets==0 ) {
74- LOG_DEBUG (L" relationTargetsOfType for IA2_RELATION_LABELLED_BY found no targets" );
82+ std::wstring debugMsg = L" relationTargetsOfType for " ;
83+ debugMsg.append ((const wchar_t *) CComBSTR (ia2TargetRelation));
84+ debugMsg.append (L" found no targets" );
85+ LOG_DEBUG (debugMsg);
7586 return nullptr ;
7687 }
7788 return CComQIPtr<IAccessible2>(ppUnk_smart[0 ]);
@@ -267,7 +278,7 @@ using OptionalLabelInfo = optional< LabelInfo >;
267278OptionalLabelInfo GeckoVBufBackend_t::getLabelInfo (IAccessible2* pacc2) {
268279 CComQIPtr<IAccessible2_2> pacc2_2=pacc2;
269280 if (!pacc2_2) return OptionalLabelInfo ();
270- auto targetAcc= getLabelElement ( pacc2_2);
281+ auto targetAcc = getRelationElement ( IA2_RELATION_LABELLED_BY , pacc2_2);
271282 if (!targetAcc) return OptionalLabelInfo ();
272283 CComVariant child;
273284 child.vt = VT_I4 ;
@@ -279,6 +290,15 @@ OptionalLabelInfo GeckoVBufBackend_t::getLabelInfo(IAccessible2* pacc2) {
279290 return LabelInfo { isVisible, ID } ;
280291}
281292
293+ std::optional<int > GeckoVBufBackend_t::getRelationId (LPCOLESTR ia2TargetRelation, IAccessible2* pacc2) {
294+ CComQIPtr<IAccessible2_2> pacc2_2 = pacc2;
295+ if (pacc2_2 == nullptr ) return std::optional<int >();
296+ auto targetAcc = getRelationElement (ia2TargetRelation, pacc2_2);
297+ if (targetAcc == nullptr ) return std::optional<int >();
298+ auto ID = getIAccessible2UniqueID (targetAcc);
299+ return ID ;
300+ }
301+
282302long getChildCount (const bool isAriaHidden, IAccessible2 * const pacc){
283303 long rawChildCount = 0 ;
284304 if (!isAriaHidden){
@@ -1124,6 +1144,29 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
11241144 }
11251145 }
11261146
1147+
1148+ /* Set the details summary by checking for both IA2_RELATION_DETAILS and IA2_RELATION_DETAILS_FOR as one
1149+ of the nodes in the relationship will not be in the buffer yet */
1150+ std::optional<int > detailsId = getRelationId (IA2_RELATION_DETAILS , pacc);
1151+ if (detailsId) {
1152+ auto detailsControlFieldNode = buffer->getControlFieldNodeWithIdentifier (docHandle, detailsId.value ());
1153+ if (detailsControlFieldNode) {
1154+ std::wstring detailsSummary = L" " ;
1155+ detailsControlFieldNode->getTextInRange (0 , detailsControlFieldNode->getLength (), detailsSummary, false );
1156+ parentNode->addAttribute (L" detailsSummary" , detailsSummary);
1157+ }
1158+ }
1159+
1160+ std::optional<int > detailsForId = getRelationId (IA2_RELATION_DETAILS_FOR , pacc);
1161+ if (detailsForId) {
1162+ auto detailsControlFieldNode = buffer->getControlFieldNodeWithIdentifier (docHandle, detailsForId.value ());
1163+ if (detailsControlFieldNode) {
1164+ std::wstring detailsSummary = L" " ;
1165+ parentNode->getTextInRange (0 , parentNode->getLength (), detailsSummary, false );
1166+ detailsControlFieldNode->addAttribute (L" detailsSummary" , detailsSummary);
1167+ }
1168+ }
1169+
11271170 // Clean up.
11281171 if (name)
11291172 SysFreeString (name);
0 commit comments