Index: src/orca/scripts/toolkits/Gecko/script.py
===================================================================
--- src/orca/scripts/toolkits/Gecko/script.py	(revision 3919)
+++ src/orca/scripts/toolkits/Gecko/script.py	(working copy)
@@ -237,6 +237,12 @@
         #
         self._currentFrame = None
 
+        # The last time we had an Orca caret navigation command used that
+        # we should handle (but might have chosen not to in order to allow
+        # the user to rapidly scroll through text.
+        #
+        self._lastCaretNavTime = 0
+
     def getWhereAmI(self):
         """Returns the "where am I" class for this script.
         """
@@ -2041,6 +2047,13 @@
             default.Script.onCaretMoved(self, event)
             return
 
+        if self._lastCaretNavTime:
+            timeDiff = time.time() - self._lastCaretNavTime
+            # print "onCaretMoved: ", timeDiff
+            if timeDiff < 2:
+                self.setCaretContext(event.source, event.detail1)
+                return
+
         text = self.queryNonEmptyText(event.source)
         if text:
             caretOffset = text.caretOffset
@@ -3334,15 +3347,11 @@
         """Returns True if we should do our own caret navigation.
         """
 
-        if not controlCaretNavigation:
+        if not controlCaretNavigation or not self.inDocumentContent() \
+           or not self.isNavigableAria(orca_state.locusOfFocus):
+            self._lastCaretNavTime = 0
             return False
 
-        if not self.inDocumentContent():
-            return False
-
-        if not self.isNavigableAria(orca_state.locusOfFocus):
-            return False
-
         weHandleIt = True
         obj = orca_state.locusOfFocus
         if obj and (obj.getRole() == pyatspi.ROLE_ENTRY):
@@ -3419,6 +3428,24 @@
             #
             weHandleIt = not obj.getState().contains(pyatspi.STATE_FOCUSABLE)
 
+        if weHandleIt:
+            if keyboardEvent.type == pyatspi.KEY_PRESSED_EVENT:
+                timeDiff = time.time() - self._lastCaretNavTime
+                # print "useCaretNavigationModel: ", timeDiff
+                if timeDiff < 0.3:
+                    # We're using our caret navigation model, but the user is
+                    # pressing keys faster than we can generate line contents.
+                    # We'll assume that they're skimming the content and will
+                    # let Firefox's built in caret navigation kick in.
+                    #
+                    weHandleIt = False
+                # Store the time of this valid (intended for us to handle)
+                # event.
+                #
+                self._lastCaretNavTime = time.time()
+        else:
+            self._lastCaretNavTime = 0
+
         return weHandleIt
 
     def useStructuralNavigationModel(self):
@@ -6405,14 +6432,24 @@
 
         return clumped
 
-    def speakContents(self, contents, speakRole=True):
-        """Speaks each string in contents using the associated voice/acss"""
+    def __speakContentsProgressCallback(self, context, progressType):
+        return
+
+    def speakContentsGenerator(self, contents, speakRole=True):
         utterances = self.getUtterancesFromContents(contents, speakRole)
         clumped = self.clumpUtterances(utterances)
-        for [string, acss] in clumped:
+        for i, [string, acss] in enumerate(clumped):
+            [obj, startOffset, endOffset] = contents[min(i, len(contents)-1)]
             string = self.adjustForRepeats(string)
-            speech.speak(string, acss, False)
+            yield [speechserver.SayAllContext(obj, string,
+                                              startOffset, endOffset),
+                   acss]
 
+    def speakContents(self, contents, speakRole=True):
+        """Speaks each string in contents using the associated voice/acss"""
+        speech.sayAll(self.speakContentsGenerator(contents, speakRole),
+                      self.__speakContentsProgressCallback)
+
     def speakCharacterAtOffset(self, obj, characterOffset):
         """Speaks the character at the given characterOffset in the
         given object."""
