From 72808fb95ebf9242c44595ea7f762ffc9379ba02 Mon Sep 17 00:00:00 2001 From: "mjudge%netscape.com" Date: Tue, 24 Aug 1999 21:51:47 +0000 Subject: [PATCH] changes to allow selection in "dead" space between frames. still need work on "outside" and not in the window at all, but this is a very good chunk of the issue and it will solve many many bugs on my place. good for dogfood as well :) git-svn-id: svn://10.0.0.236/trunk@44364 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/public/nsIFrame.h | 3 +- mozilla/layout/base/src/nsRangeList.cpp | 15 +-- mozilla/layout/generic/nsBlockFrame.cpp | 118 ++++++++++++++++++ mozilla/layout/generic/nsBlockReflowState.cpp | 118 ++++++++++++++++++ mozilla/layout/generic/nsBlockReflowState.h | 118 ++++++++++++++++++ mozilla/layout/generic/nsFrame.cpp | 68 +++++++--- mozilla/layout/generic/nsFrame.h | 6 +- mozilla/layout/generic/nsIFrame.h | 3 +- mozilla/layout/generic/nsTextFrame.cpp | 47 +++---- mozilla/layout/html/base/src/nsBlockFrame.cpp | 118 ++++++++++++++++++ .../html/base/src/nsBlockReflowState.cpp | 118 ++++++++++++++++++ .../layout/html/base/src/nsBlockReflowState.h | 118 ++++++++++++++++++ mozilla/layout/html/base/src/nsFrame.cpp | 68 +++++++--- mozilla/layout/html/base/src/nsFrame.h | 6 +- mozilla/layout/html/base/src/nsTextFrame.cpp | 47 +++---- 15 files changed, 864 insertions(+), 107 deletions(-) diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h index 7f2c807d8b1..6a7847f2043 100644 --- a/mozilla/layout/base/public/nsIFrame.h +++ b/mozilla/layout/base/public/nsIFrame.h @@ -636,10 +636,11 @@ public: * @param aStartOffset start offset to start the peek. 0 == beginning -1 = end * @param aResultContent content that actually is the next/previous * @param aResultOffset offset for result content + * @param aResultFrame resulting frame for peeking * @param aEatingWS boolean to tell us the state of our search for Next/Prev */ NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker, PRInt32 aDesiredX, nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset, - nsIContent **aResultContent, PRInt32 *aResultOffset, PRBool aEatingWS) = 0; + nsIContent **aResultContent, PRInt32 *aResultOffset, nsIFrame **aResultFrame, PRBool aEatingWS) = 0; /** * See if tree verification is enabled. To enable tree verification add diff --git a/mozilla/layout/base/src/nsRangeList.cpp b/mozilla/layout/base/src/nsRangeList.cpp index 497d5a9423d..ae90bce7b68 100644 --- a/mozilla/layout/base/src/nsRangeList.cpp +++ b/mozilla/layout/base/src/nsRangeList.cpp @@ -782,6 +782,7 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) offsetused = mDomSelections[SELECTION_NORMAL]->FetchFocusOffset(); weakNodeUsed = mDomSelections[SELECTION_NORMAL]->FetchFocusNode(); nsIFrame *frame; + nsIFrame *resultFrame; nsCOMPtr content; result = mDomSelections[SELECTION_NORMAL]->GetPrimaryFrameForFocusNode(&frame); if (NS_FAILED(result)) @@ -790,7 +791,7 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) case nsIDOMUIEvent::VK_LEFT : { //we need to look for the previous PAINTED location to move the cursor to. - if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){ + if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, &resultFrame, PR_FALSE)) && content){ result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift, PR_FALSE); } result = mDomSelections[SELECTION_NORMAL]->ScrollIntoView(); @@ -799,7 +800,7 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) case nsIDOMUIEvent::VK_RIGHT : { //we need to look for the previous PAINTED location to move the cursor to. - if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){ + if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, &resultFrame, PR_FALSE)) && content){ result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift, PR_FALSE); } result = mDomSelections[SELECTION_NORMAL]->ScrollIntoView(); @@ -812,12 +813,12 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) amount = eSelectLine; if (nsIDOMUIEvent::VK_UP == keyEvent->keyCode) { - if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){ + if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, &resultFrame, PR_FALSE)) && content){ result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift, PR_FALSE); } } else - if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){ + if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, &resultFrame, PR_FALSE)) && content){ result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift, PR_FALSE); } result = mDomSelections[SELECTION_NORMAL]->ScrollIntoView(); @@ -1183,10 +1184,10 @@ nsDOMSelection::~nsDOMSelection() PRUint32 cnt = 0; nsresult rv = mRangeArray->Count(&cnt); NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed"); - PRUint32 j; - for (j=cnt-1;j >= 0; j--) + PRInt32 j; + for (j=0; jRemoveElementAt(j); + mRangeArray->RemoveElementAt(0); } setAnchorFocusRange(-1); } diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 640c93a7f43..a47981f735e 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -47,6 +47,8 @@ // XXX for IsEmptyLine #include "nsTextFragment.h" +#include "nsIFocusTracker.h" +#include "nsIFrameSelection.h" // XXX HTML:P's that are empty yet have style indicating they should // clear floaters - we need to ignore the clear behavior. @@ -5277,11 +5279,127 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, } } + NS_IMETHODIMP nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE) { + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv)){ + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + PRBool mouseDown = PR_FALSE; + if (NS_FAILED(frameselection->GetMouseDownState(&mouseDown)) || !mouseDown) + return NS_OK;//do not handle + } + } + } + + 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); + } + */ + 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 + } + } + 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; + } + if (resultFrame) + return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); + else + return NS_OK; //just stop it + } return NS_OK; } diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 640c93a7f43..a47981f735e 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -47,6 +47,8 @@ // XXX for IsEmptyLine #include "nsTextFragment.h" +#include "nsIFocusTracker.h" +#include "nsIFrameSelection.h" // XXX HTML:P's that are empty yet have style indicating they should // clear floaters - we need to ignore the clear behavior. @@ -5277,11 +5279,127 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, } } + NS_IMETHODIMP nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE) { + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv)){ + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + PRBool mouseDown = PR_FALSE; + if (NS_FAILED(frameselection->GetMouseDownState(&mouseDown)) || !mouseDown) + return NS_OK;//do not handle + } + } + } + + 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); + } + */ + 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 + } + } + 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; + } + if (resultFrame) + return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); + else + return NS_OK; //just stop it + } return NS_OK; } diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index 640c93a7f43..a47981f735e 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -47,6 +47,8 @@ // XXX for IsEmptyLine #include "nsTextFragment.h" +#include "nsIFocusTracker.h" +#include "nsIFrameSelection.h" // XXX HTML:P's that are empty yet have style indicating they should // clear floaters - we need to ignore the clear behavior. @@ -5277,11 +5279,127 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, } } + NS_IMETHODIMP nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE) { + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv)){ + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + PRBool mouseDown = PR_FALSE; + if (NS_FAILED(frameselection->GetMouseDownState(&mouseDown)) || !mouseDown) + return NS_OK;//do not handle + } + } + } + + 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); + } + */ + 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 + } + } + 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; + } + if (resultFrame) + return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); + else + return NS_OK; //just stop it + } return NS_OK; } diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 53f5009fcfc..f7b2a3f8250 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -895,6 +895,42 @@ NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aCX, if (!aNewContent || !mContent) return NS_ERROR_NULL_POINTER; nsresult result; + + //traverse through children and look for the best one to give this to + //if it fails the getposition call, make it yourself// also only look at primary list + nsIFrame *kid; + nsIFrame *closestFrame = nsnull; + nsresult rv = FirstChild(nsnull, &kid); + if (NS_SUCCEEDED(rv) && nsnull != kid) { + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + while (nsnull != kid) { + nsRect rect; + kid->GetRect(rect); + nsPoint offsetPoint; //used for offset of result frame + nsIView * view; //used for call of get offset from view + kid->GetOffsetFromView(offsetPoint, &view); + rect.x = offsetPoint.x; + rect.y = offsetPoint.y; + if (rect.x <= aXCoord && (rect.x+rect.width) >= aXCoord) + { + closestFrame = kid; + break; + } + + PRInt32 distance = PR_MIN(abs(rect.x - aXCoord),abs((rect.x + rect.width) - aXCoord)); + if (distance < closestDistance) + { + closestDistance = distance; + closestFrame = kid; + } + else if (distance > closestDistance) + break;//done + + kid->GetNextSibling(&kid); + } + if (closestFrame) + return closestFrame->GetPosition(aCX,aXCoord,aNewContent,aContentOffset,aContentOffsetEnd); + } result = mContent->GetParent(*aNewContent); if (*aNewContent){ @@ -1592,7 +1628,7 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram return NS_OK; } -NS_IMETHODIMP +nsresult nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, nsDirection aDirection, nsIFrame *aBlockFrame, @@ -1600,7 +1636,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, nscoord aDesiredX, nsIContent **aResultContent, PRInt32 *aContentOffset, - PRInt8 aOutSideLimit + PRInt8 aOutSideLimit, + nsIFrame **aResultFrame ) { //magic numbers aLineStart will be -1 for end of block 0 will be start of block @@ -1624,12 +1661,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, (aDirection == eDirNext && aLineStart >= (countLines -1) )){ //we need to jump to new block frame. return NS_ERROR_FAILURE; -/* if (aDirection == eDirNext) - return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent, - aContentOffset, PR_FALSE); - else - return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent, - aContentOffset, PR_FALSE);*/ } PRInt32 lineFrameCount; nsIFrame *resultFrame = nsnull; @@ -1685,7 +1716,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, aDesiredX, aResultContent, aContentOffset, - 1//start from end + 1,//start from end, + aResultFrame ))) return NS_OK; } @@ -1697,7 +1729,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, aDesiredX, aResultContent, aContentOffset, - -1//start from beginning + -1,//start from beginning + aResultFrame ))) return NS_OK; } @@ -1765,15 +1798,16 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, resultFrame = (nsIFrame *)isupports; } } + *aResultFrame = resultFrame; } else { //we need to jump to new block frame. if (aDirection == eDirNext) return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent, - aContentOffset, PR_FALSE); + aContentOffset, aResultFrame, PR_FALSE); else return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent, - aContentOffset, PR_FALSE); + aContentOffset, aResultFrame, PR_FALSE); } } return NS_OK; @@ -1788,9 +1822,10 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS) { - if (!aResultContent || !aContentOffset ||!aTracker) + if (!aResultContent || !aContentOffset ||!aTracker || !aResultFrame) return NS_ERROR_NULL_POINTER; nsresult result = NS_ERROR_FAILURE; switch (aAmount){ @@ -1830,7 +1865,8 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, aDesiredX, aResultContent, aContentOffset, - 0 //start from thisLine + 0, //start from thisLine + aResultFrame ); thisBlock = blockFrame; @@ -1864,10 +1900,10 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, nsIFrame *newFrame = (nsIFrame *)isupports; if (aDirection == eDirNext) return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent, - aContentOffset, aEatingWS); + aContentOffset,aResultFrame, aEatingWS); else return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent, - aContentOffset, aEatingWS); + aContentOffset,aResultFrame, aEatingWS); } } return result; diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index 1660a62a724..a4260670b34 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -179,14 +179,15 @@ public: PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); - NS_IMETHOD GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, + static nsresult GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, nsDirection aDirection, nsIFrame *aBlockFrame, PRInt32 aLineStart, nscoord aDesiredX, nsIContent **aResultContent, PRInt32 *aContentOffset, - PRInt8 aOutSideLimit + PRInt8 aOutSideLimit, + nsIFrame **aResultFrame = nsnull ); NS_IMETHOD GetFrameState(nsFrameState* aResult); @@ -232,6 +233,7 @@ public: PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS) ; NS_IMETHOD GetOffsets(PRInt32 &aStart, PRInt32 &aEnd) const; diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index 7f2c807d8b1..6a7847f2043 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -636,10 +636,11 @@ public: * @param aStartOffset start offset to start the peek. 0 == beginning -1 = end * @param aResultContent content that actually is the next/previous * @param aResultOffset offset for result content + * @param aResultFrame resulting frame for peeking * @param aEatingWS boolean to tell us the state of our search for Next/Prev */ NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker, PRInt32 aDesiredX, nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset, - nsIContent **aResultContent, PRInt32 *aResultOffset, PRBool aEatingWS) = 0; + nsIContent **aResultContent, PRInt32 *aResultOffset, nsIFrame **aResultFrame, PRBool aEatingWS) = 0; /** * See if tree verification is enabled. To enable tree verification add diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 9958a53b96a..4072151bb73 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -249,6 +249,7 @@ public: PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS); NS_IMETHOD HandleMultiplePress(nsIPresContext& aPresContext, @@ -1717,7 +1718,6 @@ nsTextFrame::GetPosition(nsIPresContext& aCX, PRUnichar* text = paintBuf; nsPoint origin; nsIView * view; - GetView(&view); GetOffsetFromView(origin, &view); PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0, PRInt32(textLength), @@ -1731,17 +1731,6 @@ nsTextFrame::GetPosition(nsIPresContext& aCX, if (PRInt32(aXCoord) - origin.x > textWidth+charWidth) { index++; } - - /*offset = 0; - PRInt32 j; - PRInt32* ptr = ip; - for (j=0;j<=PRInt32(mContentLength);j++) { - if (*ptr == index+mContentOffset) { - offset = j;//+mContentOffset; - break; - } - ptr++; - } */ } if (ip != indicies) { @@ -1980,6 +1969,7 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS) { @@ -1990,7 +1980,11 @@ 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(); @@ -1999,7 +1993,7 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, return NS_ERROR_INVALID_ARG; } return nextInFlow->PeekOffset(aTracker, aDesiredX, aAmount,aDirection,aStartOffset, - aResultContent,aContentOffset,aEatingWS); + aResultContent,aContentOffset,aResultFrame,aEatingWS); } @@ -2079,11 +2073,11 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, if (!found){ if (frameUsed){ result = frameUsed->PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } else {//reached end ask the frame for help result = nsFrame::PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } } else { @@ -2192,11 +2186,11 @@ printf("aEatingWS = %s\n" , aEatingWS ? "TRUE" : "FALSE"); if (!found || (*aContentOffset > (mContentOffset + mContentLength)) || (*aContentOffset < mContentOffset)){ //gone too far if (frameUsed){ result = frameUsed->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } else {//reached end ask the frame for help result = nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } } else { @@ -2206,19 +2200,6 @@ printf("aEatingWS = %s\n" , aEatingWS ? "TRUE" : "FALSE"); } } break; - case eSelectLine : - { - // Cleanup - if (paintBuf != paintBufMem) { - delete [] paintBuf; - } - if (ip != indicies) { - delete [] ip; - } - return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset, - aResultContent, aContentOffset, aEatingWS); - } - break; default: result = NS_ERROR_FAILURE; break; } // Cleanup @@ -2235,6 +2216,7 @@ printf("aEatingWS = %s\n" , aEatingWS ? "TRUE" : "FALSE"); *aContentOffset = aStartOffset; result = NS_OK; } + *aResultFrame = this; return result; } @@ -2269,6 +2251,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, nsCOMPtr endNode; PRInt32 startOffset; PRInt32 endOffset; + nsIFrame *resultFrame; //peeks{} rv = PeekOffset(tracker, 0, @@ -2277,6 +2260,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, startPos, getter_AddRefs(startContent), &startOffset, + &resultFrame, PR_FALSE); if (NS_FAILED(rv)) return rv; @@ -2287,6 +2271,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, startPos, getter_AddRefs(endContent), &endOffset, + &resultFrame, PR_FALSE); if (NS_FAILED(rv)) return rv; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 640c93a7f43..a47981f735e 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -47,6 +47,8 @@ // XXX for IsEmptyLine #include "nsTextFragment.h" +#include "nsIFocusTracker.h" +#include "nsIFrameSelection.h" // XXX HTML:P's that are empty yet have style indicating they should // clear floaters - we need to ignore the clear behavior. @@ -5277,11 +5279,127 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, } } + NS_IMETHODIMP nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE) { + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv)){ + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + PRBool mouseDown = PR_FALSE; + if (NS_FAILED(frameselection->GetMouseDownState(&mouseDown)) || !mouseDown) + return NS_OK;//do not handle + } + } + } + + 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); + } + */ + 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 + } + } + 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; + } + if (resultFrame) + return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); + else + return NS_OK; //just stop it + } return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 640c93a7f43..a47981f735e 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -47,6 +47,8 @@ // XXX for IsEmptyLine #include "nsTextFragment.h" +#include "nsIFocusTracker.h" +#include "nsIFrameSelection.h" // XXX HTML:P's that are empty yet have style indicating they should // clear floaters - we need to ignore the clear behavior. @@ -5277,11 +5279,127 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, } } + NS_IMETHODIMP nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE) { + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv)){ + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + PRBool mouseDown = PR_FALSE; + if (NS_FAILED(frameselection->GetMouseDownState(&mouseDown)) || !mouseDown) + return NS_OK;//do not handle + } + } + } + + 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); + } + */ + 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 + } + } + 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; + } + if (resultFrame) + return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); + else + return NS_OK; //just stop it + } return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index 640c93a7f43..a47981f735e 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -47,6 +47,8 @@ // XXX for IsEmptyLine #include "nsTextFragment.h" +#include "nsIFocusTracker.h" +#include "nsIFrameSelection.h" // XXX HTML:P's that are empty yet have style indicating they should // clear floaters - we need to ignore the clear behavior. @@ -5277,11 +5279,127 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, } } + NS_IMETHODIMP nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE) { + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv)){ + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + PRBool mouseDown = PR_FALSE; + if (NS_FAILED(frameselection->GetMouseDownState(&mouseDown)) || !mouseDown) + return NS_OK;//do not handle + } + } + } + + 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); + } + */ + 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 + } + } + 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; + } + if (resultFrame) + return resultFrame->HandleEvent(aPresContext, aEvent, aEventStatus); + else + return NS_OK; //just stop it + } return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index 53f5009fcfc..f7b2a3f8250 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -895,6 +895,42 @@ NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aCX, if (!aNewContent || !mContent) return NS_ERROR_NULL_POINTER; nsresult result; + + //traverse through children and look for the best one to give this to + //if it fails the getposition call, make it yourself// also only look at primary list + nsIFrame *kid; + nsIFrame *closestFrame = nsnull; + nsresult rv = FirstChild(nsnull, &kid); + if (NS_SUCCEEDED(rv) && nsnull != kid) { + PRInt32 closestDistance = 999999; //some HUGE number that will always fail first comparison + while (nsnull != kid) { + nsRect rect; + kid->GetRect(rect); + nsPoint offsetPoint; //used for offset of result frame + nsIView * view; //used for call of get offset from view + kid->GetOffsetFromView(offsetPoint, &view); + rect.x = offsetPoint.x; + rect.y = offsetPoint.y; + if (rect.x <= aXCoord && (rect.x+rect.width) >= aXCoord) + { + closestFrame = kid; + break; + } + + PRInt32 distance = PR_MIN(abs(rect.x - aXCoord),abs((rect.x + rect.width) - aXCoord)); + if (distance < closestDistance) + { + closestDistance = distance; + closestFrame = kid; + } + else if (distance > closestDistance) + break;//done + + kid->GetNextSibling(&kid); + } + if (closestFrame) + return closestFrame->GetPosition(aCX,aXCoord,aNewContent,aContentOffset,aContentOffsetEnd); + } result = mContent->GetParent(*aNewContent); if (*aNewContent){ @@ -1592,7 +1628,7 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram return NS_OK; } -NS_IMETHODIMP +nsresult nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, nsDirection aDirection, nsIFrame *aBlockFrame, @@ -1600,7 +1636,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, nscoord aDesiredX, nsIContent **aResultContent, PRInt32 *aContentOffset, - PRInt8 aOutSideLimit + PRInt8 aOutSideLimit, + nsIFrame **aResultFrame ) { //magic numbers aLineStart will be -1 for end of block 0 will be start of block @@ -1624,12 +1661,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, (aDirection == eDirNext && aLineStart >= (countLines -1) )){ //we need to jump to new block frame. return NS_ERROR_FAILURE; -/* if (aDirection == eDirNext) - return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent, - aContentOffset, PR_FALSE); - else - return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent, - aContentOffset, PR_FALSE);*/ } PRInt32 lineFrameCount; nsIFrame *resultFrame = nsnull; @@ -1685,7 +1716,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, aDesiredX, aResultContent, aContentOffset, - 1//start from end + 1,//start from end, + aResultFrame ))) return NS_OK; } @@ -1697,7 +1729,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, aDesiredX, aResultContent, aContentOffset, - -1//start from beginning + -1,//start from beginning + aResultFrame ))) return NS_OK; } @@ -1765,15 +1798,16 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, resultFrame = (nsIFrame *)isupports; } } + *aResultFrame = resultFrame; } else { //we need to jump to new block frame. if (aDirection == eDirNext) return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, 0, aResultContent, - aContentOffset, PR_FALSE); + aContentOffset, aResultFrame, PR_FALSE); else return aBlockFrame->PeekOffset(aTracker, aDesiredX, eSelectLine, aDirection, -1, aResultContent, - aContentOffset, PR_FALSE); + aContentOffset, aResultFrame, PR_FALSE); } } return NS_OK; @@ -1788,9 +1822,10 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS) { - if (!aResultContent || !aContentOffset ||!aTracker) + if (!aResultContent || !aContentOffset ||!aTracker || !aResultFrame) return NS_ERROR_NULL_POINTER; nsresult result = NS_ERROR_FAILURE; switch (aAmount){ @@ -1830,7 +1865,8 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, aDesiredX, aResultContent, aContentOffset, - 0 //start from thisLine + 0, //start from thisLine + aResultFrame ); thisBlock = blockFrame; @@ -1864,10 +1900,10 @@ nsFrame::PeekOffset(nsIFocusTracker *aTracker, nsIFrame *newFrame = (nsIFrame *)isupports; if (aDirection == eDirNext) return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent, - aContentOffset, aEatingWS); + aContentOffset,aResultFrame, aEatingWS); else return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent, - aContentOffset, aEatingWS); + aContentOffset,aResultFrame, aEatingWS); } } return result; diff --git a/mozilla/layout/html/base/src/nsFrame.h b/mozilla/layout/html/base/src/nsFrame.h index 1660a62a724..a4260670b34 100644 --- a/mozilla/layout/html/base/src/nsFrame.h +++ b/mozilla/layout/html/base/src/nsFrame.h @@ -179,14 +179,15 @@ public: PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); - NS_IMETHOD GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, + static nsresult GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, nsDirection aDirection, nsIFrame *aBlockFrame, PRInt32 aLineStart, nscoord aDesiredX, nsIContent **aResultContent, PRInt32 *aContentOffset, - PRInt8 aOutSideLimit + PRInt8 aOutSideLimit, + nsIFrame **aResultFrame = nsnull ); NS_IMETHOD GetFrameState(nsFrameState* aResult); @@ -232,6 +233,7 @@ public: PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS) ; NS_IMETHOD GetOffsets(PRInt32 &aStart, PRInt32 &aEnd) const; diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index 9958a53b96a..4072151bb73 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -249,6 +249,7 @@ public: PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS); NS_IMETHOD HandleMultiplePress(nsIPresContext& aPresContext, @@ -1717,7 +1718,6 @@ nsTextFrame::GetPosition(nsIPresContext& aCX, PRUnichar* text = paintBuf; nsPoint origin; nsIView * view; - GetView(&view); GetOffsetFromView(origin, &view); PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0, PRInt32(textLength), @@ -1731,17 +1731,6 @@ nsTextFrame::GetPosition(nsIPresContext& aCX, if (PRInt32(aXCoord) - origin.x > textWidth+charWidth) { index++; } - - /*offset = 0; - PRInt32 j; - PRInt32* ptr = ip; - for (j=0;j<=PRInt32(mContentLength);j++) { - if (*ptr == index+mContentOffset) { - offset = j;//+mContentOffset; - break; - } - ptr++; - } */ } if (ip != indicies) { @@ -1980,6 +1969,7 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, PRInt32 aStartOffset, nsIContent **aResultContent, PRInt32 *aContentOffset, + nsIFrame **aResultFrame, PRBool aEatingWS) { @@ -1990,7 +1980,11 @@ 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(); @@ -1999,7 +1993,7 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, return NS_ERROR_INVALID_ARG; } return nextInFlow->PeekOffset(aTracker, aDesiredX, aAmount,aDirection,aStartOffset, - aResultContent,aContentOffset,aEatingWS); + aResultContent,aContentOffset,aResultFrame,aEatingWS); } @@ -2079,11 +2073,11 @@ nsTextFrame::PeekOffset(nsIFocusTracker *aTracker, if (!found){ if (frameUsed){ result = frameUsed->PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } else {//reached end ask the frame for help result = nsFrame::PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } } else { @@ -2192,11 +2186,11 @@ printf("aEatingWS = %s\n" , aEatingWS ? "TRUE" : "FALSE"); if (!found || (*aContentOffset > (mContentOffset + mContentLength)) || (*aContentOffset < mContentOffset)){ //gone too far if (frameUsed){ result = frameUsed->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } else {//reached end ask the frame for help result = nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent, - aContentOffset, aEatingWS); + aContentOffset, aResultFrame,aEatingWS); } } else { @@ -2206,19 +2200,6 @@ printf("aEatingWS = %s\n" , aEatingWS ? "TRUE" : "FALSE"); } } break; - case eSelectLine : - { - // Cleanup - if (paintBuf != paintBufMem) { - delete [] paintBuf; - } - if (ip != indicies) { - delete [] ip; - } - return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset, - aResultContent, aContentOffset, aEatingWS); - } - break; default: result = NS_ERROR_FAILURE; break; } // Cleanup @@ -2235,6 +2216,7 @@ printf("aEatingWS = %s\n" , aEatingWS ? "TRUE" : "FALSE"); *aContentOffset = aStartOffset; result = NS_OK; } + *aResultFrame = this; return result; } @@ -2269,6 +2251,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, nsCOMPtr endNode; PRInt32 startOffset; PRInt32 endOffset; + nsIFrame *resultFrame; //peeks{} rv = PeekOffset(tracker, 0, @@ -2277,6 +2260,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, startPos, getter_AddRefs(startContent), &startOffset, + &resultFrame, PR_FALSE); if (NS_FAILED(rv)) return rv; @@ -2287,6 +2271,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, startPos, getter_AddRefs(endContent), &endOffset, + &resultFrame, PR_FALSE); if (NS_FAILED(rv)) return rv;