[orca] Web: Attempt to identify and present custom images
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Web: Attempt to identify and present custom images
- Date: Wed, 3 Nov 2021 13:22:39 +0000 (UTC)
commit af6729fa567927a48b22480dd862fb38f2dda566
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Wed Nov 3 14:18:07 2021 +0100
Web: Attempt to identify and present custom images
A custom element with an author-provided name and one or more child
images (often lacking an accessible name) should be treated as an
image.
src/orca/scripts/web/braille_generator.py | 2 ++
src/orca/scripts/web/script_utilities.py | 35 +++++++++++++++++++++++++++++++
src/orca/scripts/web/speech_generator.py | 2 ++
3 files changed, 39 insertions(+)
---
diff --git a/src/orca/scripts/web/braille_generator.py b/src/orca/scripts/web/braille_generator.py
index 3d028af4b..36b943325 100644
--- a/src/orca/scripts/web/braille_generator.py
+++ b/src/orca/scripts/web/braille_generator.py
@@ -230,6 +230,8 @@ class BrailleGenerator(braille_generator.BrailleGenerator):
if self._script.utilities.isClickableElement(obj) \
or self._script.utilities.isLink(obj):
oldRole = self._overrideRole(pyatspi.ROLE_LINK, args)
+ elif self._script.utilities.isCustomImage(obj):
+ oldRole = self._overrideRole(pyatspi.ROLE_IMAGE, args)
elif self._script.utilities.isAnchor(obj):
oldRole = self._overrideRole(pyatspi.ROLE_STATIC, args)
elif self._script.utilities.treatAsDiv(obj, offset=args.get('startOffset')):
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index d45a188e6..e8a78e8f5 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -94,6 +94,7 @@ class Utilities(script_utilities.Utilities):
self._isListDescendant = {}
self._isNonNavigablePopup = {}
self._isNonEntryTextWidget = {}
+ self._isCustomImage = {}
self._isUselessImage = {}
self._isRedundantSVG = {}
self._isUselessEmptyElement = {}
@@ -187,6 +188,7 @@ class Utilities(script_utilities.Utilities):
self._isListDescendant = {}
self._isNonNavigablePopup = {}
self._isNonEntryTextWidget = {}
+ self._isCustomImage = {}
self._isUselessImage = {}
self._isRedundantSVG = {}
self._isUselessEmptyElement = {}
@@ -1187,6 +1189,9 @@ class Utilities(script_utilities.Utilities):
if self.isFakePlaceholderForEntry(obj):
return True
+ if self.isCustomImage(obj):
+ return True
+
return False
def __findRange(self, text, offset, start, end, boundary):
@@ -2303,6 +2308,8 @@ class Utilities(script_utilities.Utilities):
rv = False
elif role in [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]:
rv = True
+ elif self.isCustomImage(obj):
+ rv = False
elif not state.contains(pyatspi.STATE_FOCUSABLE) and not state.contains(pyatspi.STATE_FOCUSED):
rv = not self.hasNameAndActionAndNoUsefulChildren(obj)
else:
@@ -2454,6 +2461,10 @@ class Utilities(script_utilities.Utilities):
return 'suggestion' in self._getXMLRoles(obj)
+ def isCustomElement(self, obj):
+ tag = self._getTag(obj)
+ return tag and '-' in tag
+
def isInlineIframe(self, obj):
if not (obj and obj.getRole() == pyatspi.ROLE_INTERNAL_FRAME):
return False
@@ -3096,6 +3107,8 @@ class Utilities(script_utilities.Utilities):
rv = not self.hasExplicitName(obj)
elif role == pyatspi.ROLE_TABLE_ROW and not state.contains(pyatspi.STATE_EXPANDABLE):
rv = not self.hasExplicitName(obj)
+ elif self.isCustomImage(obj):
+ rv = False
else:
rv = super().isLayoutOnly(obj)
@@ -3939,6 +3952,28 @@ class Utilities(script_utilities.Utilities):
self._isRedundantSVG[hash(obj)] = rv
return rv
+ def isCustomImage(self, obj):
+ if not (obj and self.inDocumentContent(obj)):
+ return False
+
+ rv = self._isCustomImage.get(hash(obj))
+ if rv is not None:
+ return rv
+
+ rv = False
+ if self.isCustomElement(obj) and self.hasExplicitName(obj) \
+ and 'Text' in pyatspi.listInterfaces(obj) \
+ and not re.search(r'[^\s\ufffc]', obj.queryText().getText(0, -1)):
+ for child in obj:
+ if child.getRole() not in [pyatspi.ROLE_IMAGE, pyatspi.ROLE_CANVAS] \
+ and self._getTag(child) != 'svg':
+ break
+ else:
+ rv = True
+
+ self._isCustomImage[hash(obj)] = rv
+ return rv
+
def isUselessImage(self, obj):
if not (obj and self.inDocumentContent(obj)):
return False
diff --git a/src/orca/scripts/web/speech_generator.py b/src/orca/scripts/web/speech_generator.py
index 0abd658e9..3dcc74082 100644
--- a/src/orca/scripts/web/speech_generator.py
+++ b/src/orca/scripts/web/speech_generator.py
@@ -776,6 +776,8 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
oldRole = self._overrideRole('default', args)
elif self._script.utilities.isLink(obj):
oldRole = self._overrideRole(pyatspi.ROLE_LINK, args)
+ elif self._script.utilities.isCustomImage(obj):
+ oldRole = self._overrideRole(pyatspi.ROLE_IMAGE, args)
elif self._script.utilities.treatAsDiv(obj, offset=args.get('startOffset')):
oldRole = self._overrideRole(pyatspi.ROLE_SECTION, args)
else:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]