[orca] Web: Cache textiness rather than the accessible text object
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Web: Cache textiness rather than the accessible text object
- Date: Mon, 7 Dec 2020 13:52:52 +0000 (UTC)
commit 78533048ba7e8581c90a6b1aab3bd4b9f2cde564
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Mon Dec 7 14:38:52 2020 +0100
Web: Cache textiness rather than the accessible text object
queryNonEmptyText() was caching the accessible text object for elements
which we concluded should be treated as navigable text. It relied upon
accessibility events to trigger the clearing of our cache. When those
events are missing, we can wind up incorrectly concluding that an element
lacks text and skip over that content. Rather than caching the text
object itself, just cache the decision about whether or not the object
should be treated as text.
src/orca/scripts/web/script_utilities.py | 69 +++++++++++++++-----------------
1 file changed, 33 insertions(+), 36 deletions(-)
---
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 5ddd843ca..9a0a47a24 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -106,7 +106,7 @@ class Utilities(script_utilities.Utilities):
self._preferDescriptionOverName = {}
self._shouldFilter = {}
self._shouldInferLabelFor = {}
- self._text = {}
+ self._treatAsTextObject = {}
self._treatAsDiv = {}
self._currentObjectContents = None
self._currentSentenceContents = None
@@ -179,6 +179,7 @@ class Utilities(script_utilities.Utilities):
self._preferDescriptionOverName = {}
self._shouldFilter = {}
self._shouldInferLabelFor = {}
+ self._treatAsTextObject = {}
self._treatAsDiv = {}
self._paths = {}
self._contextPathsRolesAndNames = {}
@@ -195,7 +196,6 @@ class Utilities(script_utilities.Utilities):
self._currentWordContents = None
self._currentCharacterContents = None
self._currentTextAttrs = {}
- self._text = {}
def isDocument(self, obj):
if not obj:
@@ -981,66 +981,63 @@ class Utilities(script_utilities.Utilities):
self._isNonEntryTextWidget[hash(obj)] = rv
return rv
- def queryNonEmptyText(self, obj, excludeNonEntryTextWidgets=True):
- if not (obj and self.inDocumentContent(obj)) or self._script.browseModeIsSticky():
- return super().queryNonEmptyText(obj)
-
- if self.isDead(obj):
- return None
+ def treatAsTextObject(self, obj, excludeNonEntryTextWidgets=True):
+ if not obj or self.isDead(obj):
+ return False
- if hash(obj) in self._text:
- return self._text.get(hash(obj))
+ rv = self._treatAsTextObject.get(hash(obj))
+ if rv is not None:
+ return rv
- try:
- rv = obj.queryText()
- characterCount = rv.characterCount
- except NotImplementedError:
- msg = "WEB: %s doesn't implement text interface" % obj
- debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
- except:
- msg = "WEB: Exception getting character count for %s" % obj
+ rv = "Text" in pyatspi.listInterfaces(obj)
+ if not rv:
+ msg = "WEB: %s does not implement text interface" % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
- else:
- if not characterCount:
- msg = "WEB: %s reports 0 characters" % obj
- debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
- if self.isCellWithNameFromHeader(obj):
- pass
- elif self._treatObjectAsWhole(obj) and obj.name:
+ if not self.inDocumentContent(obj):
+ return rv
+
+ if rv and self._treatObjectAsWhole(obj) and obj.name and not self.isCellWithNameFromHeader(obj):
msg = "WEB: Treating %s as non-text: named object treated as whole." % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
- elif not self.isLiveRegion(obj):
+ rv = False
+
+ elif rv and not self.isLiveRegion(obj):
doNotQuery = [pyatspi.ROLE_LIST_BOX]
role = obj.getRole()
if rv and role in doNotQuery:
msg = "WEB: Treating %s as non-text due to role." % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
+ rv = False
if rv and excludeNonEntryTextWidgets and self.isNonEntryTextWidget(obj):
msg = "WEB: Treating %s as non-text: is non-entry text widget." % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
+ rv = False
if rv and (self.isHidden(obj) or self.isOffScreenLabel(obj)):
msg = "WEB: Treating %s as non-text: is hidden or off-screen label." % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
+ rv = False
if rv and self.isNonNavigableEmbeddedDocument(obj):
msg = "WEB: Treating %s as non-text: is non-navigable embedded document." % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
+ rv = False
if rv and self.isFakePlaceholderForEntry(obj):
msg = "WEB: Treating %s as non-text: is fake placeholder for entry." % obj
debug.println(debug.LEVEL_INFO, msg, True)
- rv = None
+ rv = False
- self._text[hash(obj)] = rv
+ self._treatAsTextObject[hash(obj)] = rv
return rv
+ def queryNonEmptyText(self, obj, excludeNonEntryTextWidgets=True):
+ if self._script.browseModeIsSticky():
+ return super().queryNonEmptyText(obj)
+
+ if not self.treatAsTextObject(obj, excludeNonEntryTextWidgets):
+ return None
+
+ return super().queryNonEmptyText(obj)
+
def hasNameAndActionAndNoUsefulChildren(self, obj):
if not (obj and self.inDocumentContent(obj)):
return False
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]