Backed out changeset affcc1c08bc0 (deCOM frame enumerator) due to regression from it or bug 461410.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Tue, 28 Oct 2008 02:47:40 -0400
changeset 20993 6db7098c04e46b24fc7731203602e19a3921c588
parent 20987 affcc1c08bc0659efcc34c62edf3e1424b80a7dc
child 20996 abb870420290eeb66107b53f73cfa35ae8a3a419
push idunknown
push userunknown
push dateunknown
bugs461410
milestone1.9.1b2pre
backs outaffcc1c08bc0659efcc34c62edf3e1424b80a7dc
Backed out changeset affcc1c08bc0 (deCOM frame enumerator) due to regression from it or bug 461410.
content/events/src/nsEventStateManager.cpp
layout/base/nsFrameTraversal.cpp
layout/base/nsFrameTraversal.h
layout/base/nsIFrameTraversal.h
layout/generic/nsFrame.cpp
layout/generic/nsSelection.cpp
toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -4357,17 +4357,17 @@ nsEventStateManager::GetNextTabbableCont
                                             nsIFrame** aResultFrame)
 {
   *aResultNode = nsnull;
   *aResultFrame = nsnull;
 
   nsresult rv;
   nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+  nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
 
   // --- Get frame to start with ---
   if (!aStartFrame) {
     // No frame means we need to start with the root content again.
     NS_ENSURE_TRUE(mPresContext, NS_ERROR_FAILURE);
     nsIPresShell *presShell = mPresContext->GetPresShell();
     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
     aStartFrame = presShell->GetPrimaryFrameFor(aRootContent);
@@ -4376,42 +4376,41 @@ nsEventStateManager::GetNextTabbableCont
                                 mPresContext, aStartFrame,
                                 ePreOrder,
                                 PR_FALSE, // aVisual
                                 PR_FALSE, // aLockInScrollView
                                 PR_TRUE   // aFollowOOFs
                                 );
     NS_ENSURE_SUCCESS(rv, rv);
     if (!forward) {
-      frameTraversal->Last();
+      rv = frameTraversal->Last();
     }
   }
   else {
     rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
                                  mPresContext, aStartFrame,
                                  ePreOrder,
                                  PR_FALSE, // aVisual
                                  PR_FALSE, // aLockInScrollView
                                  PR_TRUE   // aFollowOOFs
                                  );
     NS_ENSURE_SUCCESS(rv, rv);
     if (!aStartContent || aStartContent->Tag() != nsGkAtoms::area ||
         !aStartContent->IsNodeOfType(nsINode::eHTML)) {
       // Need to do special check in case we're in an imagemap which has multiple
       // content per frame, so don't skip over the starting frame.
-      if (forward)
-        frameTraversal->Next();
-      else
-        frameTraversal->Prev();
+      rv = forward ? frameTraversal->Next() : frameTraversal->Prev();
     }
   }
 
   // -- Walk frames to find something tabbable matching mCurrentTabIndex --
-  while (1) {
-    *aResultFrame = frameTraversal->CurrentItem();
+  while (NS_SUCCEEDED(rv)) {
+    nsISupports* currentItem;
+    frameTraversal->CurrentItem(&currentItem);
+    *aResultFrame = (nsIFrame*)currentItem;
     if (!*aResultFrame) {
       break;
     }
 
     // TabIndex not set defaults to 0 for form elements, anchors and other
     // elements that are normally focusable. Tabindex defaults to -1
     // for elements that are not normally focusable.
     // The returned computed tabindex from IsFocusable() is as follows:
@@ -4433,20 +4432,17 @@ nsEventStateManager::GetNextTabbableCont
         }
       }
       else if ((aIgnoreTabIndex || mCurrentTabIndex == tabIndex) &&
           currentContent != aStartContent) {
         NS_ADDREF(*aResultNode = currentContent);
         return NS_OK;
       }
     }
