Index: src/orca/Gecko.py
===================================================================
--- src/orca/Gecko.py	(revision 2589)
+++ src/orca/Gecko.py	(working copy)
@@ -2053,6 +2053,8 @@
             self.onDocumentLoadStopped
         listeners["object:visible-data-changed"]            = \
             self.onVisibleDataChanged
+        listeners["object:children-changed:"]               = \
+            self.onChildrenChanged
 
         # [[[TODO: HACK - WDW we need to accomodate Gecko's incorrect
         # use of underscores instead of dashes until they fix their bug.
@@ -3663,7 +3665,38 @@
             self.updateBraille(obj)
             self.speakContents(
                 self.getLineContentsAtOffset(obj, characterOffset))
-
+                
+    def onChildrenChanged(self, event):
+        """Called when a child node has changed.  In particular, we are looking
+        for addition events often associated with Javascipt insertion.  One such
+        such example would be the programmatic insertion of a tooltip or alert  
+        dialog."""
+        
+        # We will just look at object addition events for now
+        if event.type == 'object:children-changed:add':
+            
+            # create the child that changed.  Could put this logic in
+            # Event.__init__ if need be.
+            newacc = atspi.Accessible.makeAccessible(event.any_data.value())
+            
+            # The addition could be an alert/tooltip, but the wairole:alert
+            # or wairole:tooltip object may be a child.  For performance
+            # reasons we'll just look through this objects immediate 
+            # descendents, not recursively.  May need to check xml-roles
+            # to make sure it is not a wairole:list or other roles with 
+            # potentially many children.
+            if self.isAriaAlert(newacc):
+                output = self.expandEOCs(newacc)
+                speech.speak(output)
+                braille.displayMessage(output)
+            else:
+                for index in xrange(newacc.childCount):
+                    child = newacc.child(index)
+                    if self.isAriaAlert(child):
+                        output = self.expandEOCs(child)
+                        speech.speak(output)
+                        braille.displayMessage(output)
+    
     def handleProgressBarUpdate(self, event, obj):
         """Determine whether this progress bar event should be spoken or not.
         For Firefox, we don't want to speak the small "page load" progress
@@ -4416,17 +4449,6 @@
 
         return False
             
-    def isAriaWidget(self, obj=None):
-        obj = obj or orca_state.locusOfFocus
-        
-        attrs = obj.attributes
-        if attrs is None:
-            return False
-        for attr in attrs:
-            if attr.startswith('xml-roles'):
-                return True
-        return False
-
     def getCharacterOffsetInParent(self, obj):
         """Returns the character offset of the embedded object
         character for this object in its parent's accessible text.
@@ -5000,6 +5022,27 @@
 
         else:
             return default.Script.isLayoutOnly(self, obj)
+        
+    def isAriaWidget(self, obj=None):
+        """Returns True if the given object is an ARIA widget."""
+        obj = obj or orca_state.locusOfFocus
+        
+        attrs = obj.attributes
+        if attrs is None:
+            return False
+        for attr in attrs:
+            if attr.startswith('xml-roles'):
+                return True
+        return False
+        
+    def isAriaAlert(self, obj):
+        """Returns True if the given object is an ARIA wairole:alert or 
+           wairole:tooltip.
+        """
+        for attr in obj.attributes:
+            if attr == 'xml-roles:wairole:alert' or attr == 'xml-roles:wairole:tooltip':
+                return True
+        return False
 
     def pursueForFlatReview(self, obj):
         """Determines if we should look any further at the object
