Index: src/orca/Gecko.py
===================================================================
--- src/orca/Gecko.py	(revision 2370)
+++ src/orca/Gecko.py	(working copy)
@@ -2252,36 +2252,51 @@
 
         default.Script.onTextInserted(self, event)
 
+    def _presentDocumentLoadFinished(self, event):
+        """Informs the user that Firefox has finished loading a web page.
+
+        Arguments:
+        -event: the event that let us know Firefox was done loading a page.
+        """
+
+        if event.source.name:
+            # Translators: this is in reference to loading a web page.
+            #
+            message = _("Finished loading %s.") % event.source.name
+        else:
+            # Translators: this is in reference to loading a web page.
+            #
+            message = _("Finished loading.")
+
+        braille.displayMessage(message)
+        speech.stop()
+        speech.speak(message)
+
     def onDocumentReload(self, event):
         """Called when the reload button is hit for a web page."""
-        self._loadingDocumentContent = True
-        # [[[TODO: WDW - Currently, we handle loading notification by
-        # looking at the state changed events on the document frame
-        # (we care about busy state there) and visibility/value changes
-        # on the progress bar.]]]
+        # We care about the main document and we'll ignore document
+        # events from HTML iframes.
         #
+        if event.source.role == rolenames.ROLE_DOCUMENT_FRAME:
         self._loadingDocumentContent = True
-        pass
 
     def onDocumentLoadComplete(self, event):
         """Called when a web page load is completed."""
-        # [[[TODO: WDW - Currently, we handle loading notification by
-        # looking at the state changed events on the document frame
-        # (we care about busy state there) and visibility/value changes
-        # on the progress bar.]]]
+        # We care about the main document and we'll ignore document
+        # events from HTML iframes.
         #
+        if event.source.role == rolenames.ROLE_DOCUMENT_FRAME:
         self._loadingDocumentContent = False
-        pass
+            self._presentDocumentLoadFinished(event)
 
     def onDocumentLoadStopped(self, event):
         """Called when a web page load is interrupted."""
-        # [[[TODO: WDW - Currently, we handle loading notification by
-        # looking at the state changed events on the document frame
-        # (we care about busy state there) and visibility/value changes
-        # on the progress bar.]]]
+        # We care about the main document and we'll ignore document
+        # events from HTML iframes.
         #
+        if event.source.role == rolenames.ROLE_DOCUMENT_FRAME:
         self._loadingDocumentContent = False
-        pass
+            self._presentDocumentLoadFinished(event)
 
     def onNameChanged(self, event):
         """Called whenever a property on an object changes.
@@ -2444,36 +2459,27 @@
         - event: the Event
         """
 
-        # We care when the document frame changes it's busy state.  That
-        # means it has started/stopped loading content.
+        # We care when the document frame changes its busy state to
+        # busy.  That means it has started loading content.  We do
+        # this because there's no symmetry in the document:* events.
+        # We get busy events to let us know the load has started and
+        # document:* events to let us know the load has completed.
         #
-        if event.type == "object:state-changed:busy":
-            if event.source \
+        if event.detail1 \
+            and event.source \
+            and event.type == "object:state-changed:busy" \
                 and (event.source.role == rolenames.ROLE_DOCUMENT_FRAME):
-                if event.detail1:
+
+            # A detail1=1 means the page has started loading.
+            #
                     self._loadingDocumentContent = True
+
                     # Translators: this is in reference to loading a web page.
                     #
                     message = _("Loading.  Please wait.")
                     braille.displayMessage(message)
                     speech.stop()
                     speech.speak(message)
-                elif event.source.name:
-                    self._loadingDocumentContent = False
-                    # Translators: this is in reference to loading a web page.
-                    #
-                    message = _("Finished loading %s.") % event.source.name
-                    braille.displayMessage(message)
-                    speech.stop()
-                    speech.speak(message)
-                else:
-                    self._loadingDocumentContent = False
-                    # Translators: this is in reference to loading a web page.
-                    #
-                    message = _("Finished loading.")
-                    braille.displayMessage(message)
-                    speech.stop()
-                    speech.speak(message)
             return
 
         default.Script.onStateChanged(self, event)
@@ -2502,6 +2508,12 @@
             #print "    ", documentFrame
             #print "    ", documentFrame.parent
 
+            # If the document frame is busy loading, we won't present
+            # anything to prevent Orca from being too chatty.
+            #
+            if self._loadingDocumentContent:
+                return
+
             braille.displayMessage(documentFrame.name)
             speech.stop()
             speech.speak(
@@ -2597,6 +2609,13 @@
             self.caretContext = self.findFirstCaretContext(newLocusOfFocus,
                                                            caretOffset)
 
+        # We'll ignore focus changes when the document frame is busy.
+        # This will keep Orca from chatting too much while a page is
+        # loading.
+        #
+        if self._loadingDocumentContent:
+            return
+
         # Don't bother speaking all the information about the HTML
         # container - it's duplicated all over the place.  So, we
         # just speak the role.