-    if (forward)
-      frameTraversal->Next();
-    else
-      frameTraversal->Prev();
+    rv = forward ? frameTraversal->Next() : frameTraversal->Prev();
   }
 
   // -- Reached end or beginning of document --
 
   // If already at lowest priority tab (0), end search completely.
   // A bit counterintuitive but true, tabindex order goes 1, 2, ... 32767, 0
   if (mCurrentTabIndex == (forward? 0: 1)) {
     return NS_OK;
@@ -5543,17 +5539,17 @@ nsEventStateManager::GetDocSelectionLoca
         domNode->GetNodeValue(nodeValue);
 
         PRBool isFormControl =
           startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL);
 
         if (nodeValue.Length() == *aStartOffset && !isFormControl &&
             startContent != mDocument->GetRootContent()) {
           // Yes, indeed we were at the end of the last node
-          nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+          nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
 
           nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,
                                                              &rv));
           NS_ENSURE_SUCCESS(rv, rv);
 
           rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
                                        mPresContext, startFrame,
                                        eLeaf,
@@ -5565,18 +5561,19 @@ nsEventStateManager::GetDocSelectionLoca
 
           nsIFrame *newCaretFrame = nsnull;
           nsCOMPtr<nsIContent> newCaretContent = startContent;
           PRBool endOfSelectionInStartNode(startContent == endContent);
           do {
             // Continue getting the next frame until the primary content for the frame
             // we are on changes - we don't want to be stuck in the same place
             frameTraversal->Next();
-            newCaretFrame = frameTraversal->CurrentItem();
-            if (nsnull == newCaretFrame) {
+            nsISupports* currentItem;
+            frameTraversal->CurrentItem(&currentItem);
+            if (nsnull == (newCaretFrame = static_cast<nsIFrame*>(currentItem))) {
               break;
             }
             newCaretContent = newCaretFrame->GetContent();            
           } while (!newCaretContent || newCaretContent == startContent);
 
           if (newCaretFrame && newCaretContent) {
             // If the caret is exactly at the same position of the new frame,
             // then we can use the newCaretFrame and newCaretContent for our position
--- a/layout/base/nsFrameTraversal.cpp
+++ b/layout/base/nsFrameTraversal.cpp
@@ -37,28 +37,32 @@
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
 
 #include "nsFrameTraversal.h"
 #include "nsFrameList.h"
 #include "nsPlaceholderFrame.h"
 
 
-class nsFrameIterator : public nsIFrameEnumerator
+class nsFrameIterator: public nsIBidirectionalEnumerator
 {
 public:
   NS_DECL_ISUPPORTS
 
-  virtual void First();
-  virtual void Next();
-  virtual nsIFrame* CurrentItem();
-  virtual PRBool IsDone();
+  NS_IMETHOD First();
+
+  NS_IMETHOD Last();
+  
+  NS_IMETHOD Next();
 
-  virtual void Last();
-  virtual void Prev();
+  NS_IMETHOD Prev();
+
+  NS_IMETHOD CurrentItem(nsISupports **aItem);
+
+  NS_IMETHOD IsDone();//what does this mean??off edge? yes
 
   nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
                   nsIteratorType aType, PRBool aLockScroll, PRBool aFollowOOFs);
 
 protected:
   void      setCurrent(nsIFrame *aFrame){mCurrent = aFrame;}
   nsIFrame *getCurrent(){return mCurrent;}
   void      setStart(nsIFrame *aFrame){mStart = aFrame;}
@@ -156,69 +160,69 @@ nsresult NS_CreateFrameTraversal(nsIFram
 
   *aResult = t;
   NS_ADDREF(*aResult);
 
   return NS_OK;
 }
 
 nsresult
-NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
+NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
                      nsPresContext* aPresContext,
                      nsIFrame *aStart,
                      nsIteratorType aType,
                      PRBool aVisual,
                      PRBool aLockInScrollView,
                      PRBool aFollowOOFs)
 {
   if (!aEnumerator || !aStart)
     return NS_ERROR_NULL_POINTER;
-  nsCOMPtr<nsIFrameIterator> trav;
+  nsFrameIterator *trav;
   if (aVisual) {
     trav = new nsVisualIterator(aPresContext, aStart, aType,
                                 aLockInScrollView, aFollowOOFs);
   } else {
     trav = new nsFrameIterator(aPresContext, aStart, aType,
                                aLockInScrollView, aFollowOOFs);
   }
   if (!trav)
     return NS_ERROR_OUT_OF_MEMORY;
-  *aEnumerator = trav;
+  *aEnumerator = static_cast<nsIBidirectionalEnumerator*>(trav);
   NS_ADDREF(trav);
   return NS_OK;
 }
 
 
 nsFrameTraversal::nsFrameTraversal()
 {
 }
 
 nsFrameTraversal::~nsFrameTraversal()
 {
 }
 
 NS_IMPL_ISUPPORTS1(nsFrameTraversal,nsIFrameTraversal)
 
 NS_IMETHODIMP 
- nsFrameTraversal::NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
+ nsFrameTraversal::NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
                                      nsPresContext* aPresContext,
                                      nsIFrame *aStart,
                                      PRInt32 aType,
                                      PRBool aVisual,
                                      PRBool aLockInScrollView,
                                      PRBool aFollowOOFs)
 {
   return NS_NewFrameTraversal(aEnumerator, aPresContext, aStart,
                               static_cast<nsIteratorType>(aType),
                               aVisual, aLockInScrollView, aFollowOOFs);  
 }
 
 // nsFrameIterator implementation
 
