@@ -213,8 +213,40 @@ 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+ value = self .value
225+ if not value :
226+ return False
227+ if not hasattr (self , "treeInterceptor" ):
228+ return False
229+ ti = self .treeInterceptor
230+ if ti is None or not hasattr (ti , "documentConstantIdentifier" ):
231+ return False
232+ documentConstantIdentifier = ti .documentConstantIdentifier
233+ if self .valueToSamePage (value , documentConstantIdentifier ):
234+ return True
235+ return False
236+
237+ def valueToSamePage (self , value : str , constantIdentifier : str ) -> bool :
238+ """Function used to check if link destination points to the same page"""
239+ if not value or not constantIdentifier :
240+ return False
241+ if constantIdentifier .endswith ("/" ):
242+ constantIdentifier = constantIdentifier [:- 1 ]
243+ queryParamCharPos = constantIdentifier .find ("?" )
244+ if queryParamCharPos > 0 :
245+ constantIdentifier = constantIdentifier [:queryParamCharPos ]
246+ if value .startswith (f"{ constantIdentifier } #" ):
247+ return True
248+ return False
249+
218250 def _get_landmark (self ):
219251 xmlRoles = self .IA2Attributes .get ("xml-roles" , "" ).split (" " )
220252 landmark = next ((xr for xr in xmlRoles if xr in aria .landmarkRoles ), None )
0 commit comments