Bug 461212 - deCOM frame traversal (relanding) r=mats.palmgren sr=roc
authorBenjamin Smedberg <benjamin@smedbergs.us>
Thu, 30 Oct 2008 10:15:22 -0700
changeset 21105 307153dd899d099f18deb765e8795daabd323e52
parent 21104 9a5f7f7d0141bbb004d74caae959b1c49d4bbd86
child 21106 6fd85628b1dc1f1c4a7c95fc522d21f90861a426
push idunknown
push userunknown
push dateunknown
reviewersmats.palmgren, roc
bugs461212
milestone1.9.1b2pre
Bug 461212 - deCOM frame traversal (relanding) r=mats.palmgren sr=roc
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<nsIBidirectionalEnumerator> frameTraversal;
+  nsCOMPtr<nsIFrameEnumerator> 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,41 +4376,42 @@ nsEventStateManager::GetNextTabbableCont
                                 mPresContext, aStartFrame,
                                 ePreOrder,
                                 PR_FALSE, // aVisual
                                 PR_FALSE, // aLockInScrollView
                                 PR_TRUE   // aFollowOOFs
                                 );
     NS_ENSURE_SUCCESS(rv, rv);
     if (!forward) {
-      rv = frameTraversal->Last();
+      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.
-      rv = forward ? frameTraversal->Next() : frameTraversal->Prev();
+      if (forward)
+        frameTraversal->Next();
+      else
+        frameTraversal->Prev();
     }
   }
 
   // -- Walk frames to find something tabbable matching mCurrentTabIndex --
-  while (NS_SUCCEEDED(rv)) {
-    nsISupports* currentItem;
-    frameTraversal->CurrentItem(&currentItem);
-    *aResultFrame = (nsIFrame*)currentItem;
+  while (1) {
+    *aResultFrame = frameTraversal->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:
@@ -4432,17 +4433,20 @@ nsEventStateManager::GetNextTabbableCont
         }
       }
       else if ((aIgnoreTabIndex || mCurrentTabIndex == tabIndex) &&
           currentContent != aStartContent) {
         NS_ADDREF(*aResultNode = currentContent);
         return NS_OK;
       }
     }
-    rv = forward ? frameTraversal->Next() : frameTraversal->Prev();
+    if (forward)
+      frameTraversal->Next();
+    else
+      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;
@@ -5539,17 +5543,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<nsIBidirectionalEnumerator> frameTraversal;
+          nsCOMPtr<nsIFrameEnumerator> frameTraversal;
 
           nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,
                                                              &rv));
           NS_ENSURE_SUCCESS(rv, rv);
 
           rv = trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
                                        mPresContext, startFrame,
                                        eLeaf,