-NS_IMPL_ISUPPORTS1(nsFrameIterator, nsIFrameEnumerator)
+NS_IMPL_ISUPPORTS2(nsFrameIterator, nsIEnumerator, nsIBidirectionalEnumerator)
 
 nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
                                  nsIteratorType aType, PRBool aLockInScrollView,
                                  PRBool aFollowOOFs)
 {
   mOffEdge = 0;
   mPresContext = aPresContext;
   if (aFollowOOFs && aStart)
@@ -228,48 +232,55 @@ nsFrameIterator::nsFrameIterator(nsPresC
   setLast(aStart);
   mType = aType;
   SetLockInScrollView(aLockInScrollView);
   mFollowOOFs = aFollowOOFs;
 }
 
 
 
-nsIFrame*
-nsFrameIterator::CurrentItem()
+NS_IMETHODIMP
+nsFrameIterator::CurrentItem(nsISupports **aItem)
 {
+  if (!aItem)
+    return NS_ERROR_NULL_POINTER;
+  *aItem = mCurrent;
   if (mOffEdge)
-    return nsnull;
-
-  return mCurrent;
+    return NS_ENUMERATOR_FALSE;
+  return NS_OK;
 }
 
 
 
-PRBool
-nsFrameIterator::IsDone()
+NS_IMETHODIMP
+nsFrameIterator::IsDone()//what does this mean??off edge? yes
 {
-  return mOffEdge != 0;
+  if (mOffEdge != 0)
+    return NS_OK;
+  return NS_ENUMERATOR_FALSE;
 }
 
-void
+
+
+NS_IMETHODIMP
 nsFrameIterator::First()
 {
   mCurrent = mStart;
+  return NS_OK;
 }
 
 static PRBool
 IsRootFrame(nsIFrame* aFrame)
 {
   nsIAtom* atom = aFrame->GetType();
   return (atom == nsGkAtoms::canvasFrame) ||
          (atom == nsGkAtoms::rootFrame);
 }
 
-void
+NS_IMETHODIMP
 nsFrameIterator::Last()
 {
   nsIFrame* result;
   nsIFrame* parent = getCurrent();
   // If the current frame is a popup, don't move farther up the tree.
   // Otherwise, get the nearest root frame or popup.
   if (parent->GetType() != nsGkAtoms::menuPopupFrame) {
     while (!IsRootFrame(parent) && (result = GetParentFrameNotPopup(parent)))
@@ -278,19 +289,20 @@ nsFrameIterator::Last()
 
   while ((result = GetLastChild(parent))) {
     parent = result;
   }
   
   setCurrent(parent);
   if (!parent)
     setOffEdge(1);
+  return NS_OK;
 }
 
-void
+NS_IMETHODIMP
 nsFrameIterator::Next()
 {
   // recursive-oid method to get next frame
   nsIFrame *result = nsnull;
   nsIFrame *parent = getCurrent();
   if (!parent)
     parent = getLast();
 
@@ -334,19 +346,20 @@ nsFrameIterator::Next()
     }
   }
 
   setCurrent(result);
   if (!result) {
     setOffEdge(1);
     setLast(parent);
   }
+  return NS_OK;
 }
 
