Bug 330881: Crash when double-clicking in empty area inside isindex with position:absolute;direction:rtl;. r+sr=roc

This commit is contained in:
uriber%gmail.com 2006-03-20 09:20:49 +00:00
Родитель 6dfc980b20
Коммит 5f6eb6ecbc
3 изменённых файлов: 42 добавлений и 92 удалений

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

@ -4281,48 +4281,13 @@ nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{ {
nsCOMPtr<nsILineIteratorNavigator> iter; nsCOMPtr<nsILineIteratorNavigator> iter;
nsIFrame *blockFrame = this; nsIFrame *blockFrame = this;
nsIFrame *thisBlock = this;
PRInt32 thisLine;
while (NS_FAILED(result)){ while (NS_FAILED(result)){
thisBlock = blockFrame; PRInt32 thisLine = GetLineNumber(blockFrame, &blockFrame);
blockFrame = blockFrame->GetParent();
if (!blockFrame) //if at line 0 then nothing to do
return NS_OK;
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter));
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
blockFrame = blockFrame->GetParent();
result = NS_OK;
if (blockFrame) {
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter));
}
}
//this block is now one child down from blockframe
if (NS_FAILED(result) || !iter || !blockFrame || !thisBlock)
{
return ((result) ? result : NS_ERROR_FAILURE);
}
if (thisBlock->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
{
//if we are searching for a frame that is not in flow we will not find it.
//we must instead look for its placeholder
thisBlock =
aPresContext->FrameManager()->GetPlaceholderFrameFor(thisBlock);
if (!thisBlock)
return NS_ERROR_FAILURE;
}
result = iter->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
if (thisLine < 0) if (thisLine < 0)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter));
NS_ASSERTION(NS_SUCCEEDED(result) && iter, "GetLineNumber() succeeded but no block frame?");
int edgeCase = 0;//no edge case. this should look at thisLine int edgeCase = 0;//no edge case. this should look at thisLine
PRBool doneLooping = PR_FALSE;//tells us when no more block frames hit. PRBool doneLooping = PR_FALSE;//tells us when no more block frames hit.
@ -4410,23 +4375,12 @@ nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{ {
nsCOMPtr<nsILineIteratorNavigator> it; nsCOMPtr<nsILineIteratorNavigator> it;
// Adjusted so that the caret can't get confused when content changes // Adjusted so that the caret can't get confused when content changes
nsIFrame* thisBlock;
nsIFrame* blockFrame = AdjustFrameForSelectionStyles(this); nsIFrame* blockFrame = AdjustFrameForSelectionStyles(this);
do { PRInt32 thisLine = GetLineNumber(blockFrame, &blockFrame);
thisBlock = blockFrame; if (thisLine < 0)
blockFrame = blockFrame->GetParent();
if (blockFrame) {
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
}
} while (NS_FAILED(result) && blockFrame);
if (NS_FAILED(result))
return result;
//thisBlock is now one child down from blockFrame
PRInt32 thisLine;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result) || thisLine < 0 )
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
PRInt32 lineFrameCount; PRInt32 lineFrameCount;
nsIFrame *firstFrame; nsIFrame *firstFrame;
@ -4477,8 +4431,10 @@ nsFrame::CheckVisibility(nsPresContext* , PRInt32 , PRInt32 , PRBool , PRBool *,
PRInt32 PRInt32
nsFrame::GetLineNumber(nsIFrame *aFrame) nsFrame::GetLineNumber(nsIFrame *aFrame, nsIFrame** aContainingBlock)
{ {
NS_ASSERTION(aFrame, "null aFrame");
nsFrameManager* frameManager = aFrame->GetPresContext()->FrameManager();
nsIFrame *blockFrame = aFrame; nsIFrame *blockFrame = aFrame;
nsIFrame *thisBlock; nsIFrame *thisBlock;
PRInt32 thisLine; PRInt32 thisLine;
@ -4487,14 +4443,24 @@ nsFrame::GetLineNumber(nsIFrame *aFrame)
while (NS_FAILED(result) && blockFrame) while (NS_FAILED(result) && blockFrame)
{ {
thisBlock = blockFrame; thisBlock = blockFrame;
blockFrame = blockFrame->GetParent(); if (thisBlock->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
//if we are searching for a frame that is not in flow we will not find it.
//we must instead look for its placeholder
thisBlock = frameManager->GetPlaceholderFrameFor(thisBlock);
if (!thisBlock)
return -1;
}
blockFrame = thisBlock->GetParent();
result = NS_OK; result = NS_OK;
if (blockFrame) { if (blockFrame) {
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it)); result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
} }
} }
if (!blockFrame || !it) if (!blockFrame || !it)
return NS_ERROR_FAILURE; return -1;
if (aContainingBlock)
*aContainingBlock = blockFrame;
result = it->FindLineContaining(thisBlock, &thisLine); result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result)) if (NS_FAILED(result))
return -1; return -1;
@ -4508,27 +4474,16 @@ nsFrame::GetLineNumber(nsIFrame *aFrame)
NS_IMETHODIMP NS_IMETHODIMP
nsFrame::GetFrameFromDirection(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos) nsFrame::GetFrameFromDirection(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{ {
nsIFrame *blockFrame = this; nsIFrame *blockFrame;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIteratorNavigator> it; nsCOMPtr<nsILineIteratorNavigator> it;
PRBool preferLeft = aPos->mPreferLeft; PRBool preferLeft = aPos->mPreferLeft;
nsresult result = NS_ERROR_FAILURE; nsresult result;
while (NS_FAILED(result) && blockFrame) PRInt32 thisLine = GetLineNumber(this, &blockFrame);
{ if (thisLine < 0)
thisBlock = blockFrame;
blockFrame = blockFrame->GetParent();
result = NS_OK;
if (blockFrame) {
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
}
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine); result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
if (NS_FAILED(result)) NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
return result;
nsIFrame *traversedFrame = this; nsIFrame *traversedFrame = this;
nsIFrame *firstFrame; nsIFrame *firstFrame;
@ -4687,22 +4642,12 @@ nsFrame::GetFrameFromDirection(nsPresContext* aPresContext, nsPeekOffsetStruct *
} }
PRBool newLineIsRTL = PR_FALSE; PRBool newLineIsRTL = PR_FALSE;
if (lineJump) { if (lineJump) {
blockFrame = newFrame; thisLine = GetLineNumber(newFrame, &blockFrame);
nsresult result = NS_ERROR_FAILURE; if (thisLine < 0)
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
blockFrame = blockFrame->GetParent();
result = NS_OK;
if (blockFrame) {
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator), getter_AddRefs(it));
}
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine); result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
if (NS_FAILED(result)) NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
return result;
it->GetDirection(&newLineIsRTL); it->GetDirection(&newLineIsRTL);
result = it->CheckLineOrder(thisLine, &lineIsReordered, &firstVisual, &lastVisual); result = it->CheckLineOrder(thisLine, &lineIsReordered, &firstVisual, &lastVisual);

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

@ -487,8 +487,8 @@ protected:
// Style post processing hook // Style post processing hook
NS_IMETHOD DidSetStyleContext(); NS_IMETHOD DidSetStyleContext();
//return the line number of the aFrame // return the line number of the aFrame, and (optionally) the containing block frame.
static PRInt32 GetLineNumber(nsIFrame *aFrame); static PRInt32 GetLineNumber(nsIFrame *aFrame, nsIFrame** aContainingBlock = nsnull);
public: public:
//given a frame five me the first/last leaf available //given a frame five me the first/last leaf available

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

@ -685,8 +685,13 @@ nsLineIterator::CheckLineOrder(PRInt32 aLine,
nsIFrame **aFirstVisual, nsIFrame **aFirstVisual,
nsIFrame **aLastVisual) nsIFrame **aLastVisual)
{ {
NS_ASSERTION (aLine >= 0 && aLine < mNumLines, "aLine out of range!");
nsLineBox* line = mLines[aLine]; nsLineBox* line = mLines[aLine];
if (!line->mFirstChild) { // empty line
*aIsReordered = PR_FALSE;
return NS_OK;
}
nsPresContext* presContext = line->mFirstChild->GetPresContext(); nsPresContext* presContext = line->mFirstChild->GetPresContext();
if (!presContext->BidiEnabled()) { if (!presContext->BidiEnabled()) {