@@ -5561,19 +5565,18 @@ 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();
-            nsISupports* currentItem;
-            frameTraversal->CurrentItem(&currentItem);
-            if (nsnull == (newCaretFrame = static_cast<nsIFrame*>(currentItem))) {
+            newCaretFrame = frameTraversal->CurrentItem();
+            if (nsnull == newCaretFrame) {
               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,32 +37,28 @@
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
 
 #include "nsFrameTraversal.h"
 #include "nsFrameList.h"
 #include "nsPlaceholderFrame.h"
 
 
-class nsFrameIterator: public nsIBidirectionalEnumerator
+class nsFrameIterator : public nsIFrameEnumerator
 {
 public:
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD First();
-
-  NS_IMETHOD Last();
-  
-  NS_IMETHOD Next();
+  virtual void First();
+  virtual void Next();
+  virtual nsIFrame* CurrentItem();
+  virtual PRBool IsDone();
 
-  NS_IMETHOD Prev();
-
-  NS_IMETHOD CurrentItem(nsISupports **aItem);
-
-  NS_IMETHOD IsDone();//what does this mean??off edge? yes
+  virtual void Last();
+  virtual void Prev();
 
   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;}
@@ -160,69 +156,69 @@ nsresult NS_CreateFrameTraversal(nsIFram
 
   *aResult = t;
   NS_ADDREF(*aResult);
 
   return NS_OK;
 }
 
 nsresult
-NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
+NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                      nsPresContext* aPresContext,
                      nsIFrame *aStart,
                      nsIteratorType aType,
                      PRBool aVisual,
                      PRBool aLockInScrollView,
                      PRBool aFollowOOFs)
 {
   if (!aEnumerator || !aStart)
     return NS_ERROR_NULL_POINTER;
-  nsFrameIterator *trav;
+  nsCOMPtr<nsIFrameEnumerator> 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 = static_cast<nsIBidirectionalEnumerator*>(trav);
+  *aEnumerator = trav;
   NS_ADDREF(trav);
   return NS_OK;
 }
 
 
 nsFrameTraversal::nsFrameTraversal()
 {
 }
 
 nsFrameTraversal::~nsFrameTraversal()
 {
 }
 
 NS_IMPL_ISUPPORTS1(nsFrameTraversal,nsIFrameTraversal)
 
 NS_IMETHODIMP 
- nsFrameTraversal::NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
+ nsFrameTraversal::NewFrameTraversal(nsIFrameEnumerator **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_ISUPPORTS2(nsFrameIterator, nsIEnumerator, nsIBidirectionalEnumerator)
+NS_IMPL_ISUPPORTS1(nsFrameIterator, nsIFrameEnumerator)
 
 nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
                                  nsIteratorType aType, PRBool aLockInScrollView,
                                  PRBool aFollowOOFs)
 {
   mOffEdge = 0;
   mPresContext = aPresContext;
   if (aFollowOOFs && aStart)
@@ -232,55 +228,48 @@ nsFrameIterator::nsFrameIterator(nsPresC
   setLast(aStart);
   mType = aType;
   SetLockInScrollView(aLockInScrollView);
   mFollowOOFs = aFollowOOFs;
 }
 
 
 
-NS_IMETHODIMP
-nsFrameIterator::CurrentItem(nsISupports **aItem)
+nsIFrame*
+nsFrameIterator::CurrentItem()
 {
-  if (!aItem)
-    return NS_ERROR_NULL_POINTER;
-  *aItem = mCurrent;
   if (mOffEdge)
-    return NS_ENUMERATOR_FALSE;
-  return NS_OK;
+    return nsnull;
+
+  return mCurrent;
 }
 
 
 
-NS_IMETHODIMP
-nsFrameIterator::IsDone()//what does this mean??off edge? yes
+PRBool
+nsFrameIterator::IsDone()
 {
-  if (mOffEdge != 0)
-    return NS_OK;
-  return NS_ENUMERATOR_FALSE;
+  return mOffEdge != 0;
 }
 
-
-
-NS_IMETHODIMP
+void
 nsFrameIterator::First()
 {
   mCurrent = mStart;
-  return NS_OK;
 }
 
 static PRBool
 IsRootFrame(nsIFrame* aFrame)
 {
   nsIAtom* atom = aFrame->GetType();
   return (atom == nsGkAtoms::canvasFrame) ||
          (atom == nsGkAtoms::rootFrame);
 }
 
-NS_IMETHODIMP
+void
 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)))