-void
+NS_IMETHODIMP
 nsFrameIterator::Prev()
 {
   // recursive-oid method to get prev frame
   nsIFrame *result = nsnull;
   nsIFrame *parent = getCurrent();
   if (!parent)
     parent = getLast();
 
@@ -389,16 +402,17 @@ nsFrameIterator::Prev()
     }
   }
 
   setCurrent(result);
   if (!result) {
     setOffEdge(-1);
     setLast(parent);
   }
+  return NS_OK;
 }
 
 nsIFrame*
 nsFrameIterator::GetParentFrame(nsIFrame* aFrame)
 {
   if (mFollowOOFs)
     aFrame = GetPlaceholderFrame(aFrame);
   if (aFrame)
--- a/layout/base/nsFrameTraversal.h
+++ b/layout/base/nsFrameTraversal.h
@@ -32,20 +32,21 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef NSFRAMETRAVERSAL_H
 #define NSFRAMETRAVERSAL_H
 
+#include "nsIEnumerator.h"
 #include "nsIFrame.h"
 #include "nsIFrameTraversal.h"
 
-nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
+nsresult NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
                               nsPresContext* aPresContext,
                               nsIFrame *aStart,
                               nsIteratorType aType,
                               PRBool aVisual,
                               PRBool aLockInScrollView,
                               PRBool aFollowOOFs);
 
 nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
@@ -53,17 +54,17 @@ nsresult NS_CreateFrameTraversal(nsIFram
 class nsFrameTraversal : public nsIFrameTraversal
 {
 public:
   nsFrameTraversal();
   virtual ~nsFrameTraversal();
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
+  NS_IMETHOD NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
                                nsPresContext* aPresContext,
                                nsIFrame *aStart,
                                PRInt32 aType,
                                PRBool aVisual,
                                PRBool aLockInScrollView,
                                PRBool aFollowOOFs);
 };
 
--- a/layout/base/nsIFrameTraversal.h
+++ b/layout/base/nsIFrameTraversal.h
@@ -33,38 +33,19 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef NSIFRAMETRAVERSAL_H
 #define NSIFRAMETRAVERSAL_H
 
 #include "nsISupports.h"
+#include "nsIEnumerator.h"
 #include "nsIFrame.h"
 
-#define NS_IFRAMEENUMERATOR_IID \
-{ 0x7c633f5d, 0x91eb, 0x494e, \
-  { 0xa1, 0x40, 0x17, 0x46, 0x17, 0x4c, 0x23, 0xd3 } }
-
-class nsIFrameEnumerator : public nsISupports
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFRAMEENUMERATOR_IID)
-
-  virtual void First() = 0;
-  virtual void Next() = 0;
-  virtual nsIFrame* CurrentItem() = 0;
-  virtual PRBool IsDone() = 0;
-
-  virtual void Last() = 0;
-  virtual void Prev() = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrameEnumerator, NS_IFRAMEENUMERATOR_IID)
-
 enum nsIteratorType {
   eLeaf,
   ePreOrder,
   ePostOrder
 };
 
 // {9d469828-9bf2-4151-a385-05f30219221b}
 #define NS_IFRAMETRAVERSAL_IID \
@@ -85,17 +66,17 @@ public:
    *        bidi order
    * @param aLockInScrollView [in] whether to stop iterating when exiting a
    *        scroll view
    * @param aFollowOOFs [in] whether the iterator should follow out-of-flows.
    *        If true, when reaching a placeholder frame while going down will get
    *        the real frame. Going back up will go on past the placeholder,
    *        so the placeholders are logically part of the frame tree.
    */
