Bug 461212 - deCOM frame traversal (relanding) r=mats.palmgren sr=roc

This commit is contained in:
Benjamin Smedberg 2008-10-30 10:15:22 -07:00
Родитель 245dc2f25a
Коммит bb3bf9ec94
7 изменённых файлов: 85 добавлений и 104 удалений

Просмотреть файл

@ -4362,7 +4362,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent,
nsresult rv; nsresult rv;
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID, &rv)); nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID, &rv));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;
// --- Get frame to start with --- // --- Get frame to start with ---
if (!aStartFrame) { if (!aStartFrame) {
@ -4381,7 +4381,7 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent,
); );
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!forward) { if (!forward) {
rv = frameTraversal->Last(); frameTraversal->Last();
} }
} }
else { else {
@ -4397,15 +4397,16 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent,
!aStartContent->IsNodeOfType(nsINode::eHTML)) { !aStartContent->IsNodeOfType(nsINode::eHTML)) {
// Need to do special check in case we're in an imagemap which has multiple // 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. // 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 -- // -- Walk frames to find something tabbable matching mCurrentTabIndex --
while (NS_SUCCEEDED(rv)) { while (1) {
nsISupports* currentItem; *aResultFrame = frameTraversal->CurrentItem();
frameTraversal->CurrentItem(&currentItem);
*aResultFrame = (nsIFrame*)currentItem;
if (!*aResultFrame) { if (!*aResultFrame) {
break; break;
} }
@ -4437,7 +4438,10 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent,
return NS_OK; return NS_OK;
} }
} }
rv = forward ? frameTraversal->Next() : frameTraversal->Prev(); if (forward)
frameTraversal->Next();
else
frameTraversal->Prev();
} }
// -- Reached end or beginning of document -- // -- Reached end or beginning of document --
@ -5544,7 +5548,7 @@ nsEventStateManager::GetDocSelectionLocation(nsIContent **aStartContent,
if (nodeValue.Length() == *aStartOffset && !isFormControl && if (nodeValue.Length() == *aStartOffset && !isFormControl &&
startContent != mDocument->GetRootContent()) { startContent != mDocument->GetRootContent()) {
// Yes, indeed we were at the end of the last node // Yes, indeed we were at the end of the last node
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID, nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,
&rv)); &rv));
@ -5566,9 +5570,8 @@ nsEventStateManager::GetDocSelectionLocation(nsIContent **aStartContent,
// Continue getting the next frame until the primary content for the frame // 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 // we are on changes - we don't want to be stuck in the same place
frameTraversal->Next(); frameTraversal->Next();
nsISupports* currentItem; newCaretFrame = frameTraversal->CurrentItem();
frameTraversal->CurrentItem(&currentItem); if (nsnull == newCaretFrame) {
if (nsnull == (newCaretFrame = static_cast<nsIFrame*>(currentItem))) {
break; break;
} }
newCaretContent = newCaretFrame->GetContent(); newCaretContent = newCaretFrame->GetContent();

Просмотреть файл

@ -42,22 +42,18 @@
#include "nsPlaceholderFrame.h" #include "nsPlaceholderFrame.h"
class nsFrameIterator: public nsIBidirectionalEnumerator class nsFrameIterator : public nsIFrameEnumerator
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_IMETHOD First(); virtual void First();
virtual void Next();
virtual nsIFrame* CurrentItem();
virtual PRBool IsDone();
NS_IMETHOD Last(); virtual void Last();
virtual void Prev();
NS_IMETHOD Next();
NS_IMETHOD Prev();
NS_IMETHOD CurrentItem(nsISupports **aItem);
NS_IMETHOD IsDone();//what does this mean??off edge? yes
nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart, nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
nsIteratorType aType, PRBool aLockScroll, PRBool aFollowOOFs); nsIteratorType aType, PRBool aLockScroll, PRBool aFollowOOFs);
@ -165,7 +161,7 @@ nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult)
} }
nsresult nsresult
NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator, NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsIFrame *aStart, nsIFrame *aStart,
nsIteratorType aType, nsIteratorType aType,
@ -175,7 +171,7 @@ NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
{ {
if (!aEnumerator || !aStart) if (!aEnumerator || !aStart)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
nsFrameIterator *trav; nsCOMPtr<nsIFrameEnumerator> trav;
if (aVisual) { if (aVisual) {
trav = new nsVisualIterator(aPresContext, aStart, aType, trav = new nsVisualIterator(aPresContext, aStart, aType,
aLockInScrollView, aFollowOOFs); aLockInScrollView, aFollowOOFs);
@ -185,7 +181,7 @@ NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
} }
if (!trav) if (!trav)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
*aEnumerator = static_cast<nsIBidirectionalEnumerator*>(trav); *aEnumerator = trav;
NS_ADDREF(trav); NS_ADDREF(trav);
return NS_OK; return NS_OK;
} }
@ -202,7 +198,7 @@ nsFrameTraversal::~nsFrameTraversal()
NS_IMPL_ISUPPORTS1(nsFrameTraversal,nsIFrameTraversal) NS_IMPL_ISUPPORTS1(nsFrameTraversal,nsIFrameTraversal)
NS_IMETHODIMP NS_IMETHODIMP
nsFrameTraversal::NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator, nsFrameTraversal::NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsIFrame *aStart, nsIFrame *aStart,
PRInt32 aType, PRInt32 aType,
@ -217,7 +213,7 @@ NS_IMETHODIMP
// nsFrameIterator implementation // nsFrameIterator implementation
NS_IMPL_ISUPPORTS2(nsFrameIterator, nsIEnumerator, nsIBidirectionalEnumerator) NS_IMPL_ISUPPORTS1(nsFrameIterator, nsIFrameEnumerator)
nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart, nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
nsIteratorType aType, PRBool aLockInScrollView, nsIteratorType aType, PRBool aLockInScrollView,
@ -237,34 +233,27 @@ nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
NS_IMETHODIMP nsIFrame*
nsFrameIterator::CurrentItem(nsISupports **aItem) nsFrameIterator::CurrentItem()
{ {
if (!aItem)
return NS_ERROR_NULL_POINTER;
*aItem = mCurrent;
if (mOffEdge) if (mOffEdge)
return NS_ENUMERATOR_FALSE; return nsnull;
return NS_OK;
return mCurrent;
} }
NS_IMETHODIMP PRBool
nsFrameIterator::IsDone()//what does this mean??off edge? yes nsFrameIterator::IsDone()
{ {
if (mOffEdge != 0) return mOffEdge != 0;
return NS_OK;
return NS_ENUMERATOR_FALSE;
} }
void
NS_IMETHODIMP
nsFrameIterator::First() nsFrameIterator::First()
{ {
mCurrent = mStart; mCurrent = mStart;
return NS_OK;
} }
static PRBool static PRBool
@ -275,7 +264,7 @@ IsRootFrame(nsIFrame* aFrame)
(atom == nsGkAtoms::rootFrame); (atom == nsGkAtoms::rootFrame);
} }
NS_IMETHODIMP void
nsFrameIterator::Last() nsFrameIterator::Last()
{ {
nsIFrame* result; nsIFrame* result;
@ -294,10 +283,9 @@ nsFrameIterator::Last()
setCurrent(parent); setCurrent(parent);
if (!parent) if (!parent)
setOffEdge(1); setOffEdge(1);
return NS_OK;
} }
NS_IMETHODIMP void
nsFrameIterator::Next() nsFrameIterator::Next()
{ {
// recursive-oid method to get next frame // recursive-oid method to get next frame
@ -351,10 +339,9 @@ nsFrameIterator::Next()
setOffEdge(1); setOffEdge(1);
setLast(parent); setLast(parent);
} }
return NS_OK;
} }
NS_IMETHODIMP void
nsFrameIterator::Prev() nsFrameIterator::Prev()
{ {
// recursive-oid method to get prev frame // recursive-oid method to get prev frame
@ -407,7 +394,6 @@ nsFrameIterator::Prev()
setOffEdge(-1); setOffEdge(-1);
setLast(parent); setLast(parent);
} }
return NS_OK;
} }
nsIFrame* nsIFrame*