@@ -289,20 +278,19 @@ nsFrameIterator::Last()
 
   while ((result = GetLastChild(parent))) {
     parent = result;
   }
   
   setCurrent(parent);
   if (!parent)
     setOffEdge(1);
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 nsFrameIterator::Next()
 {
   // recursive-oid method to get next frame
   nsIFrame *result = nsnull;
   nsIFrame *parent = getCurrent();
   if (!parent)
     parent = getLast();
 
@@ -346,20 +334,19 @@ nsFrameIterator::Next()
     }
   }
 
   setCurrent(result);
   if (!result) {
     setOffEdge(1);
     setLast(parent);
   }
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 nsFrameIterator::Prev()
 {
   // recursive-oid method to get prev frame
   nsIFrame *result = nsnull;
   nsIFrame *parent = getCurrent();
   if (!parent)
     parent = getLast();
 
@@ -402,17 +389,16 @@ 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,21 +32,20 @@
  * 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(nsIBidirectionalEnumerator **aEnumerator,
+nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                               nsPresContext* aPresContext,
                               nsIFrame *aStart,
                               nsIteratorType aType,
                               PRBool aVisual,
                               PRBool aLockInScrollView,
                               PRBool aFollowOOFs);
 
 nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
@@ -54,17 +53,17 @@ nsresult NS_CreateFrameTraversal(nsIFram
 class nsFrameTraversal : public nsIFrameTraversal
 {
 public:
   nsFrameTraversal();
   virtual ~nsFrameTraversal();
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
+  NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                                nsPresContext* aPresContext,
                                nsIFrame *aStart,
                                PRInt32 aType,
                                PRBool aVisual,
                                PRBool aLockInScrollView,
                                PRBool aFollowOOFs);
 };
 
--- a/layout/base/nsIFrameTraversal.h
+++ b/layout/base/nsIFrameTraversal.h
@@ -33,19 +33,38 @@
  * 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 \
@@ -66,17 +85,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(nsIBidirectionalEnumerator **aEnumerator,
+  NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                                nsPresContext* aPresContext,
                                nsIFrame *aStart,
                                PRInt32 aType,
                                PRBool aVisual,
                                PRBool aLockInScrollView,
                                PRBool aFollowOOFs) = 0;
 };
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4624,27 +4624,26 @@ 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<nsIBidirectionalEnumerator> frameTraversal;
+      nsCOMPtr<nsIFrameEnumerator> 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
@@ -4712,24 +4711,20 @@ 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
-        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;
+        frameTraversal->Prev();
+        resultFrame = frameTraversal->CurrentItem();
+        if (!resultFrame)
+          return NS_ERROR_FAILURE;
       }
 
       if (!found){
         resultFrame = storeOldResultFrame;
         result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
                                       aPresContext, resultFrame,
                                       eLeaf,
                                       PR_FALSE, // aVisual
@@ -4761,24 +4756,21 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
             break;
           }
         }
         if (aPos->mDirection == eDirPrevious && (resultFrame == nearStoppingFrame))
           break;
         if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame))
           break;
         //previous didnt work now we try "next"
-        result = frameTraversal->Next();
-        if (NS_FAILED(result))
+        frameTraversal->Next();
+        nsIFrame *tempFrame = frameTraversal->CurrentItem();
+        if (!tempFrame)
           break;
-        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;
+        resultFrame = tempFrame;
       }
       aPos->mResultFrame = resultFrame;
     }
     else {
         //we need to jump to new block frame.
       aPos->mAmount = eSelectLine;
       aPos->mStartOffset = 0;
       aPos->mAttachForward = !(aPos->mDirection == eDirNext);
@@ -5455,43 +5447,35 @@ nsIFrame::GetFrameFromDirection(nsDirect
     }
 
     if (atLineEdge) {
       *aOutJumpedLine = PR_TRUE;
       if (!aJumpLines)
         return NS_ERROR_FAILURE; //we are done. cannot jump lines
     }
 
-    nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
+    nsCOMPtr<nsIFrameEnumerator> 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)
-      result = frameTraversal->Next();
+      frameTraversal->Next();
     else
-      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;
+      frameTraversal->Prev();
+
+    traversedFrame = frameTraversal->CurrentItem();
+    if (!traversedFrame)
+      return NS_ERROR_FAILURE;
     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,50 +1578,42 @@ nsFrameSelection::GetFrameFromLevel(nsIF
                                     nsDirection  aDirection,
                                     PRUint8      aBidiLevel,
                                     nsIFrame   **aFrameOut) const
 {
   NS_ENSURE_STATE(mShell);
   PRUint8 foundLevel = 0;
   nsIFrame *foundFrame = aFrameIn;
 
-  nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
+  nsCOMPtr<nsIFrameEnumerator> 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)
-      result = frameTraversal->Next();
+      frameTraversal->Next();
     else 
-      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;
+      frameTraversal->Prev();
+
+    foundFrame = frameTraversal->CurrentItem();
+    if (!foundFrame)
+      return NS_ERROR_FAILURE;
     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,35 +1170,33 @@ 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<nsIBidirectionalEnumerator> frameTraversal;
+  nsCOMPtr<nsIFrameEnumerator> 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();
-    nsISupports* currentItem;
-    frameTraversal->CurrentItem(&currentItem);
-    frame = static_cast<nsIFrame*>(currentItem);
+    frame = frameTraversal->CurrentItem();
     if (!frame)
       return PR_FALSE;
 
     nsRect relFrameRect = frame->GetRect();
     frame->GetOffsetFromView(frameOffset, &containingView);
     if (containingView) {
       relFrameRect.x = frameOffset.x;
       relFrameRect.y = frameOffset.y;