Skip to content

Commit c78e95c

Browse files
authored
Merge 9d13634 into 0b0bfb0
2 parents 0b0bfb0 + 9d13634 commit c78e95c

3 files changed

Lines changed: 36 additions & 4 deletions

File tree

nvdaHelper/vbufBackends/gecko_ia2/gecko_ia2.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,10 +1000,16 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(
10001000
}
10011001

10021002
BSTR value=NULL;
1003-
if(pacc->get_accValue(varChild,&value)==S_OK) {
1004-
if(value&&SysStringLen(value)==0) {
1005-
SysFreeString(value);
1006-
value=NULL;
1003+
if (pacc->get_accValue(varChild, &value) == S_OK) {
1004+
if (value) {
1005+
if (role == ROLE_SYSTEM_LINK) {
1006+
// For links, store the IAccessible value to handle same page link detection.
1007+
parentNode->addAttribute(L"IAccessible::value", value);
1008+
}
1009+
if (SysStringLen(value)==0) {
1010+
SysFreeString(value);
1011+
value=NULL;
1012+
}
10071013
}
10081014
}
10091015

source/NVDAObjects/IAccessible/ia2Web.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,30 @@ def _get_states(self):
213213
if popupState:
214214
states.discard(controlTypes.State.HASPOPUP)
215215
states.add(popupState)
216+
if self.isInternalLink:
217+
states.add(controlTypes.State.INTERNAL_LINK)
216218
return states
217219

220+
@property
221+
def isInternalLink(self) -> bool:
222+
if self.role != controlTypes.Role.LINK:
223+
return False
224+
if (
225+
not hasattr(self, "treeInterceptor")
226+
or self.treeInterceptor is None
227+
or not self.treeInterceptor.documentConstantIdentifier
228+
):
229+
return False
230+
documentConstantIdentifier = self.treeInterceptor.documentConstantIdentifier
231+
if documentConstantIdentifier.endswith("/"):
232+
documentConstantIdentifier = documentConstantIdentifier[:-1]
233+
queryParamCharPos = documentConstantIdentifier.find("?")
234+
if queryParamCharPos > 0:
235+
documentConstantIdentifier = documentConstantIdentifier[:queryParamCharPos]
236+
if self.value.startswith(f"{documentConstantIdentifier}#"):
237+
return True
238+
return False
239+
218240
def _get_landmark(self):
219241
xmlRoles = self.IA2Attributes.get("xml-roles", "").split(" ")
220242
landmark = next((xr for xr in xmlRoles if xr in aria.landmarkRoles), None)

source/controlTypes/state.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ def negativeDisplayString(self) -> str:
102102
HASPOPUP_GRID = setBit(48)
103103
HASPOPUP_LIST = setBit(49)
104104
HASPOPUP_TREE = setBit(50)
105+
INTERNAL_LINK = setBit(51)
105106

106107

107108
STATES_SORTED = frozenset([State.SORTED, State.SORTED_ASCENDING, State.SORTED_DESCENDING])
@@ -204,6 +205,9 @@ def negativeDisplayString(self) -> str:
204205
State.HASPOPUP_LIST: _("opens list"),
205206
# Translators: Presented when a control has a pop-up tree.
206207
State.HASPOPUP_TREE: _("opens tree"),
208+
# Translators: Presented when a link destination points to the page containing the link.
209+
# For example, links of a table of contents of a document with different sections.
210+
State.INTERNAL_LINK: _("same page"),
207211
}
208212

209213

0 commit comments

Comments
 (0)