Просмотреть файл

@ -37,11 +37,10 @@
#ifndef NSFRAMETRAVERSAL_H #ifndef NSFRAMETRAVERSAL_H
#define NSFRAMETRAVERSAL_H #define NSFRAMETRAVERSAL_H
#include "nsIEnumerator.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsIFrameTraversal.h" #include "nsIFrameTraversal.h"
nsresult NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator, nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsIFrame *aStart, nsIFrame *aStart,
nsIteratorType aType, nsIteratorType aType,
@ -59,7 +58,7 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_IMETHOD NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator, NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsIFrame *aStart, nsIFrame *aStart,
PRInt32 aType, PRInt32 aType,

Просмотреть файл

@ -38,9 +38,28 @@
#define NSIFRAMETRAVERSAL_H #define NSIFRAMETRAVERSAL_H
#include "nsISupports.h" #include "nsISupports.h"
#include "nsIEnumerator.h"
#include "nsIFrame.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 { enum nsIteratorType {
eLeaf, eLeaf,
ePreOrder, ePreOrder,
@ -71,7 +90,7 @@ public:
* the real frame. Going back up will go on past the placeholder, * the real frame. Going back up will go on past the placeholder,
* so the placeholders are logically part of the frame tree. * so the placeholders are logically part of the frame tree.
*/ */
NS_IMETHOD NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator, NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsIFrame *aStart, nsIFrame *aStart,
PRInt32 aType, PRInt32 aType,

Просмотреть файл

