Author: shaeger Date: Fri Feb 8 19:33:04 2008 New Revision: 3549 URL: http://svn.gnome.org/viewvc/orca?rev=3549&view=rev
Log: Fixed bug #462883, ARIA tooltips/alerts are not being output Modified: trunk/ChangeLog trunk/src/orca/Gecko.py trunk/src/orca/liveregions.py Modified: trunk/src/orca/Gecko.py ============================================================================== --- trunk/src/orca/Gecko.py (original) +++ trunk/src/orca/Gecko.py Fri Feb 8 19:33:04 2008 @@ -62,6 +62,7 @@ import speech import speechgenerator import speechserver +import time import where_am_I import bookmarks @@ -1911,6 +1912,7 @@ # loading a page. # self._loadingDocumentContent = False + self._loadingDocumentTime = 0.0 # In tabbed content (i.e., Firefox's support for one tab per # URL), we also keep track of the caret context in each tab. @@ -3885,6 +3887,7 @@ # Reset the live region manager. self.liveMngr.reset() self._loadingDocumentContent = False + self._loadingDocumentTime = time.time() def onDocumentLoadStopped(self, event): """Called when a web page load is interrupted.""" @@ -3893,6 +3896,7 @@ # if event.source.getRole() == pyatspi.ROLE_DOCUMENT_FRAME: self._loadingDocumentContent = False + self._loadingDocumentTime = time.time() def onNameChanged(self, event): """Called whenever a property on an object changes. @@ -5222,8 +5226,7 @@ # regions. We will handle everything else as a live region. We # will do the cheap tests first if self._loadingDocumentContent \ - or not settings.inferLiveRegions \ - or not event.type.endswith(':system'): + or not settings.inferLiveRegions: return False # Ideally, we would like to do a inDocumentContent() call to filter out @@ -5233,35 +5236,42 @@ # event.type specific checks if event.type.startswith('object:children-changed'): - # This will filter out lists that are not of interest and - # events from other tabs. - stateset = event.source.getState() - if stateset.contains(pyatspi.STATE_FOCUSABLE) \ - or stateset.contains(pyatspi.STATE_FOCUSED) \ - or not stateset.contains(pyatspi.STATE_VISIBLE): - return False + if event.type.endswith(':system'): + # This will filter out list items that are not of interest and + # events from other tabs. + stateset = event.any_data.getState() + if stateset.contains(pyatspi.STATE_SELECTABLE) \ + or not stateset.contains(pyatspi.STATE_VISIBLE): + return False - # Now we need to look at the object attributes - attrs = self._getAttrDictionary(event.source) - # Good live region markup - if attrs.has_key('container-live'): - return True + # Now we need to look at the object attributes + attrs = self._getAttrDictionary(event.source) + # Good live region markup + if attrs.has_key('container-live'): + return True - # We see this one with the URL bar opening (sometimes) - if attrs.has_key('tag') and attrs['tag'] == 'xul:richlistbox': - return False + # We see this one with the URL bar opening (sometimes) + if attrs.has_key('tag') and attrs['tag'] == 'xul:richlistbox': + return False - # This eliminates all ARIA widgets that are not considered live - if attrs.has_key('xml-roles') \ - and not attrs.has_key('container-live'): - return False + # This eliminates all ARIA widgets that are not considered live + if attrs.has_key('xml-roles') \ + and attrs['xml-roles'] != 'alert': + return False + else: + # Some alerts have been seen without the :system postfix. + # We will take care of them separately. + attrs = self._getAttrDictionary(event.any_data) + if attrs.has_key('xml-roles') \ + and attrs['xml-roles'] != 'alert': + return False - else: # object:text-inserted event + elif event.type.startswith('object:text-changed:insert:system'): # Live regions will not be focusable. # Filter out events from hidden tabs (not VISIBLE) stateset = event.source.getState() if stateset.contains(pyatspi.STATE_FOCUSABLE) \ - or stateset.contains(pyatspi.STATE_FOCUSED) \ + or stateset.contains(pyatspi.STATE_SELECTABLE) \ or not stateset.contains(pyatspi.STATE_VISIBLE): return False @@ -5278,11 +5288,18 @@ return False # This eliminates all ARIA widgets that are not considered live - if attrs.has_key('xml-roles') \ - and not attrs.has_key('container-live'): + if attrs.has_key('xml-roles'): return False - # It sure looks like a live region - return True + else: # object:text-inserted events + return False + + # This last filter gets rid of some events that come in after + # window:activate event. They are usually areas of a page that + # are built dynamically. + if time.time() - self._loadingDocumentTime > 2.0: + return True + else: + return False def getCharacterOffsetInParent(self, obj): """Returns the character offset of the embedded object Modified: trunk/src/orca/liveregions.py ============================================================================== --- trunk/src/orca/liveregions.py (original) +++ trunk/src/orca/liveregions.py Fri Feb 8 19:33:04 2008 @@ -389,21 +389,29 @@ attrs = self._getAttrDictionary(event.source) content = [] labels = [] + + # A message is divided into two parts: labels and content. We + # will first try to get the content. If there is None, + # assume it is an invalid message and return None if event.type.startswith('object:children-changed:add'): - # Get a handle to the Text interface for the target. - try: - targetitext = event.any_data.queryText() - except NotImplementedError: - return None - # Get the text based on the atomic property try: if attrs['container-atomic'] == 'true': - content.append(self._script.expandEOCs(event.source)) + # expand the source if atomic is true + newcontent = self._script.expandEOCs(event.source) else: - content.append(targetitext.getText(0, -1)) + # expand the target if atomic is false + newcontent = self._script.expandEOCs(event.any_data) except (KeyError, TypeError): - content.append(targetitext.getText(0, -1)) + # expand the target if there is no ARIA markup + newcontent = self._script.expandEOCs(event.any_data) + + # add our content to the returned message or return None if no + # content + if newcontent: + content.append(newcontent) + else: + return None else: #object:text-changed:insert # Get a handle to the Text interface for the source. @@ -417,20 +425,27 @@ # We found an embed character. We can expect a children-changed # event, which we will act on, so just return. txt = sourceitext.getText(0, -1) - if txt.find(self._script.EMBEDDED_OBJECT_CHARACTER) == 0: + if txt.count(self._script.EMBEDDED_OBJECT_CHARACTER) > 0: return None - # Get labeling information - labels = self._getLabelsAsUtterances(event.source) - # Get the text based on the atomic property try: if attrs['container-atomic'] == 'true': - content.append(txt) + newcontent = txt else: - content.append(txt[event.detail1:]) + newcontent = txt[event.detail1:event.detail1+event.detail2] except KeyError: - content.append(txt) + newcontent = txt[event.detail1:event.detail1+event.detail2] + + # add our content to the returned message or return None if no + # content + if len(newcontent) > 0: + content.append(newcontent) + else: + return None + + # Get the labeling information now that we have good content. + labels = self._getLabelsAsUtterances(event.source) return {'content':content, 'labels':labels} _______________________________________________ SVN-commits-list mailing list (read only) http://mail.gnome.org/mailman/listinfo/svn-commits-list Want to limit the commits to a few modules? Go to above URL, log in to edit your options and select the modules ('topics') you want. Module maintainer? It is possible to set the reply-to to your development mailing list. Email [EMAIL PROTECTED] if interested.