Skip to content

Commit 55fbf64

Browse files
authored
Merge 8ab4c98 into 3c981e2
2 parents 3c981e2 + 8ab4c98 commit 55fbf64

1 file changed

Lines changed: 15 additions & 89 deletions

File tree

source/virtualBuffers/gecko_ia2.py

Lines changed: 15 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
Optional,
1010
)
1111
import typing
12-
import weakref
1312
from ctypes import byref
1413
from . import VirtualBuffer, VirtualBufferTextInfo, VBufStorage_findMatch_word, VBufStorage_findMatch_notEmpty
1514
import treeInterceptorHandler
@@ -264,87 +263,12 @@ def _get_location(self) -> locationHelper.RectLTWH:
264263
class Gecko_ia2(VirtualBuffer):
265264

266265
TextInfo=Gecko_ia2_TextInfo
267-
#: Maps NVDAObjects to a list of iframes/frames in that object's ancestry,
268-
#: ordered from deepest to shallowest. The key is held as a weak reference so
269-
#: that the cache for an object is cleaned up when that object dies. Each
270-
#: frame/iframe in the lists is a tuple of (IAccessible2_2, uniqueId). This
271-
#: cache is used across instances.
272-
_framesCache = weakref.WeakKeyDictionary()
273266
_nativeAppSelectionModeSupported = True
274267

275268
def __init__(self,rootNVDAObject):
276269
super(Gecko_ia2,self).__init__(rootNVDAObject,backendName="gecko_ia2")
277270
self._initialScrollObj = None
278271

279-
@staticmethod
280-
def _getEmbedderFrame(acc):
281-
"""Get the iframe/frame (if any) which contains the given object.
282-
For example, if acc is a button inside an iframe, this will return the iframe.
283-
"""
284-
try:
285-
# 1. Get the containing document.
286-
if not isinstance(acc, IA2.IAccessible2_2):
287-
# IAccessible NVDAObjects currently fetch IA2, but we need IA2_2 for relationTargetsOfType.
288-
# (Out-of-process, for a single relation, this is cheaper than IA2::relations.)
289-
acc = acc.QueryInterface(IA2.IAccessible2_2)
290-
targets, count = acc.relationTargetsOfType(
291-
IAccessibleHandler.RelationType.CONTAINING_DOCUMENT,
292-
1 # max relations to fetch
293-
)
294-
if count == 0:
295-
return None
296-
doc = targets[0].QueryInterface(IA2.IAccessible2_2)
297-
# 2. Get its parent (the embedder); e.g. iframe.
298-
embedder = doc.accParent
299-
if not embedder:
300-
return None
301-
embedder = embedder.QueryInterface(IA2.IAccessible2_2)
302-
# 3. Make sure this is an iframe/frame.
303-
attribs = embedder.attributes
304-
if "tag:browser;" in attribs:
305-
# This is a top level browser, not an iframe/frame.
306-
return None
307-
return embedder
308-
except COMError:
309-
return None
310-
311-
@classmethod
312-
def _iterIdsToTryWithAccChild(cls, obj):
313-
"""Return the child ids we should try with accChild in order to determine
314-
whether this object is a descendant of a particular document.
315-
"""
316-
# 1. Try the object itself.
317-
acc = obj.IAccessibleObject
318-
accId = obj.IA2UniqueID
319-
yield accId
320-
# 2. If this fails, this might be because the object is in an
321-
# out-of-process frame, in which case the embedder document won't know
322-
# about it. Try embedder frames.
323-
# 2.1. Try cached frames. We cache because walking frames is expensive,
324-
# and when trying to work out what TreeInterceptor this object belongs to,
325-
# we'll need to query these frames for each TreeInterceptor.
326-
cache = cls._framesCache.setdefault(obj, [])
327-
for acc, accId in cache:
328-
if not acc:
329-
# All frames were cached in a previous run. There are no more.
330-
return
331-
yield accId
332-
# 2.2. Walk remaining ancestor embedder frames, filling the cache as we go.
333-
while True:
334-
acc = cls._getEmbedderFrame(acc)
335-
if not acc:
336-
# No more. Signal this in the cache.
337-
cache.append((None, None))
338-
return
339-
try:
340-
accId = acc.uniqueID
341-
except COMError:
342-
# Dead object.
343-
cache.append((None, None))
344-
return
345-
cache.append((acc, accId))
346-
yield accId
347-
348272
def __contains__(self,obj):
349273
if (
350274
not (
@@ -355,19 +279,13 @@ def __contains__(self,obj):
355279
or not winUser.isDescendantWindow(self.rootNVDAObject.windowHandle, obj.windowHandle)
356280
):
357281
return False
358-
for accId in self._iterIdsToTryWithAccChild(obj):
359-
if accId == self.rootID:
360-
return True
361-
try:
362-
self.rootNVDAObject.IAccessibleObject.accChild(accId)
363-
# The object is definitely a descendant of the document.
364-
break
365-
except COMError:
366-
pass
367-
else:
368-
# The object is definitely not a descendant of the document.
282+
accId = obj.IA2UniqueID
283+
if accId == self.rootID:
284+
return True
285+
try:
286+
self.rootNVDAObject.IAccessibleObject.accChild(accId)
287+
except COMError:
369288
return False
370-
371289
return not self._isNVDAObjectInApplication(obj)
372290

373291
def _get_isAlive(self):
@@ -393,7 +311,15 @@ def _get_isAlive(self):
393311
return not isDefunct
394312

395313
def getNVDAObjectFromIdentifier(self, docHandle, ID):
396-
return NVDAObjects.IAccessible.getNVDAObjectFromEvent(docHandle, winUser.OBJID_CLIENT, ID)
314+
try:
315+
pacc=self.rootNVDAObject.IAccessibleObject.accChild(ID)
316+
except COMError:
317+
return None
318+
return NVDAObjects.IAccessible.IAccessible(
319+
windowHandle=docHandle,
320+
IAccessibleObject=IAccessibleHandler.normalizeIAccessible(pacc),
321+
IAccessibleChildID=0
322+
)
397323

398324
def getIdentifierFromNVDAObject(self,obj):
399325
docHandle=obj.windowHandle

0 commit comments

Comments
 (0)