From fa5d3c3459094df935f3a0c1bfc2b7f9f6db1f85 Mon Sep 17 00:00:00 2001 From: "mjudge%netscape.com" Date: Wed, 1 Sep 1999 21:40:16 +0000 Subject: [PATCH] new selection code for dead areas. this is much better, trust me. the block frame now will look at its best line and look for a spot to select. if it finds another block frame now, it will continue the process in a while loop. each time looking for best x and y area. this reuses the code located in GetNextPrevLine. --- layout/generic/nsBlockFrame.cpp | 156 +++++++++----------- layout/generic/nsBlockReflowState.cpp | 156 +++++++++----------- layout/generic/nsBlockReflowState.h | 156 +++++++++----------- layout/generic/nsFrame.cpp | 60 ++++---- layout/generic/nsTextFrame.cpp | 13 +- layout/html/base/src/nsBlockFrame.cpp | 156 +++++++++----------- layout/html/base/src/nsBlockReflowState.cpp | 156 +++++++++----------- layout/html/base/src/nsBlockReflowState.h | 156 +++++++++----------- layout/html/base/src/nsFrame.cpp | 60 ++++---- layout/html/base/src/nsTextFrame.cpp | 13 +- 10 files changed, 502 insertions(+), 580 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 6c9f9c28b440..d820d47e5806 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -4591,6 +4591,7 @@ nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext, } return NS_OK; } + #endif void @@ -5318,100 +5319,85 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN || aEvent->message == NS_MOUSE_MOVE || aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK ) { nsresult result; - nsIFrame *resultFrame = nsnull; -/* result = GetFrameForPoint(aEvent->point, &resultFrame); - if (resultFrame && NS_SUCCEEDED(result)) - { - return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); - } - */ + nsIFrame *resultFrame = nsnull;//this will be passed the handle event when we + //can tell who to pass it to nsCOMPtr it; - result = QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 countLines; - result = it->GetNumLines(&countLines); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 i; - PRInt32 lineFrameCount; - nsIFrame *firstFrame; - nsRect rect; - PRInt32 closestLine = 0; - PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison - for (i = 0; i< countLines;i++) - { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); - if (NS_FAILED(result)) - continue;//do not handle - if (rect.Contains(aEvent->point.x, aEvent->point.y)) - { - closestLine = i; - break; - } - else - { - PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - { - closestDistance = distance; - closestLine = i; - } - else if (distance > closestDistance) - break;//done - } - } + nsIFrame *mainframe = this; nsCOMPtr shell; aPresContext.GetShell(getter_AddRefs(shell)); if (!shell) return NS_OK; nsCOMPtr tracker; result = shell->QueryInterface(nsIFocusTracker::GetIID(),getter_AddRefs(tracker)); - nsIContent *content; - PRInt32 contentOffset; - nsIFrame *returnFrame; - closestDistance = 999999; - PRInt32 distance; - nsPoint offsetPoint; //used for offset of result frame - nsIView * view; //used for call of get offset from view - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirNext, - this, - closestLine-1, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - closestDistance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - resultFrame = returnFrame; - } - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirPrevious, - this, - closestLine, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - resultFrame = returnFrame; + result = mainframe->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + nsIView* parentWithView; + nsPoint origin; + + while(NS_SUCCEEDED(result)) + { //we are starting aloop to allow us to "drill down to the one we want" + mainframe->GetOffsetFromView(origin, &parentWithView); + + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 countLines; + result = it->GetNumLines(&countLines); + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 i; + PRInt32 lineFrameCount; + nsIFrame *firstFrame; + nsRect rect; + PRInt32 closestLine = 0; + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + //incase we hit another block frame. + for (i = 0; i< countLines;i++) + { + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + if (NS_FAILED(result)) + continue;//do not handle + rect+=origin; + if (rect.Contains(aEvent->point.x, aEvent->point.y)) + { + closestLine = i; + break; + } + else + { + PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); + if (distance < closestDistance) + { + closestDistance = distance; + closestLine = i; + } + else if (distance > closestDistance) + break;//done + } + } + nsIContent *content; + PRInt32 contentOffset; + //we will now ask where to go. if we cant find what we want"aka another block frame" + //we drill down again + result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, + eDirNext, + mainframe, + closestLine-1, + aEvent->point.x, + &content, + &contentOffset, + 0, + &resultFrame + ); + + if (NS_SUCCEEDED(result) && resultFrame){ + result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + mainframe = resultFrame; + } } + //end while loop. if nssucceeded resutl then keep going that means + //we have successfully hit another block frame and we should keep going. + + if (resultFrame) return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); else diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index 6c9f9c28b440..d820d47e5806 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -4591,6 +4591,7 @@ nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext, } return NS_OK; } + #endif void @@ -5318,100 +5319,85 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN || aEvent->message == NS_MOUSE_MOVE || aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK ) { nsresult result; - nsIFrame *resultFrame = nsnull; -/* result = GetFrameForPoint(aEvent->point, &resultFrame); - if (resultFrame && NS_SUCCEEDED(result)) - { - return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); - } - */ + nsIFrame *resultFrame = nsnull;//this will be passed the handle event when we + //can tell who to pass it to nsCOMPtr it; - result = QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 countLines; - result = it->GetNumLines(&countLines); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 i; - PRInt32 lineFrameCount; - nsIFrame *firstFrame; - nsRect rect; - PRInt32 closestLine = 0; - PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison - for (i = 0; i< countLines;i++) - { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); - if (NS_FAILED(result)) - continue;//do not handle - if (rect.Contains(aEvent->point.x, aEvent->point.y)) - { - closestLine = i; - break; - } - else - { - PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - { - closestDistance = distance; - closestLine = i; - } - else if (distance > closestDistance) - break;//done - } - } + nsIFrame *mainframe = this; nsCOMPtr shell; aPresContext.GetShell(getter_AddRefs(shell)); if (!shell) return NS_OK; nsCOMPtr tracker; result = shell->QueryInterface(nsIFocusTracker::GetIID(),getter_AddRefs(tracker)); - nsIContent *content; - PRInt32 contentOffset; - nsIFrame *returnFrame; - closestDistance = 999999; - PRInt32 distance; - nsPoint offsetPoint; //used for offset of result frame - nsIView * view; //used for call of get offset from view - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirNext, - this, - closestLine-1, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - closestDistance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - resultFrame = returnFrame; - } - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirPrevious, - this, - closestLine, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - resultFrame = returnFrame; + result = mainframe->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + nsIView* parentWithView; + nsPoint origin; + + while(NS_SUCCEEDED(result)) + { //we are starting aloop to allow us to "drill down to the one we want" + mainframe->GetOffsetFromView(origin, &parentWithView); + + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 countLines; + result = it->GetNumLines(&countLines); + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 i; + PRInt32 lineFrameCount; + nsIFrame *firstFrame; + nsRect rect; + PRInt32 closestLine = 0; + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + //incase we hit another block frame. + for (i = 0; i< countLines;i++) + { + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + if (NS_FAILED(result)) + continue;//do not handle + rect+=origin; + if (rect.Contains(aEvent->point.x, aEvent->point.y)) + { + closestLine = i; + break; + } + else + { + PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); + if (distance < closestDistance) + { + closestDistance = distance; + closestLine = i; + } + else if (distance > closestDistance) + break;//done + } + } + nsIContent *content; + PRInt32 contentOffset; + //we will now ask where to go. if we cant find what we want"aka another block frame" + //we drill down again + result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, + eDirNext, + mainframe, + closestLine-1, + aEvent->point.x, + &content, + &contentOffset, + 0, + &resultFrame + ); + + if (NS_SUCCEEDED(result) && resultFrame){ + result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + mainframe = resultFrame; + } } + //end while loop. if nssucceeded resutl then keep going that means + //we have successfully hit another block frame and we should keep going. + + if (resultFrame) return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); else diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h index 6c9f9c28b440..d820d47e5806 100644 --- a/layout/generic/nsBlockReflowState.h +++ b/layout/generic/nsBlockReflowState.h @@ -4591,6 +4591,7 @@ nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext, } return NS_OK; } + #endif void @@ -5318,100 +5319,85 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN || aEvent->message == NS_MOUSE_MOVE || aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK ) { nsresult result; - nsIFrame *resultFrame = nsnull; -/* result = GetFrameForPoint(aEvent->point, &resultFrame); - if (resultFrame && NS_SUCCEEDED(result)) - { - return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); - } - */ + nsIFrame *resultFrame = nsnull;//this will be passed the handle event when we + //can tell who to pass it to nsCOMPtr it; - result = QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 countLines; - result = it->GetNumLines(&countLines); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 i; - PRInt32 lineFrameCount; - nsIFrame *firstFrame; - nsRect rect; - PRInt32 closestLine = 0; - PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison - for (i = 0; i< countLines;i++) - { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); - if (NS_FAILED(result)) - continue;//do not handle - if (rect.Contains(aEvent->point.x, aEvent->point.y)) - { - closestLine = i; - break; - } - else - { - PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - { - closestDistance = distance; - closestLine = i; - } - else if (distance > closestDistance) - break;//done - } - } + nsIFrame *mainframe = this; nsCOMPtr shell; aPresContext.GetShell(getter_AddRefs(shell)); if (!shell) return NS_OK; nsCOMPtr tracker; result = shell->QueryInterface(nsIFocusTracker::GetIID(),getter_AddRefs(tracker)); - nsIContent *content; - PRInt32 contentOffset; - nsIFrame *returnFrame; - closestDistance = 999999; - PRInt32 distance; - nsPoint offsetPoint; //used for offset of result frame - nsIView * view; //used for call of get offset from view - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirNext, - this, - closestLine-1, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - closestDistance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - resultFrame = returnFrame; - } - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirPrevious, - this, - closestLine, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - resultFrame = returnFrame; + result = mainframe->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + nsIView* parentWithView; + nsPoint origin; + + while(NS_SUCCEEDED(result)) + { //we are starting aloop to allow us to "drill down to the one we want" + mainframe->GetOffsetFromView(origin, &parentWithView); + + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 countLines; + result = it->GetNumLines(&countLines); + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 i; + PRInt32 lineFrameCount; + nsIFrame *firstFrame; + nsRect rect; + PRInt32 closestLine = 0; + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + //incase we hit another block frame. + for (i = 0; i< countLines;i++) + { + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + if (NS_FAILED(result)) + continue;//do not handle + rect+=origin; + if (rect.Contains(aEvent->point.x, aEvent->point.y)) + { + closestLine = i; + break; + } + else + { + PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); + if (distance < closestDistance) + { + closestDistance = distance; + closestLine = i; + } + else if (distance > closestDistance) + break;//done + } + } + nsIContent *content; + PRInt32 contentOffset; + //we will now ask where to go. if we cant find what we want"aka another block frame" + //we drill down again + result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, + eDirNext, + mainframe, + closestLine-1, + aEvent->point.x, + &content, + &contentOffset, + 0, + &resultFrame + ); + + if (NS_SUCCEEDED(result) && resultFrame){ + result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + mainframe = resultFrame; + } } + //end while loop. if nssucceeded resutl then keep going that means + //we have successfully hit another block frame and we should keep going. + + if (resultFrame) return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); else diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 4efb30dd9054..36f8420dea5a 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1757,32 +1757,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(newIt)); if (NS_SUCCEEDED(result) && newIt) { - if (aDirection == eDirPrevious){ - if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker, - aDirection, - resultFrame, - 0, - aDesiredX, - aResultContent, - aContentOffset, - 1,//start from end, - aResultFrame - ))) - return NS_OK; - } - else { - if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker, - aDirection, - resultFrame, - 0, - aDesiredX, - aResultContent, - aContentOffset, - -1,//start from beginning - aResultFrame - ))) - return NS_OK; - } + *aResultFrame = resultFrame; + return NS_OK; } //resultFrame is not a block frame @@ -1899,22 +1875,46 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); } } - if (NS_FAILED(result) || !it || !blockFrame) + //this block is now one child down from blockframe + if (NS_FAILED(result) || !it || !blockFrame || !thisBlock) return result; result = it->FindLineContaining(thisBlock, &thisLine); if (NS_FAILED(result)) return result; - result = GetNextPrevLineFromeBlockFrame(aTracker, + int edgeCase = 0;//no edge case. this should look at thisLine + PRBool doneLooping = PR_FALSE;//tells us when no more block frames hit. + //this part will find a frame or a block frame. if its a block frame + //it will "drill down" to find a viable frame or it will return an error. + do { + result = GetNextPrevLineFromeBlockFrame(aTracker, aDirection, blockFrame, thisLine, aDesiredX, aResultContent, aContentOffset, - 0, //start from thisLine + edgeCase, //start from thisLine aResultFrame ); - thisBlock = blockFrame; + doneLooping = PR_TRUE; //do not continue with while loop + if (NS_SUCCEEDED(result) && *aResultFrame){ + result = (*aResultFrame)->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + if (NS_SUCCEEDED(result) && it)//we have struck another block element! + { + doneLooping = PR_FALSE; + if (aDirection == eDirPrevious) + edgeCase = 1;//far edge, search from end backwards + else + edgeCase = -1;//near edge search from beginning onwards + thisLine=0;//this line means nothing now. + //everything else means something so keep looking "inside" the block + blockFrame = *aResultFrame; + + } + else + result = NS_OK;//THIS is to mean that everything is ok to the containing while loop + } + }while(!doneLooping); } break; diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 72687caa25e9..db7354775e57 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -907,6 +907,9 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext, aRenderingContext.SetColor(NS_RGB(128,0,255)); aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size); }break; + default: + NS_ASSERTION(0,"what type of selection do i not know about?"); + break; } } @@ -1977,11 +1980,6 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, if (aStartOffset < mContentOffset){ aStartOffset = mContentOffset; } - if (aAmount == eSelectLine) - { - return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset, - aResultContent, aContentOffset, aResultFrame,aEatingWS); - } if (aStartOffset > (mContentOffset + mContentLength)){ nsIFrame *nextInFlow; nextInFlow = GetNextInFlow(); @@ -1993,6 +1991,11 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, aResultContent,aContentOffset,aResultFrame,aEatingWS); } + if (aAmount == eSelectLine) + { + return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset, + aResultContent, aContentOffset, aResultFrame,aEatingWS); + } PRUnichar wordBufMem[WORD_BUF_SIZE]; PRUnichar paintBufMem[TEXT_BUF_SIZE]; diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index 6c9f9c28b440..d820d47e5806 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -4591,6 +4591,7 @@ nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext, } return NS_OK; } + #endif void @@ -5318,100 +5319,85 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN || aEvent->message == NS_MOUSE_MOVE || aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK ) { nsresult result; - nsIFrame *resultFrame = nsnull; -/* result = GetFrameForPoint(aEvent->point, &resultFrame); - if (resultFrame && NS_SUCCEEDED(result)) - { - return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); - } - */ + nsIFrame *resultFrame = nsnull;//this will be passed the handle event when we + //can tell who to pass it to nsCOMPtr it; - result = QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 countLines; - result = it->GetNumLines(&countLines); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 i; - PRInt32 lineFrameCount; - nsIFrame *firstFrame; - nsRect rect; - PRInt32 closestLine = 0; - PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison - for (i = 0; i< countLines;i++) - { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); - if (NS_FAILED(result)) - continue;//do not handle - if (rect.Contains(aEvent->point.x, aEvent->point.y)) - { - closestLine = i; - break; - } - else - { - PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - { - closestDistance = distance; - closestLine = i; - } - else if (distance > closestDistance) - break;//done - } - } + nsIFrame *mainframe = this; nsCOMPtr shell; aPresContext.GetShell(getter_AddRefs(shell)); if (!shell) return NS_OK; nsCOMPtr tracker; result = shell->QueryInterface(nsIFocusTracker::GetIID(),getter_AddRefs(tracker)); - nsIContent *content; - PRInt32 contentOffset; - nsIFrame *returnFrame; - closestDistance = 999999; - PRInt32 distance; - nsPoint offsetPoint; //used for offset of result frame - nsIView * view; //used for call of get offset from view - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirNext, - this, - closestLine-1, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - closestDistance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - resultFrame = returnFrame; - } - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirPrevious, - this, - closestLine, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - resultFrame = returnFrame; + result = mainframe->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + nsIView* parentWithView; + nsPoint origin; + + while(NS_SUCCEEDED(result)) + { //we are starting aloop to allow us to "drill down to the one we want" + mainframe->GetOffsetFromView(origin, &parentWithView); + + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 countLines; + result = it->GetNumLines(&countLines); + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 i; + PRInt32 lineFrameCount; + nsIFrame *firstFrame; + nsRect rect; + PRInt32 closestLine = 0; + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + //incase we hit another block frame. + for (i = 0; i< countLines;i++) + { + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + if (NS_FAILED(result)) + continue;//do not handle + rect+=origin; + if (rect.Contains(aEvent->point.x, aEvent->point.y)) + { + closestLine = i; + break; + } + else + { + PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); + if (distance < closestDistance) + { + closestDistance = distance; + closestLine = i; + } + else if (distance > closestDistance) + break;//done + } + } + nsIContent *content; + PRInt32 contentOffset; + //we will now ask where to go. if we cant find what we want"aka another block frame" + //we drill down again + result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, + eDirNext, + mainframe, + closestLine-1, + aEvent->point.x, + &content, + &contentOffset, + 0, + &resultFrame + ); + + if (NS_SUCCEEDED(result) && resultFrame){ + result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + mainframe = resultFrame; + } } + //end while loop. if nssucceeded resutl then keep going that means + //we have successfully hit another block frame and we should keep going. + + if (resultFrame) return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); else diff --git a/layout/html/base/src/nsBlockReflowState.cpp b/layout/html/base/src/nsBlockReflowState.cpp index 6c9f9c28b440..d820d47e5806 100644 --- a/layout/html/base/src/nsBlockReflowState.cpp +++ b/layout/html/base/src/nsBlockReflowState.cpp @@ -4591,6 +4591,7 @@ nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext, } return NS_OK; } + #endif void @@ -5318,100 +5319,85 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN || aEvent->message == NS_MOUSE_MOVE || aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK ) { nsresult result; - nsIFrame *resultFrame = nsnull; -/* result = GetFrameForPoint(aEvent->point, &resultFrame); - if (resultFrame && NS_SUCCEEDED(result)) - { - return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); - } - */ + nsIFrame *resultFrame = nsnull;//this will be passed the handle event when we + //can tell who to pass it to nsCOMPtr it; - result = QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 countLines; - result = it->GetNumLines(&countLines); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 i; - PRInt32 lineFrameCount; - nsIFrame *firstFrame; - nsRect rect; - PRInt32 closestLine = 0; - PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison - for (i = 0; i< countLines;i++) - { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); - if (NS_FAILED(result)) - continue;//do not handle - if (rect.Contains(aEvent->point.x, aEvent->point.y)) - { - closestLine = i; - break; - } - else - { - PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - { - closestDistance = distance; - closestLine = i; - } - else if (distance > closestDistance) - break;//done - } - } + nsIFrame *mainframe = this; nsCOMPtr shell; aPresContext.GetShell(getter_AddRefs(shell)); if (!shell) return NS_OK; nsCOMPtr tracker; result = shell->QueryInterface(nsIFocusTracker::GetIID(),getter_AddRefs(tracker)); - nsIContent *content; - PRInt32 contentOffset; - nsIFrame *returnFrame; - closestDistance = 999999; - PRInt32 distance; - nsPoint offsetPoint; //used for offset of result frame - nsIView * view; //used for call of get offset from view - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirNext, - this, - closestLine-1, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - closestDistance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - resultFrame = returnFrame; - } - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirPrevious, - this, - closestLine, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - resultFrame = returnFrame; + result = mainframe->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + nsIView* parentWithView; + nsPoint origin; + + while(NS_SUCCEEDED(result)) + { //we are starting aloop to allow us to "drill down to the one we want" + mainframe->GetOffsetFromView(origin, &parentWithView); + + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 countLines; + result = it->GetNumLines(&countLines); + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 i; + PRInt32 lineFrameCount; + nsIFrame *firstFrame; + nsRect rect; + PRInt32 closestLine = 0; + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + //incase we hit another block frame. + for (i = 0; i< countLines;i++) + { + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + if (NS_FAILED(result)) + continue;//do not handle + rect+=origin; + if (rect.Contains(aEvent->point.x, aEvent->point.y)) + { + closestLine = i; + break; + } + else + { + PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); + if (distance < closestDistance) + { + closestDistance = distance; + closestLine = i; + } + else if (distance > closestDistance) + break;//done + } + } + nsIContent *content; + PRInt32 contentOffset; + //we will now ask where to go. if we cant find what we want"aka another block frame" + //we drill down again + result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, + eDirNext, + mainframe, + closestLine-1, + aEvent->point.x, + &content, + &contentOffset, + 0, + &resultFrame + ); + + if (NS_SUCCEEDED(result) && resultFrame){ + result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + mainframe = resultFrame; + } } + //end while loop. if nssucceeded resutl then keep going that means + //we have successfully hit another block frame and we should keep going. + + if (resultFrame) return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); else diff --git a/layout/html/base/src/nsBlockReflowState.h b/layout/html/base/src/nsBlockReflowState.h index 6c9f9c28b440..d820d47e5806 100644 --- a/layout/html/base/src/nsBlockReflowState.h +++ b/layout/html/base/src/nsBlockReflowState.h @@ -4591,6 +4591,7 @@ nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext, } return NS_OK; } + #endif void @@ -5318,100 +5319,85 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN || aEvent->message == NS_MOUSE_MOVE || aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK ) { nsresult result; - nsIFrame *resultFrame = nsnull; -/* result = GetFrameForPoint(aEvent->point, &resultFrame); - if (resultFrame && NS_SUCCEEDED(result)) - { - return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); - } - */ + nsIFrame *resultFrame = nsnull;//this will be passed the handle event when we + //can tell who to pass it to nsCOMPtr it; - result = QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 countLines; - result = it->GetNumLines(&countLines); - if (NS_FAILED(result)) - return NS_OK;//do not handle - PRInt32 i; - PRInt32 lineFrameCount; - nsIFrame *firstFrame; - nsRect rect; - PRInt32 closestLine = 0; - PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison - for (i = 0; i< countLines;i++) - { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); - if (NS_FAILED(result)) - continue;//do not handle - if (rect.Contains(aEvent->point.x, aEvent->point.y)) - { - closestLine = i; - break; - } - else - { - PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - { - closestDistance = distance; - closestLine = i; - } - else if (distance > closestDistance) - break;//done - } - } + nsIFrame *mainframe = this; nsCOMPtr shell; aPresContext.GetShell(getter_AddRefs(shell)); if (!shell) return NS_OK; nsCOMPtr tracker; result = shell->QueryInterface(nsIFocusTracker::GetIID(),getter_AddRefs(tracker)); - nsIContent *content; - PRInt32 contentOffset; - nsIFrame *returnFrame; - closestDistance = 999999; - PRInt32 distance; - nsPoint offsetPoint; //used for offset of result frame - nsIView * view; //used for call of get offset from view - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirNext, - this, - closestLine-1, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - closestDistance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - resultFrame = returnFrame; - } - result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, - eDirPrevious, - this, - closestLine, - aEvent->point.x, - &content, - &contentOffset, - 0, - &returnFrame - ); - if (NS_SUCCEEDED(result) && returnFrame){ - returnFrame->GetOffsetFromView(offsetPoint, &view); - returnFrame->GetRect(rect); - rect.x = offsetPoint.x; - rect.y = offsetPoint.y; - distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); - if (distance < closestDistance) - resultFrame = returnFrame; + result = mainframe->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + nsIView* parentWithView; + nsPoint origin; + + while(NS_SUCCEEDED(result)) + { //we are starting aloop to allow us to "drill down to the one we want" + mainframe->GetOffsetFromView(origin, &parentWithView); + + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 countLines; + result = it->GetNumLines(&countLines); + if (NS_FAILED(result)) + return NS_OK;//do not handle + PRInt32 i; + PRInt32 lineFrameCount; + nsIFrame *firstFrame; + nsRect rect; + PRInt32 closestLine = 0; + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + //incase we hit another block frame. + for (i = 0; i< countLines;i++) + { + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + if (NS_FAILED(result)) + continue;//do not handle + rect+=origin; + if (rect.Contains(aEvent->point.x, aEvent->point.y)) + { + closestLine = i; + break; + } + else + { + PRInt32 distance = PR_MIN(abs(rect.y - aEvent->point.y),abs((rect.y + rect.height) - aEvent->point.y)); + if (distance < closestDistance) + { + closestDistance = distance; + closestLine = i; + } + else if (distance > closestDistance) + break;//done + } + } + nsIContent *content; + PRInt32 contentOffset; + //we will now ask where to go. if we cant find what we want"aka another block frame" + //we drill down again + result = nsFrame::GetNextPrevLineFromeBlockFrame(tracker, + eDirNext, + mainframe, + closestLine-1, + aEvent->point.x, + &content, + &contentOffset, + 0, + &resultFrame + ); + + if (NS_SUCCEEDED(result) && resultFrame){ + result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + mainframe = resultFrame; + } } + //end while loop. if nssucceeded resutl then keep going that means + //we have successfully hit another block frame and we should keep going. + + if (resultFrame) return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); else diff --git a/layout/html/base/src/nsFrame.cpp b/layout/html/base/src/nsFrame.cpp index 4efb30dd9054..36f8420dea5a 100644 --- a/layout/html/base/src/nsFrame.cpp +++ b/layout/html/base/src/nsFrame.cpp @@ -1757,32 +1757,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, result = resultFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(newIt)); if (NS_SUCCEEDED(result) && newIt) { - if (aDirection == eDirPrevious){ - if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker, - aDirection, - resultFrame, - 0, - aDesiredX, - aResultContent, - aContentOffset, - 1,//start from end, - aResultFrame - ))) - return NS_OK; - } - else { - if (NS_SUCCEEDED(GetNextPrevLineFromeBlockFrame(aTracker, - aDirection, - resultFrame, - 0, - aDesiredX, - aResultContent, - aContentOffset, - -1,//start from beginning - aResultFrame - ))) - return NS_OK; - } + *aResultFrame = resultFrame; + return NS_OK; } //resultFrame is not a block frame @@ -1899,22 +1875,46 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); } } - if (NS_FAILED(result) || !it || !blockFrame) + //this block is now one child down from blockframe + if (NS_FAILED(result) || !it || !blockFrame || !thisBlock) return result; result = it->FindLineContaining(thisBlock, &thisLine); if (NS_FAILED(result)) return result; - result = GetNextPrevLineFromeBlockFrame(aTracker, + int edgeCase = 0;//no edge case. this should look at thisLine + PRBool doneLooping = PR_FALSE;//tells us when no more block frames hit. + //this part will find a frame or a block frame. if its a block frame + //it will "drill down" to find a viable frame or it will return an error. + do { + result = GetNextPrevLineFromeBlockFrame(aTracker, aDirection, blockFrame, thisLine, aDesiredX, aResultContent, aContentOffset, - 0, //start from thisLine + edgeCase, //start from thisLine aResultFrame ); - thisBlock = blockFrame; + doneLooping = PR_TRUE; //do not continue with while loop + if (NS_SUCCEEDED(result) && *aResultFrame){ + result = (*aResultFrame)->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it)); + if (NS_SUCCEEDED(result) && it)//we have struck another block element! + { + doneLooping = PR_FALSE; + if (aDirection == eDirPrevious) + edgeCase = 1;//far edge, search from end backwards + else + edgeCase = -1;//near edge search from beginning onwards + thisLine=0;//this line means nothing now. + //everything else means something so keep looking "inside" the block + blockFrame = *aResultFrame; + + } + else + result = NS_OK;//THIS is to mean that everything is ok to the containing while loop + } + }while(!doneLooping); } break; diff --git a/layout/html/base/src/nsTextFrame.cpp b/layout/html/base/src/nsTextFrame.cpp index 72687caa25e9..db7354775e57 100644 --- a/layout/html/base/src/nsTextFrame.cpp +++ b/layout/html/base/src/nsTextFrame.cpp @@ -907,6 +907,9 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext, aRenderingContext.SetColor(NS_RGB(128,0,255)); aRenderingContext.FillRect(aX, aY + baseline - offset, aWidth, size); }break; + default: + NS_ASSERTION(0,"what type of selection do i not know about?"); + break; } } @@ -1977,11 +1980,6 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, if (aStartOffset < mContentOffset){ aStartOffset = mContentOffset; } - if (aAmount == eSelectLine) - { - return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset, - aResultContent, aContentOffset, aResultFrame,aEatingWS); - } if (aStartOffset > (mContentOffset + mContentLength)){ nsIFrame *nextInFlow; nextInFlow = GetNextInFlow(); @@ -1993,6 +1991,11 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, aResultContent,aContentOffset,aResultFrame,aEatingWS); } + if (aAmount == eSelectLine) + { + return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset, + aResultContent, aContentOffset, aResultFrame,aEatingWS); + } PRUnichar wordBufMem[WORD_BUF_SIZE]; PRUnichar paintBufMem[TEXT_BUF_SIZE];