@ -4629,7 +4629,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
} }
//resultFrame is not a block frame //resultFrame is not a block frame
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
aPresContext, resultFrame, aPresContext, resultFrame,
ePostOrder, ePostOrder,
@ -4639,7 +4639,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
); );
if (NS_FAILED(result)) if (NS_FAILED(result))
return result; return result;
nsISupports *isupports = nsnull;
nsIFrame *storeOldResultFrame = resultFrame; nsIFrame *storeOldResultFrame = resultFrame;
while ( !found ){ while ( !found ){
nsPoint point; nsPoint point;
@ -4717,14 +4716,10 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
if (aPos->mDirection == eDirNext && (resultFrame == nearStoppingFrame)) if (aPos->mDirection == eDirNext && (resultFrame == nearStoppingFrame))
break; break;
//always try previous on THAT line if that fails go the other way //always try previous on THAT line if that fails go the other way
result = frameTraversal->Prev(); frameTraversal->Prev();
if (NS_FAILED(result)) resultFrame = frameTraversal->CurrentItem();
break; if (!resultFrame)
result = frameTraversal->CurrentItem(&isupports); return NS_ERROR_FAILURE;
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){ if (!found){
@ -4766,14 +4761,11 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame)) if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame))
break; break;
//previous didnt work now we try "next" //previous didnt work now we try "next"
result = frameTraversal->Next(); frameTraversal->Next();
if (NS_FAILED(result)) nsIFrame *tempFrame = frameTraversal->CurrentItem();
if (!tempFrame)
break; break;
result = frameTraversal->CurrentItem(&isupports); resultFrame = tempFrame;
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; aPos->mResultFrame = resultFrame;
} }
@ -5460,7 +5452,7 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
return NS_ERROR_FAILURE; //we are done. cannot jump lines return NS_ERROR_FAILURE; //we are done. cannot jump lines
} }
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
presContext, traversedFrame, presContext, traversedFrame,
eLeaf, eLeaf,
@ -5472,21 +5464,13 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
return result; return result;
if (aDirection == eDirNext) if (aDirection == eDirNext)
result = frameTraversal->Next(); frameTraversal->Next();
else else
result = frameTraversal->Prev(); frameTraversal->Prev();
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull; traversedFrame = frameTraversal->CurrentItem();
result = frameTraversal->CurrentItem(&isupports); if (!traversedFrame)
if (NS_FAILED(result)) return NS_ERROR_FAILURE;
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); traversedFrame->IsSelectable(&selectable, nsnull);
} // while (!selectable) } // while (!selectable)

Просмотреть файл

@ -1583,7 +1583,7 @@ nsFrameSelection::GetFrameFromLevel(nsIFrame *aFrameIn,
PRUint8 foundLevel = 0; PRUint8 foundLevel = 0;
nsIFrame *foundFrame = aFrameIn; nsIFrame *foundFrame = aFrameIn;
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;
nsresult result; nsresult result;
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,&result)); nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,&result));
if (NS_FAILED(result)) if (NS_FAILED(result))
@ -1598,25 +1598,17 @@ nsFrameSelection::GetFrameFromLevel(nsIFrame *aFrameIn,
); );
if (NS_FAILED(result)) if (NS_FAILED(result))
return result; return result;
nsISupports *isupports = nsnull;
do { do {
*aFrameOut = foundFrame; *aFrameOut = foundFrame;
if (aDirection == eDirNext) if (aDirection == eDirNext)
result = frameTraversal->Next(); frameTraversal->Next();
else else
result = frameTraversal->Prev(); frameTraversal->Prev();
if (NS_FAILED(result)) foundFrame = frameTraversal->CurrentItem();
return result; if (!foundFrame)
result = frameTraversal->CurrentItem(&isupports); return NS_ERROR_FAILURE;
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); foundLevel = NS_GET_EMBEDDING_LEVEL(foundFrame);
} while (foundLevel > aBidiLevel); } while (foundLevel > aBidiLevel);

Просмотреть файл

@ -1175,7 +1175,7 @@ nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,
// We know that the target range isn't usable because it's not in the // We know that the target range isn't usable because it's not in the
// view port. Move range forward to first visible point, // view port. Move range forward to first visible point,
// this speeds us up a lot in long documents // this speeds us up a lot in long documents
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal; nsCOMPtr<nsIFrameEnumerator> frameTraversal;
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID)); nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID));
if (trav) if (trav)
trav->NewFrameTraversal(getter_AddRefs(frameTraversal), trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
@ -1191,9 +1191,7 @@ nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,
while (rectVisibility == nsRectVisibility_kAboveViewport || rectVisibility == nsRectVisibility_kZeroAreaRect) { while (rectVisibility == nsRectVisibility_kAboveViewport || rectVisibility == nsRectVisibility_kZeroAreaRect) {
frameTraversal->Next(); frameTraversal->Next();
nsISupports* currentItem; frame = frameTraversal->CurrentItem();
frameTraversal->CurrentItem(&currentItem);
frame = static_cast<nsIFrame*>(currentItem);
if (!frame) if (!frame)
return PR_FALSE; return PR_FALSE;