-  NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
+  NS_IMETHOD NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
                                nsPresContext* aPresContext,
                                nsIFrame *aStart,
                                PRInt32 aType,
                                PRBool aVisual,
                                PRBool aLockInScrollView,
                                PRBool aFollowOOFs) = 0;
 };
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4646,26 +4646,27 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
       result = resultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(newIt));
       if (NS_SUCCEEDED(result) && newIt)
       {
         aPos->mResultFrame = resultFrame;
         return NS_OK;
       }
       //resultFrame is not a block frame
 
-      nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+      nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
       result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
                                     aPresContext, resultFrame,
                                     ePostOrder,
                                     PR_FALSE, // aVisual
                                     aPos->mScrollViewStop,
                                     PR_FALSE  // aFollowOOFs
                                     );
       if (NS_FAILED(result))
         return result;
+      nsISupports *isupports = nsnull;
       nsIFrame *storeOldResultFrame = resultFrame;
       while ( !found ){
         nsPoint point;
         point.x = aPos->mDesiredX;
 
         nsRect tempRect = resultFrame->GetRect();
         nsPoint offset;
         nsIView * view; //used for call of get offset from view
@@ -4733,20 +4734,24 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
           }
         }
 
         if (aPos->mDirection == eDirPrevious && (resultFrame == farStoppingFrame))
           break;
         if (aPos->mDirection == eDirNext && (resultFrame == nearStoppingFrame))
           break;
         //always try previous on THAT line if that fails go the other way
-        frameTraversal->Prev();
-        resultFrame = frameTraversal->CurrentItem();
-        if (!resultFrame)
-          return NS_ERROR_FAILURE;
+        result = frameTraversal->Prev();
+        if (NS_FAILED(result))
+          break;
+        result = frameTraversal->CurrentItem(&isupports);
+        if (NS_FAILED(result) || !isupports)
+          return result;
+        //we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
+        resultFrame = (nsIFrame *)isupports;
       }
 
       if (!found){
         resultFrame = storeOldResultFrame;
         result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
                                       aPresContext, resultFrame,
                                       eLeaf,
                                       PR_FALSE, // aVisual
@@ -4778,21 +4783,24 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
             break;
           }
         }
         if (aPos->mDirection == eDirPrevious && (resultFrame == nearStoppingFrame))
           break;
         if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame))
           break;
         //previous didnt work now we try "next"
-        frameTraversal->Next();
-        nsIFrame *tempFrame = frameTraversal->CurrentItem();
-        if (!tempFrame)
+        result = frameTraversal->Next();
+        if (NS_FAILED(result))
           break;
-        resultFrame = tempFrame;
+        result = frameTraversal->CurrentItem(&isupports);
+        if (NS_FAILED(result) || !isupports)
+          break;
+        //we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
+        resultFrame = (nsIFrame *)isupports;
       }
       aPos->mResultFrame = resultFrame;
     }
     else {
         //we need to jump to new block frame.
       aPos->mAmount = eSelectLine;
       aPos->mStartOffset = 0;
       aPos->mAttachForward = !(aPos->mDirection == eDirNext);
@@ -5469,35 +5477,43 @@ nsIFrame::GetFrameFromDirection(nsDirect
     }
 
     if (atLineEdge) {
       *aOutJumpedLine = PR_TRUE;
       if (!aJumpLines)
         return NS_ERROR_FAILURE; //we are done. cannot jump lines
     }
 
-    nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+    nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
     result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
                                   presContext, traversedFrame,
                                   eLeaf,
                                   aVisual && presContext->BidiEnabled(),
                                   aScrollViewStop,
                                   PR_TRUE  // aFollowOOFs
                                   );
     if (NS_FAILED(result))
       return result;
 
     if (aDirection == eDirNext)
-      frameTraversal->Next();
+      result = frameTraversal->Next();
     else
