diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index e84ab68102a1..6f5f1409749d 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -230,16 +230,13 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB // find the frame that contains the content node that has focus nsIFrame* theFrame = nsnull; - err = mPresShell->GetPrimaryFrameFor(contentNode, &theFrame); - if (NS_FAILED(err)) - return err; - - if (!theFrame) - return NS_ERROR_UNEXPECTED; - - // find the child frame containing the offset we want - PRInt32 contentOffset = focusOffset; - err = theFrame->GetChildFrameContainingOffset(focusOffset, &focusOffset, &theFrame); + + //get frame selection and find out what frame to use... + nsCOMPtr frameSelection; + err = mPresShell->GetFrameSelection(getter_AddRefs(frameSelection)); + if (NS_FAILED(err) || !frameSelection) + return err; + err = frameSelection->GetFrameForNodeOffset(contentNode, focusOffset, &theFrame); if (NS_FAILED(err)) return err; @@ -274,7 +271,7 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB // now we can measure the offset into the frame. nsPoint framePos(0, 0); - theFrame->GetPointFromOffset(presContext, rendContext, contentOffset, &framePos); + theFrame->GetPointFromOffset(presContext, rendContext, focusOffset, &framePos); // now add the frame offset to the view offset, and we're done viewOffset += framePos; @@ -454,10 +451,16 @@ PRBool nsCaret::SetupDrawingFrameAndOffset() } nsIFrame* theFrame = nsnull; - PRInt32 focusOffset; - if (NS_SUCCEEDED(mPresShell->GetPrimaryFrameFor(contentNode, &theFrame)) && - theFrame && NS_SUCCEEDED(theFrame->GetChildFrameContainingOffset(contentOffset, &focusOffset, &theFrame))) + //get frame selection and find out what frame to use... + nsCOMPtr frameSelection; + err = mPresShell->GetFrameSelection(getter_AddRefs(frameSelection)); + if (NS_FAILED(err) || !frameSelection) + return err; + err = frameSelection->GetFrameForNodeOffset(contentNode, contentOffset, &theFrame); + if (NS_FAILED(err)) + return err; + else { // mark the frame, so we get notified on deletion. diff --git a/layout/base/nsIFrameSelection.h b/layout/base/nsIFrameSelection.h index 193852631544..f2842c354cce 100644 --- a/layout/base/nsIFrameSelection.h +++ b/layout/base/nsIFrameSelection.h @@ -184,6 +184,14 @@ public: * @param aSelectionType enum value defined in nsIDOMSelection for the domseleciton you want. */ NS_IMETHOD RepaintSelection(SelectionType aSelectionType)=0; + + /** GetFrameForNodeOffset given a node and its child offset, return the nsIFrame and + * the offset into that frame. + * @param aNode input parameter for the node to look at + * @param aOffset offset into above node. + * @param aResultFrame will contain the return frame. MUST NOT BE NULL or will return error + */ + NS_IMETHOD GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame)=0; }; diff --git a/layout/base/public/nsIFrame.h b/layout/base/public/nsIFrame.h index 22afaa9aa9f2..2d40b55100ac 100644 --- a/layout/base/public/nsIFrame.h +++ b/layout/base/public/nsIFrame.h @@ -500,9 +500,12 @@ public: * Get the child frame of this frame which contains the given * content offset. outChildFrame may be this frame, or nsnull on return. * outContentOffset returns the content offset relative to the start - * of the returned node + * of the returned node. You can also pass a hint which tells the method + * to stick to the end of the first found frame or the beginning of the + * next in case the offset falls on a boundary. */ NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint,//false stick left PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame) = 0; diff --git a/layout/base/public/nsIFrameSelection.h b/layout/base/public/nsIFrameSelection.h index 193852631544..f2842c354cce 100644 --- a/layout/base/public/nsIFrameSelection.h +++ b/layout/base/public/nsIFrameSelection.h @@ -184,6 +184,14 @@ public: * @param aSelectionType enum value defined in nsIDOMSelection for the domseleciton you want. */ NS_IMETHOD RepaintSelection(SelectionType aSelectionType)=0; + + /** GetFrameForNodeOffset given a node and its child offset, return the nsIFrame and + * the offset into that frame. + * @param aNode input parameter for the node to look at + * @param aOffset offset into above node. + * @param aResultFrame will contain the return frame. MUST NOT BE NULL or will return error + */ + NS_IMETHOD GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame)=0; }; diff --git a/layout/base/src/nsCaret.cpp b/layout/base/src/nsCaret.cpp index e84ab68102a1..6f5f1409749d 100644 --- a/layout/base/src/nsCaret.cpp +++ b/layout/base/src/nsCaret.cpp @@ -230,16 +230,13 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB // find the frame that contains the content node that has focus nsIFrame* theFrame = nsnull; - err = mPresShell->GetPrimaryFrameFor(contentNode, &theFrame); - if (NS_FAILED(err)) - return err; - - if (!theFrame) - return NS_ERROR_UNEXPECTED; - - // find the child frame containing the offset we want - PRInt32 contentOffset = focusOffset; - err = theFrame->GetChildFrameContainingOffset(focusOffset, &focusOffset, &theFrame); + + //get frame selection and find out what frame to use... + nsCOMPtr frameSelection; + err = mPresShell->GetFrameSelection(getter_AddRefs(frameSelection)); + if (NS_FAILED(err) || !frameSelection) + return err; + err = frameSelection->GetFrameForNodeOffset(contentNode, focusOffset, &theFrame); if (NS_FAILED(err)) return err; @@ -274,7 +271,7 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB // now we can measure the offset into the frame. nsPoint framePos(0, 0); - theFrame->GetPointFromOffset(presContext, rendContext, contentOffset, &framePos); + theFrame->GetPointFromOffset(presContext, rendContext, focusOffset, &framePos); // now add the frame offset to the view offset, and we're done viewOffset += framePos; @@ -454,10 +451,16 @@ PRBool nsCaret::SetupDrawingFrameAndOffset() } nsIFrame* theFrame = nsnull; - PRInt32 focusOffset; - if (NS_SUCCEEDED(mPresShell->GetPrimaryFrameFor(contentNode, &theFrame)) && - theFrame && NS_SUCCEEDED(theFrame->GetChildFrameContainingOffset(contentOffset, &focusOffset, &theFrame))) + //get frame selection and find out what frame to use... + nsCOMPtr frameSelection; + err = mPresShell->GetFrameSelection(getter_AddRefs(frameSelection)); + if (NS_FAILED(err) || !frameSelection) + return err; + err = frameSelection->GetFrameForNodeOffset(contentNode, contentOffset, &theFrame); + if (NS_FAILED(err)) + return err; + else { // mark the frame, so we get notified on deletion. diff --git a/layout/base/src/nsRangeList.cpp b/layout/base/src/nsRangeList.cpp index e9e95174b0b1..df5ff9de5dbf 100644 --- a/layout/base/src/nsRangeList.cpp +++ b/layout/base/src/nsRangeList.cpp @@ -143,7 +143,7 @@ public: nsDirection GetDirection(){return mDirection;} void SetDirection(nsDirection aDir){mDirection = aDir;} - NS_IMETHOD GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, PRInt32 aOffset, PRBool aIsEndNode, nsIFrame **aResultFrame); +// NS_IMETHOD GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, PRInt32 aOffset, PRBool aIsEndNode, nsIFrame **aResultFrame); NS_IMETHOD GetPrimaryFrameForAnchorNode(nsIFrame **aResultFrame); NS_IMETHOD GetPrimaryFrameForFocusNode(nsIFrame **aResultFrame); NS_IMETHOD SetOriginalAnchorPoint(nsIDOMNode *aNode, PRInt32 aOffset); @@ -200,6 +200,7 @@ public: NS_IMETHOD GetSelection(SelectionType aType, nsIDOMSelection **aDomSelection); NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion); NS_IMETHOD RepaintSelection(SelectionType aType); + NS_IMETHOD GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame); /*END nsIFrameSelection interfacse*/ @@ -249,6 +250,7 @@ private: PRBool mMouseDownState; //for drag purposes PRInt32 mDesiredX; PRBool mDesiredXSet; + enum HINT {HINTLEFT=0,HINTRIGHT=1}mHint;//end of this line or beginning of next public: static nsIAtom *sTableAtom; static nsIAtom *sCellAtom; @@ -790,14 +792,17 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) return result; nsPeekOffsetStruct pos; pos.SetData(mTracker, desiredX, amount, eDirPrevious, offsetused, PR_FALSE,PR_TRUE); + mHint = HINTRIGHT;//stick to opposite of movement switch (keyEvent->keyCode){ case nsIDOMUIEvent::VK_RIGHT : pos.mDirection = eDirNext; + mHint = HINTLEFT;//stick to this line case nsIDOMUIEvent::VK_LEFT : //no break InvalidateDesiredX(); break; case nsIDOMUIEvent::VK_DOWN : - pos.mDirection = eDirNext;//no break here + pos.mDirection = eDirNext;//no break here + mHint = HINTLEFT;//stick to this line case nsIDOMUIEvent::VK_UP : pos.mAmount = eSelectLine; break; @@ -808,7 +813,8 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) case nsIDOMUIEvent::VK_END : pos.mAmount = eSelectEndLine; InvalidateDesiredX(); - break; + mHint = HINTLEFT;//stick to this line + break; default :return result; } if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(&pos)) && pos.mResultContent) @@ -867,6 +873,7 @@ nsRangeList::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset, PRBool aContinueSelection, PRBool aMultipleSelection) { InvalidateDesiredX(); + mHint = HINTLEFT;//not really good we need a "hint" from the clicking code... this can be done.. return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection); } @@ -1015,6 +1022,24 @@ nsRangeList::RepaintSelection(SelectionType aType) return mDomSelections[aType]->Repaint(); } + +NS_IMETHODIMP +nsRangeList::GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame) +{ + if (!aNode || !aReturnFrame) + return NS_ERROR_NULL_POINTER; + nsresult result; + result = mTracker->GetPrimaryFrameFor(aNode, aReturnFrame); + if (NS_FAILED(result)) + return result; + + if (!*aReturnFrame) + return NS_ERROR_UNEXPECTED; + + // find the child frame containing the offset we want + result = (*aReturnFrame)->GetChildFrameContainingOffset(aOffset, mHint, &aOffset, aReturnFrame); + return result; +} //////////END FRAMESELECTION NS_METHOD @@ -1524,6 +1549,7 @@ nsDOMSelection::Clear() //utility method to get the primary frame of node or use the offset to get frame of child node +#if 0 NS_IMETHODIMP nsDOMSelection::GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, PRInt32 aOffset, PRBool aIsEndNode, nsIFrame **aReturnFrame) { @@ -1573,6 +1599,8 @@ nsDOMSelection::GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, PRInt32 aOffs result = mRangeList->GetTracker()->GetPrimaryFrameFor(content,aReturnFrame); return result; } +#endif + NS_IMETHODIMP nsDOMSelection::GetPrimaryFrameForAnchorNode(nsIFrame **aReturnFrame) @@ -1581,9 +1609,10 @@ nsDOMSelection::GetPrimaryFrameForAnchorNode(nsIFrame **aReturnFrame) return NS_ERROR_NULL_POINTER; *aReturnFrame = 0; - - return GetPrimaryFrameForRangeEndpoint(FetchAnchorNode(), FetchAnchorOffset(), - (GetDirection() == eDirPrevious), aReturnFrame); + nsCOMPtr content = do_QueryInterface(FetchAnchorNode()); + if (content) + return mRangeList->GetFrameForNodeOffset(content, FetchAnchorOffset(),aReturnFrame); + return NS_ERROR_FAILURE; } NS_IMETHODIMP @@ -1594,8 +1623,10 @@ nsDOMSelection::GetPrimaryFrameForFocusNode(nsIFrame **aReturnFrame) *aReturnFrame = 0; - return GetPrimaryFrameForRangeEndpoint(FetchFocusNode(), FetchFocusOffset(), - (GetDirection() == eDirNext), aReturnFrame); + nsCOMPtr content = do_QueryInterface(FetchAnchorNode()); + if (content) + return mRangeList->GetFrameForNodeOffset(content, FetchFocusOffset(),aReturnFrame); + return NS_ERROR_FAILURE; } //the idea of this helper method is to select, deselect "top to bottom" traversing through the frames @@ -2940,8 +2971,11 @@ nsDOMSelection::GetSelectionRegionRect(SelectionRegion aRegion, nsRect *aRect) if (!node) return NS_ERROR_NULL_POINTER; - result = GetPrimaryFrameForRangeEndpoint(node, nodeOffset, isEndNode, &frame); - + nsCOMPtr content = do_QueryInterface(node); + if (content) + result = mRangeList->GetFrameForNodeOffset(content, nodeOffset, &frame); + else + result = NS_ERROR_FAILURE; if(NS_FAILED(result)) return result; @@ -2960,7 +2994,7 @@ nsDOMSelection::GetSelectionRegionRect(SelectionRegion aRegion, nsRect *aRect) nsIFrame *childFrame = 0; PRInt32 frameOffset = 0; - result = frame->GetChildFrameContainingOffset(nodeOffset, &frameOffset, &childFrame); + result = frame->GetChildFrameContainingOffset(nodeOffset, mRangeList->mHint, &frameOffset, &childFrame); if (NS_FAILED(result)) return result; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 496bf5bd5e45..8c58af12ab77 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -834,6 +834,9 @@ nsFrame::HandlePress(nsIPresContext& aPresContext, if (!DisplaySelection(aPresContext)) { return NS_OK; } + nsMouseEvent *me = (nsMouseEvent *)aEvent; + if (me->clickCount >2 ) + return nsFrame::HandleMultiplePress(aPresContext,aEvent,aEventStatus); nsCOMPtr shell; nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); @@ -865,6 +868,77 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (!DisplaySelection(aPresContext)) { + return NS_OK; + } + + nsMouseEvent *me = (nsMouseEvent *)aEvent; + if (me->clickCount <3 ) + return NS_OK; + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell) { + nsCOMPtr acx; + nsCOMPtr tracker; + tracker = do_QueryInterface(shell, &rv); + if (NS_FAILED(rv) || !tracker) + return rv; + rv = shell->CreateRenderingContext(this, getter_AddRefs(acx)); + if (NS_SUCCEEDED(rv)){ + PRInt32 startPos = 0; + PRInt32 contentOffsetEnd = 0; + nsCOMPtr newContent; + if (NS_SUCCEEDED(GetPosition(aPresContext, aEvent->point.x, + getter_AddRefs(newContent), startPos, contentOffsetEnd))){ + //find which word needs to be selected! use peek offset one way then the other + nsCOMPtr startContent; + nsCOMPtr startNode; + nsCOMPtr endContent; + nsCOMPtr endNode; + //peeks{} + nsPeekOffsetStruct startpos; + startpos.SetData(tracker, + 0, + eSelectBeginLine, + eDirPrevious, + startPos, + PR_FALSE, + PR_TRUE); + rv = PeekOffset(&startpos); + if (NS_FAILED(rv)) + return rv; + nsPeekOffsetStruct endpos; + endpos.SetData(tracker, + 0, + eSelectEndLine, + eDirNext, + startPos, + PR_FALSE, + PR_FALSE); + rv = PeekOffset(&endpos); + if (NS_FAILED(rv)) + return rv; + + endNode = do_QueryInterface(endpos.mResultContent,&rv); + if (NS_FAILED(rv)) + return rv; + startNode = do_QueryInterface(startpos.mResultContent,&rv); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr selection; + if (NS_SUCCEEDED(shell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)))){ + rv = selection->Collapse(startNode,startpos.mContentOffset); + if (NS_FAILED(rv)) + return rv; + rv = selection->Extend(endNode,endpos.mContentOffset); + if (NS_FAILED(rv)) + return rv; + } + //no release + } + } + } return NS_OK; } @@ -1692,10 +1766,10 @@ nsFrame::GetPointFromOffset(nsIPresContext* inPresContext, nsIRenderingContext* } NS_IMETHODIMP -nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFrameContentOffset, nsIFrame **outChildFrame) +nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame **outChildFrame) { NS_PRECONDITION(outChildFrame && outFrameContentOffset, "Null parameter"); - *outFrameContentOffset = 0; + *outFrameContentOffset = (PRInt32)inHint; *outChildFrame = this; return NS_OK; } diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 607488390056..5d933c296eea 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -180,6 +180,7 @@ public: nsPoint* outPoint); NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 22afaa9aa9f2..2d40b55100ac 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -500,9 +500,12 @@ public: * Get the child frame of this frame which contains the given * content offset. outChildFrame may be this frame, or nsnull on return. * outContentOffset returns the content offset relative to the start - * of the returned node + * of the returned node. You can also pass a hint which tells the method + * to stick to the end of the first found frame or the beginning of the + * next in case the offset falls on a boundary. */ NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint,//false stick left PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame) = 0; diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index fc6a6f9c4a54..4d5b1fe8ba65 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -260,6 +260,7 @@ public: nsPoint* outPoint); NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); @@ -1916,6 +1917,7 @@ nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext, NS_IMETHODIMP nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame **outChildFrame) { @@ -1927,13 +1929,13 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, if (contentOffset != -1) //-1 signified the end of the current content contentOffset = inContentOffset - mContentOffset; - if (contentOffset > mContentLength) + if ((contentOffset > mContentLength) || ((contentOffset == mContentLength) && inHint) ) { //this is not the frame we are looking for. nsIFrame *nextInFlow; nextInFlow = GetNextInFlow(); if (nextInFlow) - return nextInFlow->GetChildFrameContainingOffset(inContentOffset, outFrameContentOffset, outChildFrame); + return nextInFlow->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset, outChildFrame); else return NS_ERROR_FAILURE; } @@ -1941,7 +1943,7 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, { result = GetPrevInFlow(outChildFrame); if (NS_SUCCEEDED(result)) - return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, + return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset,outChildFrame); else return result; @@ -1992,10 +1994,10 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos) PRInt32 textLength; nsresult result(NS_OK); + aPos->mResultContent = mContent;//do this right off switch (aPos->mAmount){ case eSelectNoAmount : { - aPos->mResultContent = mContent; aPos->mContentOffset = aPos->mStartOffset; } break; @@ -2161,8 +2163,8 @@ printf("2-GetNextWord return non null, wordLen%d, contentLen%d isWhitespace=%s\n printf("aEatingWS = %s\n" , aPos->mEatingWS ? "TRUE" : "FALSE"); #endif if (!found || (aPos->mContentOffset > (mContentOffset + mContentLength)) || (aPos->mContentOffset < mContentOffset)){ //gone too far - aPos->mStartOffset = start; if (frameUsed){ + aPos->mStartOffset = start; result = frameUsed->PeekOffset(aPos); } else {//reached end ask the frame for help @@ -2185,7 +2187,7 @@ printf("aEatingWS = %s\n" , aPos->mEatingWS ? "TRUE" : "FALSE"); } if (NS_FAILED(result)){ aPos->mResultContent = mContent; - aPos->mContentOffset = aPos->mStartOffset; + //aPos->mContentOffset = aPos->mStartOffset; result = NS_OK; } aPos->mResultFrame = this; @@ -2200,7 +2202,9 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, if (!DisplaySelection(aPresContext)) { return NS_OK; } - + nsMouseEvent *me = (nsMouseEvent *)aEvent; + if (me->clickCount > 2) + return nsFrame::HandleMultiplePress(aPresContext,aEvent,aEventStatus); nsCOMPtr shell; nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); if (NS_SUCCEEDED(rv) && shell) { @@ -2240,7 +2244,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, eDirNext, startPos, PR_FALSE, - PR_TRUE); + PR_FALSE); rv = PeekOffset(&endpos); if (NS_FAILED(rv)) return rv; diff --git a/layout/html/base/src/nsFrame.cpp b/layout/html/base/src/nsFrame.cpp index 496bf5bd5e45..8c58af12ab77 100644 --- a/layout/html/base/src/nsFrame.cpp +++ b/layout/html/base/src/nsFrame.cpp @@ -834,6 +834,9 @@ nsFrame::HandlePress(nsIPresContext& aPresContext, if (!DisplaySelection(aPresContext)) { return NS_OK; } + nsMouseEvent *me = (nsMouseEvent *)aEvent; + if (me->clickCount >2 ) + return nsFrame::HandleMultiplePress(aPresContext,aEvent,aEventStatus); nsCOMPtr shell; nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); @@ -865,6 +868,77 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + if (!DisplaySelection(aPresContext)) { + return NS_OK; + } + + nsMouseEvent *me = (nsMouseEvent *)aEvent; + if (me->clickCount <3 ) + return NS_OK; + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell) { + nsCOMPtr acx; + nsCOMPtr tracker; + tracker = do_QueryInterface(shell, &rv); + if (NS_FAILED(rv) || !tracker) + return rv; + rv = shell->CreateRenderingContext(this, getter_AddRefs(acx)); + if (NS_SUCCEEDED(rv)){ + PRInt32 startPos = 0; + PRInt32 contentOffsetEnd = 0; + nsCOMPtr newContent; + if (NS_SUCCEEDED(GetPosition(aPresContext, aEvent->point.x, + getter_AddRefs(newContent), startPos, contentOffsetEnd))){ + //find which word needs to be selected! use peek offset one way then the other + nsCOMPtr startContent; + nsCOMPtr startNode; + nsCOMPtr endContent; + nsCOMPtr endNode; + //peeks{} + nsPeekOffsetStruct startpos; + startpos.SetData(tracker, + 0, + eSelectBeginLine, + eDirPrevious, + startPos, + PR_FALSE, + PR_TRUE); + rv = PeekOffset(&startpos); + if (NS_FAILED(rv)) + return rv; + nsPeekOffsetStruct endpos; + endpos.SetData(tracker, + 0, + eSelectEndLine, + eDirNext, + startPos, + PR_FALSE, + PR_FALSE); + rv = PeekOffset(&endpos); + if (NS_FAILED(rv)) + return rv; + + endNode = do_QueryInterface(endpos.mResultContent,&rv); + if (NS_FAILED(rv)) + return rv; + startNode = do_QueryInterface(startpos.mResultContent,&rv); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr selection; + if (NS_SUCCEEDED(shell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)))){ + rv = selection->Collapse(startNode,startpos.mContentOffset); + if (NS_FAILED(rv)) + return rv; + rv = selection->Extend(endNode,endpos.mContentOffset); + if (NS_FAILED(rv)) + return rv; + } + //no release + } + } + } return NS_OK; } @@ -1692,10 +1766,10 @@ nsFrame::GetPointFromOffset(nsIPresContext* inPresContext, nsIRenderingContext* } NS_IMETHODIMP -nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFrameContentOffset, nsIFrame **outChildFrame) +nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame **outChildFrame) { NS_PRECONDITION(outChildFrame && outFrameContentOffset, "Null parameter"); - *outFrameContentOffset = 0; + *outFrameContentOffset = (PRInt32)inHint; *outChildFrame = this; return NS_OK; } diff --git a/layout/html/base/src/nsFrame.h b/layout/html/base/src/nsFrame.h index 607488390056..5d933c296eea 100644 --- a/layout/html/base/src/nsFrame.h +++ b/layout/html/base/src/nsFrame.h @@ -180,6 +180,7 @@ public: nsPoint* outPoint); NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); diff --git a/layout/html/base/src/nsTextFrame.cpp b/layout/html/base/src/nsTextFrame.cpp index fc6a6f9c4a54..4d5b1fe8ba65 100644 --- a/layout/html/base/src/nsTextFrame.cpp +++ b/layout/html/base/src/nsTextFrame.cpp @@ -260,6 +260,7 @@ public: nsPoint* outPoint); NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); @@ -1916,6 +1917,7 @@ nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext, NS_IMETHODIMP nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, + PRBool inHint, PRInt32* outFrameContentOffset, nsIFrame **outChildFrame) { @@ -1927,13 +1929,13 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, if (contentOffset != -1) //-1 signified the end of the current content contentOffset = inContentOffset - mContentOffset; - if (contentOffset > mContentLength) + if ((contentOffset > mContentLength) || ((contentOffset == mContentLength) && inHint) ) { //this is not the frame we are looking for. nsIFrame *nextInFlow; nextInFlow = GetNextInFlow(); if (nextInFlow) - return nextInFlow->GetChildFrameContainingOffset(inContentOffset, outFrameContentOffset, outChildFrame); + return nextInFlow->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset, outChildFrame); else return NS_ERROR_FAILURE; } @@ -1941,7 +1943,7 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, { result = GetPrevInFlow(outChildFrame); if (NS_SUCCEEDED(result)) - return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, + return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset,outChildFrame); else return result; @@ -1992,10 +1994,10 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos) PRInt32 textLength; nsresult result(NS_OK); + aPos->mResultContent = mContent;//do this right off switch (aPos->mAmount){ case eSelectNoAmount : { - aPos->mResultContent = mContent; aPos->mContentOffset = aPos->mStartOffset; } break; @@ -2161,8 +2163,8 @@ printf("2-GetNextWord return non null, wordLen%d, contentLen%d isWhitespace=%s\n printf("aEatingWS = %s\n" , aPos->mEatingWS ? "TRUE" : "FALSE"); #endif if (!found || (aPos->mContentOffset > (mContentOffset + mContentLength)) || (aPos->mContentOffset < mContentOffset)){ //gone too far - aPos->mStartOffset = start; if (frameUsed){ + aPos->mStartOffset = start; result = frameUsed->PeekOffset(aPos); } else {//reached end ask the frame for help @@ -2185,7 +2187,7 @@ printf("aEatingWS = %s\n" , aPos->mEatingWS ? "TRUE" : "FALSE"); } if (NS_FAILED(result)){ aPos->mResultContent = mContent; - aPos->mContentOffset = aPos->mStartOffset; + //aPos->mContentOffset = aPos->mStartOffset; result = NS_OK; } aPos->mResultFrame = this; @@ -2200,7 +2202,9 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, if (!DisplaySelection(aPresContext)) { return NS_OK; } - + nsMouseEvent *me = (nsMouseEvent *)aEvent; + if (me->clickCount > 2) + return nsFrame::HandleMultiplePress(aPresContext,aEvent,aEventStatus); nsCOMPtr shell; nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); if (NS_SUCCEEDED(rv) && shell) { @@ -2240,7 +2244,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext, eDirNext, startPos, PR_FALSE, - PR_TRUE); + PR_FALSE); rv = PeekOffset(&endpos); if (NS_FAILED(rv)) return rv;