[orca] Add support for DPub ARIA roles



commit 2b8b3000301486cc7deea3b67efa0fc96d986a08
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Fri Jul 21 10:05:42 2017 +0200

    Add support for DPub ARIA roles

 src/orca/formatting.py                   |   15 +++
 src/orca/generator.py                    |   79 ++++++++++++
 src/orca/messages.py                     |  162 ++++++++++++++++++++++++
 src/orca/object_properties.py            |  201 ++++++++++++++++++++++++++++++
 src/orca/script_utilities.py             |  130 +++++++++++++++++++
 src/orca/scripts/web/script_utilities.py |  125 ++++++++++++++++++
 src/orca/scripts/web/speech_generator.py |    7 +-
 src/orca/speech_generator.py             |   82 +++++++++++--
 8 files changed, 788 insertions(+), 13 deletions(-)
---
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index 93627ac..36f21eb 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -172,6 +172,10 @@ formatting = {
             'unfocused': 'labelAndName + roleName + pause + (currentLineText + anyTextSelection or 
positionInList) + ' + MNEMONIC + ' + accelerator',
             'basicWhereAmI': 'label + roleName + pause + name + (currentLineText + anyTextSelection or 
positionInList) + ' + MNEMONIC + ' + accelerator'
             },
+        pyatspi.ROLE_COMMENT: {
+            'focused': 'labelOrName + roleName',
+            'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection',
+            },
         pyatspi.ROLE_DIAL: {
             'focused': 'value',
             'unfocused': 'labelOrName + roleName + value + required + availability + ' + MNEMONIC,
@@ -186,6 +190,14 @@ formatting = {
             'basicWhereAmI': 'label + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC,
             'detailedWhereAmI': 'label + readOnly + textRole + textContentWithAttributes + anyTextSelection 
+ ' + MNEMONIC
             },
+        'ROLE_DPUB_LANDMARK': {
+            'focused': 'leaving or labelOrName',
+            'unfocused': 'labelOrName + currentLineText + allTextSelection'
+            },
+        'ROLE_DPUB_SECTION': {
+            'focused': 'leaving or (labelOrName + roleName)',
+            'unfocused': 'labelOrName + currentLineText + allTextSelection'
+            },
         pyatspi.ROLE_EMBEDDED: {
             'focused': 'labelOrName + roleName',
             'unfocused': '(expandedEOCs or (labelOrName + unrelatedLabels)) + roleName'
@@ -196,6 +208,9 @@ formatting = {
             'basicWhereAmI': 'labelOrName + readOnly + textRole + (textContent or placeholderText) + 
anyTextSelection + required + pause + invalid + ' + MNEMONIC,
             'detailedWhereAmI': 'labelOrName + readOnly + textRole + (textContentWithAttributes or 
placeholderText) + anyTextSelection + required + pause + invalid + ' + MNEMONIC,
             },
+        'ROLE_FOOTNOTE': {
+            'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection',
+            },
         pyatspi.ROLE_FOOTER: {
             'unfocused': '(displayedText or name) + roleName',
         },
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 1f682a3..27bd38f 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -1189,6 +1189,13 @@ class Generator:
                 return 'ROLE_MATH_TABLE'
             if self._script.utilities.isMathTableRow(obj):
                 return 'ROLE_MATH_TABLE_ROW'
+        if self._script.utilities.isDPub(obj):
+            if self._script.utilities.isDPubFootnote(obj):
+                return 'ROLE_FOOTNOTE'
+            if self._script.utilities.isLandmark(obj):
+                return 'ROLE_DPUB_LANDMARK'
+            if obj.getRole() == pyatspi.ROLE_SECTION:
+                return 'ROLE_DPUB_SECTION'
         if self._script.utilities.isSwitch(obj):
             return 'ROLE_SWITCH'
         if self._script.utilities.isAnchor(obj):
@@ -1240,6 +1247,78 @@ class Generator:
         if self._script.utilities.isSwitch(obj):
             return object_properties.ROLE_SWITCH
 
+        if self._script.utilities.isDPub(obj):
+            if self._script.utilities.isLandmark(obj):
+                if self._script.utilities.isDPubAcknowledgments(obj):
+                    return object_properties.ROLE_ACKNOWLEDGMENTS
+                if self._script.utilities.isDPubAfterword(obj):
+                    return object_properties.ROLE_AFTERWORD
+                if self._script.utilities.isDPubAppendix(obj):
+                    return object_properties.ROLE_APPENDIX
+                if self._script.utilities.isDPubBibliography(obj):
+                    return object_properties.ROLE_BIBLIOGRAPHY
+                if self._script.utilities.isDPubChapter(obj):
+                    return object_properties.ROLE_CHAPTER
+                if self._script.utilities.isDPubConclusion(obj):
+                    return object_properties.ROLE_CONCLUSION
+                if self._script.utilities.isDPubCredits(obj):
+                    return object_properties.ROLE_CREDITS
+                if self._script.utilities.isDPubEndnotes(obj):
+                    return object_properties.ROLE_ENDNOTES
+                if self._script.utilities.isDPubEpilogue(obj):
+                    return object_properties.ROLE_EPILOGUE
+                if self._script.utilities.isDPubErrata(obj):
+                    return object_properties.ROLE_ERRATA
+                if self._script.utilities.isDPubForeword(obj):
+                    return object_properties.ROLE_FOREWORD
+                if self._script.utilities.isDPubGlossary(obj):
+                    return object_properties.ROLE_GLOSSARY
+                if self._script.utilities.isDPubIndex(obj):
+                    return object_properties.ROLE_INDEX
+                if self._script.utilities.isDPubIntroduction(obj):
+                    return object_properties.ROLE_INTRODUCTION
+                if self._script.utilities.isDPubPagelist(obj):
+                    return object_properties.ROLE_PAGELIST
+                if self._script.utilities.isDPubPart(obj):
+                    return object_properties.ROLE_PART
+                if self._script.utilities.isDPubPreface(obj):
+                    return object_properties.ROLE_PREFACE
+                if self._script.utilities.isDPubPrologue(obj):
+                    return object_properties.ROLE_PROLOGUE
+                if self._script.utilities.isDPubToc(obj):
+                    return object_properties.ROLE_TOC
+            elif role == "ROLE_DPUB_SECTION":
+                if self._script.utilities.isDPubAbstract(obj):
+                    return object_properties.ROLE_ABSTRACT
+                if self._script.utilities.isDPubColophon(obj):
+                    return object_properties.ROLE_COLOPHON
+                if self._script.utilities.isDPubCredit(obj):
+                    return object_properties.ROLE_CREDIT
+                if self._script.utilities.isDPubDedication(obj):
+                    return object_properties.ROLE_DEDICATION
+                if self._script.utilities.isDPubEpigraph(obj):
+                    return object_properties.ROLE_EPIGRAPH
+                if self._script.utilities.isDPubExample(obj):
+                    return object_properties.ROLE_EXAMPLE
+                if self._script.utilities.isDPubPullquote(obj):
+                    return object_properties.ROLE_PULLQUOTE
+                if self._script.utilities.isDPubQna(obj):
+                    return object_properties.ROLE_QNA
+            elif role == pyatspi.ROLE_LIST_ITEM:
+                if self._script.utilities.isDPubBiblioentry(obj):
+                    return object_properties.ROLE_BIBLIOENTRY
+                if self._script.utilities.isDPubEndnote(obj):
+                    return object_properties.ROLE_ENDNOTE
+            else:
+                if self._script.utilities.isDPubCover(obj):
+                    return object_properties.ROLE_COVER
+                if self._script.utilities.isDPubFootnote(obj):
+                    return object_properties.ROLE_FOOTNOTE
+                if self._script.utilities.isDPubPagebreak(obj):
+                    return object_properties.ROLE_PAGEBREAK
+                if self._script.utilities.isDPubSubtitle(obj):
+                    return object_properties.ROLE_SUBTITLE
+
         if self._script.utilities.isLandmark(obj):
             if self._script.utilities.isLandmarkBanner(obj):
                 return object_properties.ROLE_LANDMARK_BANNER
diff --git a/src/orca/messages.py b/src/orca/messages.py
index a2a3abb..7473dcc 100644
--- a/src/orca/messages.py
+++ b/src/orca/messages.py
@@ -1112,6 +1112,168 @@ LEAVING_PANEL = _("leaving panel.")
 # table and then navigates out of it.
 LEAVING_TABLE = _("leaving table.")
 
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_ABSTRACT = C_("role", "leaving abstract.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_ACKNOWLEDGMENTS = C_("role", "leaving acknowledgments.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_AFTERWORD = C_("role", "leaving afterword.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_APPENDIX = C_("role", "leaving appendix.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_BIBLIOGRAPHY = C_("role", "leaving bibliography.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_CHAPTER = C_("role", "leaving chapter.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_COLOPHON = C_("role", "leaving colophon.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_CONCLUSION = C_("role", "leaving conclusion.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_CREDIT = C_("role", "leaving credit.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_CREDITS = C_("role", "leaving credits.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_DEDICATION = C_("role", "leaving dedication.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_ENDNOTES = C_("role", "leaving endnotes.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_EPIGRAPH = C_("role", "leaving epigraph.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_EPILOGUE = C_("role", "leaving epilogue.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_ERRATA = C_("role", "leaving errata.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_EXAMPLE = C_("role", "leaving example.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_FOREWORD = C_("role", "leaving foreword.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_GLOSSARY = C_("role", "leaving glossary.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_INDEX = C_("role", "leaving index.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_INTRODUCTION = C_("role", "leaving introduction.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_PAGELIST = C_("role", "leaving page list.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_PART = C_("role", "leaving part.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_PREFACE = C_("role", "leaving preface.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_PROLOGUE = C_("role", "leaving prologue.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_PULLQUOTE = C_("role", "leaving pullquote.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_QNA = C_("role", "leaving QNA.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_TOC = C_("role", "leaving table of contents.")
+
 # Translators: when the user selects (highlights) or unselects text in a
 # document, Orca will speak information about what they have selected or
 # unselected. This message is presented when the user selects from the
diff --git a/src/orca/object_properties.py b/src/orca/object_properties.py
index 45a9f72..ae50377 100644
--- a/src/orca/object_properties.py
+++ b/src/orca/object_properties.py
@@ -72,6 +72,207 @@ NODE_LEVEL_BRAILLE = _("TREE LEVEL %d")
 # typed or arrowed to.
 ROLE_EDITABLE_COMBO_BOX = _("editable combo box")
 
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the abstract in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-abstract
+ROLE_ABSTRACT = C_("role", "abstract")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the acknowledgments in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-acknowledgments
+ROLE_ACKNOWLEDGMENTS = C_("role", "acknowledgments")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the afterword in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-afterword
+ROLE_AFTERWORD = C_("role", "afterword")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the appendix in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-appendix
+ROLE_APPENDIX = C_("role", "appendix")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a bibliography entry in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-biblioentry
+ROLE_BIBLIOENTRY = C_("role", "bibliography entry")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the bibliography in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-bibliography
+ROLE_BIBLIOGRAPHY = C_("role", "bibliography")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a chapter in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-chapter
+ROLE_CHAPTER = C_("role", "chapter")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the colophon in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-colophon
+ROLE_COLOPHON = C_("role", "colophon")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the conclusion in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-conclusion
+ROLE_CONCLUSION = C_("role", "conclusion")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the cover in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-cover
+ROLE_COVER = C_("role", "cover")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a single credit in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-credit
+ROLE_CREDIT = C_("role", "credit")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the credits in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-credits
+ROLE_CREDITS = C_("role", "credits")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the dedication in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-dedication
+ROLE_DEDICATION = C_("role", "dedication")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a single endnote in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-endnote
+ROLE_ENDNOTE = C_("role", "endnote")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the endnotes in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-endnotes
+ROLE_ENDNOTES = C_("role", "endnotes")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the epigraph in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-epigraph
+ROLE_EPIGRAPH = C_("role", "epigraph")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the epilogue in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-epilogue
+ROLE_EPILOGUE = C_("role", "epilogue")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the errata in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-errata
+ROLE_ERRATA = C_("role", "errata")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to an example in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-example
+ROLE_EXAMPLE = C_("role", "example")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a single footnote in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-footnote
+ROLE_FOOTNOTE = C_("role", "footnote")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the foreword in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-foreword
+ROLE_FOREWORD = C_("role", "foreword")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the glossary in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-glossary
+ROLE_GLOSSARY = C_("role", "glossary")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the index in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-index
+ROLE_INDEX = C_("role", "index")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the introduction in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-introduction
+ROLE_INTRODUCTION = C_("role", "introduction")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a pagebreak in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-pagebreak
+ROLE_PAGEBREAK = C_("role", "page break")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a page list in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-pagelist
+ROLE_PAGELIST = C_("role", "page list")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a named part in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-part
+ROLE_PART = C_("role", "part")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the preface in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-preface
+ROLE_PREFACE = C_("role", "preface")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the prologue in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-prologue
+ROLE_PROLOGUE = C_("role", "prologue")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a pullquote in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-pullquote
+ROLE_PULLQUOTE = C_("role", "pullquote")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to a questions-and-answers section in a digitally-published
+# document. https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-qna
+# In English, "QNA" is generally recognized by native speakers. If your language
+# lacks the equivalent, please prefer the shortest phrase which clearly conveys
+# the meaning.
+ROLE_QNA = C_("role", "QNA")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the subtitle in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-subtitle
+ROLE_SUBTITLE = C_("role", "subtitle")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# This role refers to the table of contents in a digitally-published document.
+# https://rawgit.com/w3c/aria/master/aria/dpub.html#doc-toc
+ROLE_TOC = C_("role", "table of contents")
+
 # Translators: The 'h' in this string represents a heading level attribute for
 # content that you might find in something such as HTML content (e.g., <h1>).
 # The translated form is meant to be a single character followed by a numeric
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index deecc93..8f0a43f 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -656,6 +656,114 @@ class Utilities:
     def isHidden(self, obj):
         return False
 
+    def isDPub(self, obj):
+        return False
+
+    def isDPubAbstract(self, obj):
+        return False
+
+    def isDPubAcknowledgments(self, obj):
+        return False
+
+    def isDPubAfterword(self, obj):
+        return False
+
+    def isDPubAppendix(self, obj):
+        return False
+
+    def isDPubBibliography(self, obj):
+        return False
+
+    def isDPubBacklink(self, obj):
+        return False
+
+    def isDPubBiblioref(self, obj):
+        return False
+
+    def isDPubChapter(self, obj):
+        return False
+
+    def isDPubColophon(self, obj):
+        return False
+
+    def isDPubConclusion(self, obj):
+        return False
+
+    def isDPubCover(self, obj):
+        return False
+
+    def isDPubCredit(self, obj):
+        return False
+
+    def isDPubCredits(self, obj):
+        return False
+
+    def isDPubDedication(self, obj):
+        return False
+
+    def isDPubEndnote(self, obj):
+        return False
+
+    def isDPubEndnotes(self, obj):
+        return False
+
+    def isDPubEpigraph(self, obj):
+        return False
+
+    def isDPubEpilogue(self, obj):
+        return False
+
+    def isDPubErrata(self, obj):
+        return False
+
+    def isDPubExample(self, obj):
+        return False
+
+    def isDPubFootnote(self, obj):
+        return False
+
+    def isDPubForeword(self, obj):
+        return False
+
+    def isDPubGlossary(self, obj):
+        return False
+
+    def isDPubGlossref(self, obj):
+        return False
+
+    def isDPubIndex(self, obj):
+        return False
+
+    def isDPubIntroduction(self, obj):
+        return False
+
+    def isDPubPagelist(self, obj):
+        return False
+
+    def isDPubPagebreak(self, obj):
+        return False
+
+    def isDPubPart(self, obj):
+        return False
+
+    def isDPubPreface(self, obj):
+        return False
+
+    def isDPubPrologue(self, obj):
+        return False
+
+    def isDPubPullquote(self, obj):
+        return False
+
+    def isDPubQna(self, obj):
+        return False
+
+    def isDPubSubtitle(self, obj):
+        return False
+
+    def isDPubToc(self, obj):
+        return False
+
     def isLandmark(self, obj):
         return False
 
@@ -677,6 +785,9 @@ class Utilities:
     def isLandmarkNavigation(self, obj):
         return False
 
+    def isDPubNoteref(self, obj):
+        return False
+
     def isLandmarkRegion(self, obj):
         return False
 
@@ -786,6 +897,25 @@ class Utilities:
         return ["banner",
                 "complementary",
                 "contentinfo",
+                "doc-acknowledgments",
+                "doc-afterword",
+                "doc-appendix",
+                "doc-bibliography",
+                "doc-chapter",
+                "doc-conclusion",
+                "doc-credits",
+                "doc-endnotes",
+                "doc-epilogue",
+                "doc-errata",
+                "doc-foreword",
+                "doc-glossary",
+                "doc-index",
+                "doc-introduction",
+                "doc-pagelist",
+                "doc-part",
+                "doc-preface",
+                "doc-prologue",
+                "doc-toc",
                 "form",
                 "main",
                 "navigation",
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 9feca55..0adb65a 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -62,6 +62,7 @@ class Utilities(script_utilities.Utilities):
         self._isMenuDescendant = {}
         self._isToolBarDescendant = {}
         self._isLayoutOnly = {}
+        self._isDPub = {}
         self._isMath = {}
         self._mathNestingLevel = {}
         self._isOffScreenLabel = {}
@@ -123,6 +124,7 @@ class Utilities(script_utilities.Utilities):
         self._isMenuDescendant = {}
         self._isToolBarDescendant = {}
         self._isLayoutOnly = {}
+        self._isDPub = {}
         self._isMath = {}
         self._mathNestingLevel = {}
         self._isOffScreenLabel = {}
@@ -2151,6 +2153,8 @@ class Utilities(script_utilities.Utilities):
             rv = False
         elif self.isLandmark(obj):
             rv = False
+        elif self.isDPub(obj):
+            rv = False
         else:
             rv = super().isLayoutOnly(obj)
 
@@ -2415,6 +2419,127 @@ class Utilities(script_utilities.Utilities):
         self._isEditableComboBox[hash(obj)] = rv
         return rv
 
+    def isDPub(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
+            return False
+
+        rv = self._isDPub.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        roles = self._getXMLRoles(obj)
+        rv = bool(list(filter(lambda x: x.startswith("doc-"), roles)))
+        self._isDPub[hash(obj)] = rv
+        return rv
+
+    def isDPubAbstract(self, obj):
+        return 'doc-abstract' in self._getXMLRoles(obj)
+
+    def isDPubAcknowledgments(self, obj):
+        return 'doc-acknowledgments' in self._getXMLRoles(obj)
+
+    def isDPubAfterword(self, obj):
+        return 'doc-afterword' in self._getXMLRoles(obj)
+
+    def isDPubAppendix(self, obj):
+        return 'doc-appendix' in self._getXMLRoles(obj)
+
+    def isDPubBacklink(self, obj):
+        return 'doc-backlink' in self._getXMLRoles(obj)
+
+    def isDPubBiblioref(self, obj):
+        return 'doc-biblioref' in self._getXMLRoles(obj)
+
+    def isDPubBibliography(self, obj):
+        return 'doc-bibliography' in self._getXMLRoles(obj)
+
+    def isDPubChapter(self, obj):
+        return 'doc-chapter' in self._getXMLRoles(obj)
+
+    def isDPubColophon(self, obj):
+        return 'doc-colophon' in self._getXMLRoles(obj)
+
+    def isDPubConclusion(self, obj):
+        return 'doc-conclusion' in self._getXMLRoles(obj)
+
+    def isDPubCover(self, obj):
+        return 'doc-cover' in self._getXMLRoles(obj)
+
+    def isDPubCredit(self, obj):
+        return 'doc-credit' in self._getXMLRoles(obj)
+
+    def isDPubCredits(self, obj):
+        return 'doc-credits' in self._getXMLRoles(obj)
+
+    def isDPubDedication(self, obj):
+        return 'doc-dedication' in self._getXMLRoles(obj)
+
+    def isDPubEndnote(self, obj):
+        return 'doc-endnote' in self._getXMLRoles(obj)
+
+    def isDPubEndnotes(self, obj):
+        return 'doc-endnotes' in self._getXMLRoles(obj)
+
+    def isDPubEpigraph(self, obj):
+        return 'doc-epigraph' in self._getXMLRoles(obj)
+
+    def isDPubEpilogue(self, obj):
+        return 'doc-epilogue' in self._getXMLRoles(obj)
+
+    def isDPubErrata(self, obj):
+        return 'doc-errata' in self._getXMLRoles(obj)
+
+    def isDPubExample(self, obj):
+        return 'doc-example' in self._getXMLRoles(obj)
+
+    def isDPubFootnote(self, obj):
+        return 'doc-footnote' in self._getXMLRoles(obj)
+
+    def isDPubForeword(self, obj):
+        return 'doc-foreword' in self._getXMLRoles(obj)
+
+    def isDPubGlossary(self, obj):
+        return 'doc-glossary' in self._getXMLRoles(obj)
+
+    def isDPubGlossref(self, obj):
+        return 'doc-glossref' in self._getXMLRoles(obj)
+
+    def isDPubIndex(self, obj):
+        return 'doc-index' in self._getXMLRoles(obj)
+
+    def isDPubIntroduction(self, obj):
+        return 'doc-introduction' in self._getXMLRoles(obj)
+
+    def isDPubNoteref(self, obj):
+        return 'doc-noteref' in self._getXMLRoles(obj)
+
+    def isDPubPagelist(self, obj):
+        return 'doc-pagelist' in self._getXMLRoles(obj)
+
+    def isDPubPagebreak(self, obj):
+        return 'doc-pagebreak' in self._getXMLRoles(obj)
+
+    def isDPubPart(self, obj):
+        return 'doc-part' in self._getXMLRoles(obj)
+
+    def isDPubPreface(self, obj):
+        return 'doc-preface' in self._getXMLRoles(obj)
+
+    def isDPubPrologue(self, obj):
+        return 'doc-prologue' in self._getXMLRoles(obj)
+
+    def isDPubPullquote(self, obj):
+        return 'doc-pullquote' in self._getXMLRoles(obj)
+
+    def isDPubQna(self, obj):
+        return 'doc-qna' in self._getXMLRoles(obj)
+
+    def isDPubSubtitle(self, obj):
+        return 'doc-subtitle' in self._getXMLRoles(obj)
+
+    def isDPubToc(self, obj):
+        return 'doc-toc' in self._getXMLRoles(obj)
+
     def isLandmark(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 114d17b..eed2462 100644
--- a/src/orca/scripts/web/speech_generator.py
+++ b/src/orca/scripts/web/speech_generator.py
@@ -147,7 +147,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         return []
 
     def _generateLabelOrName(self, obj, **args):
-        if self._script.utilities.isTextBlockElement(obj):
+        if self._script.utilities.isTextBlockElement(obj) \
+           and not self._script.utilities.isLandmark(obj) \
+           and not self._script.utilities.isDPub(obj):
             return []
 
         if self._script.utilities.inDocumentContent(obj) and obj.name:
@@ -159,7 +161,8 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
 
     def _generateName(self, obj, **args):
         if self._script.utilities.isTextBlockElement(obj) \
-           and not self._script.utilities.isLandmark(obj):
+           and not self._script.utilities.isLandmark(obj) \
+           and not self._script.utilities.isDPub(obj):
             return []
 
         # TODO - JD: Once the formatting strings are vastly cleaned up
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index aa17cb6..ee9b33c 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -1489,6 +1489,8 @@ class SpeechGenerator(generator.Generator):
         allRoles = [pyatspi.ROLE_BLOCK_QUOTE,
                     pyatspi.ROLE_FORM,
                     pyatspi.ROLE_LANDMARK,
+                    'ROLE_DPUB_LANDMARK',
+                    'ROLE_DPUB_SECTION',
                     pyatspi.ROLE_LIST,
                     pyatspi.ROLE_PANEL,
                     pyatspi.ROLE_TABLE]
@@ -1498,11 +1500,11 @@ class SpeechGenerator(generator.Generator):
             if _settingsManager.getSetting('sayAllContextBlockquote'):
                 enabled.append(pyatspi.ROLE_BLOCK_QUOTE)
             if _settingsManager.getSetting('sayAllContextLandmark'):
-                enabled.append(pyatspi.ROLE_LANDMARK)
+                enabled.extend([pyatspi.ROLE_LANDMARK, 'ROLE_DPUB_LANDMARK'])
             if _settingsManager.getSetting('sayAllContextList'):
                 enabled.append(pyatspi.ROLE_LIST)
             if _settingsManager.getSetting('sayAllContextPanel'):
-                enabled.append(pyatspi.ROLE_PANEL)
+                enabled.extend([pyatspi.ROLE_PANEL, 'ROLE_DPUB_SECTION'])
             if _settingsManager.getSetting('sayAllContextNonLandmarkForm'):
                 enabled.append(pyatspi.ROLE_FORM)
             if _settingsManager.getSetting('sayAllContextTable'):
@@ -1511,11 +1513,11 @@ class SpeechGenerator(generator.Generator):
             if _settingsManager.getSetting('speakContextBlockquote'):
                 enabled.append(pyatspi.ROLE_BLOCK_QUOTE)
             if _settingsManager.getSetting('speakContextLandmark'):
-                enabled.append(pyatspi.ROLE_LANDMARK)
+                enabled.extend([pyatspi.ROLE_LANDMARK, 'ROLE_DPUB_LANDMARK'])
             if _settingsManager.getSetting('speakContextList'):
                 enabled.append(pyatspi.ROLE_LIST)
             if _settingsManager.getSetting('speakContextPanel'):
-                enabled.append(pyatspi.ROLE_PANEL)
+                enabled.extend([pyatspi.ROLE_PANEL, 'ROLE_DPUB_SECTION'])
             if _settingsManager.getSetting('speakContextNonLandmarkForm'):
                 enabled.append(pyatspi.ROLE_FORM)
             if _settingsManager.getSetting('speakContextTable'):
@@ -1550,22 +1552,78 @@ class SpeechGenerator(generator.Generator):
             result.append(messages.LEAVING_PANEL)
         elif role == pyatspi.ROLE_TABLE and self._script.utilities.isTextDocumentTable(obj):
             result.append(messages.LEAVING_TABLE)
+        elif role == 'ROLE_DPUB_LANDMARK':
+            if self._script.utilities.isDPubAcknowledgments(obj):
+                result.append(messages.LEAVING_ACKNOWLEDGMENTS)
+            elif self._script.utilities.isDPubAfterword(obj):
+                result.append(messages.LEAVING_AFTERWORD)
+            elif self._script.utilities.isDPubAppendix(obj):
+                result.append(messages.LEAVING_APPENDIX)
+            elif self._script.utilities.isDPubBibliography(obj):
+                result.append(messages.LEAVING_BIBLIOGRAPHY)
+            elif self._script.utilities.isDPubChapter(obj):
+                result.append(messages.LEAVING_CHAPTER)
+            elif self._script.utilities.isDPubConclusion(obj):
+                result.append(messages.LEAVING_CONCLUSION)
+            elif self._script.utilities.isDPubCredits(obj):
+                result.append(messages.LEAVING_CREDITS)
+            elif self._script.utilities.isDPubEndnotes(obj):
+                result.append(messages.LEAVING_ENDNOTES)
+            elif self._script.utilities.isDPubEpilogue(obj):
+                result.append(messages.LEAVING_EPILOGUE)
+            elif self._script.utilities.isDPubErrata(obj):
+                result.append(messages.LEAVING_ERRATA)
+            elif self._script.utilities.isDPubForeword(obj):
+                result.append(messages.LEAVING_FOREWORD)
+            elif self._script.utilities.isDPubGlossary(obj):
+                result.append(messages.LEAVING_GLOSSARY)
+            elif self._script.utilities.isDPubIndex(obj):
+                result.append(messages.LEAVING_INDEX)
+            elif self._script.utilities.isDPubIntroduction(obj):
+                result.append(messages.LEAVING_INTRODUCTION)
+            elif self._script.utilities.isDPubPagelist(obj):
+                result.append(messages.LEAVING_PAGELIST)
+            elif self._script.utilities.isDPubPart(obj):
+                result.append(messages.LEAVING_PART)
+            elif self._script.utilities.isDPubPreface(obj):
+                result.append(messages.LEAVING_PREFACE)
+            elif self._script.utilities.isDPubPrologue(obj):
+                result.append(messages.LEAVING_PROLOGUE)
+            elif self._script.utilities.isDPubToc(obj):
+                result.append(messages.LEAVING_TOC)
+        elif role == 'ROLE_DPUB_SECTION':
+            if self._script.utilities.isDPubAbstract(obj):
+                result.append(messages.LEAVING_ABSTRACT)
+            elif self._script.utilities.isDPubColophon(obj):
+                result.append(messages.LEAVING_COLOPHON)
+            elif self._script.utilities.isDPubCredit(obj):
+                result.append(messages.LEAVING_CREDIT)
+            elif self._script.utilities.isDPubDedication(obj):
+                result.append(messages.LEAVING_DEDICATION)
+            elif self._script.utilities.isDPubEpigraph(obj):
+                result.append(messages.LEAVING_EPIGRAPH)
+            elif self._script.utilities.isDPubExample(obj):
+                result.append(messages.LEAVING_EXAMPLE)
+            elif self._script.utilities.isDPubPullquote(obj):
+                result.append(messages.LEAVING_PULLQUOTE)
+            elif self._script.utilities.isDPubQna(obj):
+                result.append(messages.LEAVING_QNA)
         elif self._script.utilities.isLandmark(obj):
             if self._script.utilities.isLandmarkBanner(obj):
                 result.append(messages.LEAVING_LANDMARK_BANNER)
-            if self._script.utilities.isLandmarkComplementary(obj):
+            elif self._script.utilities.isLandmarkComplementary(obj):
                 result.append(messages.LEAVING_LANDMARK_COMPLEMENTARY)
-            if self._script.utilities.isLandmarkContentInfo(obj):
+            elif self._script.utilities.isLandmarkContentInfo(obj):
                 result.append(messages.LEAVING_LANDMARK_CONTENTINFO)
-            if self._script.utilities.isLandmarkMain(obj):
+            elif self._script.utilities.isLandmarkMain(obj):
                 result.append(messages.LEAVING_LANDMARK_MAIN)
-            if self._script.utilities.isLandmarkNavigation(obj):
+            elif self._script.utilities.isLandmarkNavigation(obj):
                 result.append(messages.LEAVING_LANDMARK_NAVIGATION)
-            if self._script.utilities.isLandmarkRegion(obj):
+            elif self._script.utilities.isLandmarkRegion(obj):
                 result.append(messages.LEAVING_LANDMARK_REGION)
-            if self._script.utilities.isLandmarkSearch(obj):
+            elif self._script.utilities.isLandmarkSearch(obj):
                 result.append(messages.LEAVING_LANDMARK_SEARCH)
-            if self._script.utilities.isLandmarkForm(obj):
+            elif self._script.utilities.isLandmarkForm(obj):
                 result.append(messages.LEAVING_FORM)
         elif role == pyatspi.ROLE_FORM:
             result.append(messages.LEAVING_FORM)
@@ -1692,6 +1750,8 @@ class SpeechGenerator(generator.Generator):
         args['includeOnly'] = [pyatspi.ROLE_BLOCK_QUOTE,
                                pyatspi.ROLE_FORM,
                                pyatspi.ROLE_LANDMARK,
+                               'ROLE_DPUB_LANDMARK',
+                               'ROLE_DPUB_SECTION',
                                pyatspi.ROLE_LIST,
                                pyatspi.ROLE_PANEL,
                                pyatspi.ROLE_TABLE]



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]