-      frameTraversal->Prev();
-
-    traversedFrame = frameTraversal->CurrentItem();
-    if (!traversedFrame)
-      return NS_ERROR_FAILURE;
+      result = frameTraversal->Prev();
+    if (NS_FAILED(result))
+      return result;
+
+    nsISupports *isupports = nsnull;
+    result = frameTraversal->CurrentItem(&isupports);
+    if (NS_FAILED(result))
+      return result;
+    if (!isupports)
+      return NS_ERROR_NULL_POINTER;
+    //we must CAST here to an nsIFrame. nsIFrame doesn't really follow the rules
+    //for speed reasons
+    traversedFrame = (nsIFrame *)isupports;
     traversedFrame->IsSelectable(&selectable, nsnull);
   } // while (!selectable)
 
   *aOutOffset = (aDirection == eDirNext) ? 0 : -1;
 
 #ifdef IBMBIDI
   if (aVisual) {
     PRUint8 newLevel = NS_GET_EMBEDDING_LEVEL(traversedFrame);
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -1578,42 +1578,50 @@ nsFrameSelection::GetFrameFromLevel(nsIF
                                     nsDirection  aDirection,
                                     PRUint8      aBidiLevel,
                                     nsIFrame   **aFrameOut) const
 {
   NS_ENSURE_STATE(mShell);
   PRUint8 foundLevel = 0;
   nsIFrame *foundFrame = aFrameIn;
 
-  nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+  nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
   nsresult result;
   nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,&result));
   if (NS_FAILED(result))
       return result;
 
   result = trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
                                    mShell->GetPresContext(), aFrameIn,
                                    eLeaf,
                                    PR_FALSE, // aVisual
                                    PR_FALSE, // aLockInScrollView
                                    PR_FALSE  // aFollowOOFs
                                    );
   if (NS_FAILED(result))
     return result;
+  nsISupports *isupports = nsnull;
 
   do {
     *aFrameOut = foundFrame;
     if (aDirection == eDirNext)
-      frameTraversal->Next();
+      result = frameTraversal->Next();
     else 
-      frameTraversal->Prev();
-
-    foundFrame = frameTraversal->CurrentItem();
-    if (!foundFrame)
-      return NS_ERROR_FAILURE;
+      result = frameTraversal->Prev();
+
+    if (NS_FAILED(result))
+      return result;
+    result = frameTraversal->CurrentItem(&isupports);
+    if (NS_FAILED(result))
+      return result;
+    if (!isupports)
+      return NS_ERROR_NULL_POINTER;
+    //we must CAST here to an nsIFrame. nsIFrame doesn't really follow the rules
+    //for speed reasons
+    foundFrame = (nsIFrame *)isupports;
     foundLevel = NS_GET_EMBEDDING_LEVEL(foundFrame);
 
   } while (foundLevel > aBidiLevel);
 
   return NS_OK;
 }
 
 
--- a/toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp
@@ -1170,33 +1170,35 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS
         rectVisibility != nsRectVisibility_kZeroAreaRect) {
       return PR_TRUE;
     }
   }
 
   // We know that the target range isn't usable because it's not in the
   // view port. Move range forward to first visible point,
   // this speeds us up a lot in long documents
-  nsCOMPtr<nsIFrameEnumerator> frameTraversal;
+  nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
   nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID));
   if (trav)
     trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
                             aPresContext, frame,
                             eLeaf,
                             PR_FALSE, // aVisual
                             PR_FALSE, // aLockInScrollView
                             PR_FALSE  // aFollowOOFs
                             );
 
   if (!frameTraversal)
     return PR_FALSE;
 
   while (rectVisibility == nsRectVisibility_kAboveViewport || rectVisibility == nsRectVisibility_kZeroAreaRect) {
     frameTraversal->Next();
-    frame = frameTraversal->CurrentItem();
+    nsISupports* currentItem;
+    frameTraversal->CurrentItem(&currentItem);
+    frame = static_cast<nsIFrame*>(currentItem);
     if (!frame)
       return PR_FALSE;
 
     nsRect relFrameRect = frame->GetRect();
     frame->GetOffsetFromView(frameOffset, &containingView);
     if (containingView) {
       relFrameRect.x = frameOffset.x;
       relFrameRect.y = frameOffset.y;