diff --git a/layout/base/public/nsIFrame.h b/layout/base/public/nsIFrame.h index f435a504d26..9dd2fbc0ff5 100644 --- a/layout/base/public/nsIFrame.h +++ b/layout/base/public/nsIFrame.h @@ -160,7 +160,8 @@ enum nsSelectionAmount { eSelectLine = 2, //previous drawn line in flow. eSelectBeginLine = 3, eSelectEndLine = 4, - eSelectNoAmount = 5 //just bounce back current offset. + eSelectNoAmount = 5, //just bounce back current offset. + eSelectDir = 6 //select next/previous frame based on direction }; enum nsDirection { diff --git a/layout/base/src/nsRangeList.cpp b/layout/base/src/nsRangeList.cpp index 511fba6e095..06fe9635c19 100644 --- a/layout/base/src/nsRangeList.cpp +++ b/layout/base/src/nsRangeList.cpp @@ -816,6 +816,7 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) pos.SetData(mTracker, desiredX, amount, eDirPrevious, offsetused, PR_FALSE,PR_TRUE); switch (keyEvent->keyCode){ case nsIDOMUIEvent::DOM_VK_RIGHT : + InvalidateDesiredX(); pos.mDirection = eDirNext; mHint = HINTLEFT;//stick to this line break; @@ -831,11 +832,13 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent) pos.mAmount = eSelectLine; break; case nsIDOMUIEvent::DOM_VK_HOME : + InvalidateDesiredX(); pos.mAmount = eSelectBeginLine; InvalidateDesiredX(); mHint = HINTRIGHT;//stick to opposite of movement break; case nsIDOMUIEvent::DOM_VK_END : + InvalidateDesiredX(); pos.mAmount = eSelectEndLine; InvalidateDesiredX(); mHint = HINTLEFT;//stick to this line diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index f9701405d65..f98ec88b314 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -731,9 +731,12 @@ nsFrame::HandleEvent(nsIPresContext& aPresContext, } } */ - if (aEvent->message == NS_MOUSE_MOVE) { - nsCOMPtr shell; - nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + switch (aEvent->message) + { + case NS_MOUSE_MOVE: + { if (NS_SUCCEEDED(rv)){ nsCOMPtr frameselection; if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ @@ -743,59 +746,56 @@ nsFrame::HandleEvent(nsIPresContext& aPresContext, #if NORMAL_DRAG_HANDLING HandleDrag(aPresContext, aEvent, aEventStatus); #else - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { - nsCOMPtr trans; - rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, - nsITransferable::GetIID(), getter_AddRefs(trans)); - nsCOMPtr trans2; - rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, - nsITransferable::GetIID(), getter_AddRefs(trans2)); - if ( trans && trans2 ) { - nsString textPlainFlavor ( "text/plain" ); - trans->AddDataFlavor(&textPlainFlavor); - nsString dragText = "Drag Text"; - PRUint32 len = 9; - trans->SetTransferData(&textPlainFlavor, dragText.ToNewCString(), len); // transferable consumes the data + nsIDragService* dragService; + nsresult rv = nsServiceManager::GetService(kCDragServiceCID, + nsIDragService::GetIID(), + (nsISupports **)&dragService); + if (NS_OK == rv) { + nsCOMPtr trans; + rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, + nsITransferable::GetIID(), getter_AddRefs(trans)); + nsCOMPtr trans2; + rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, + nsITransferable::GetIID(), getter_AddRefs(trans2)); + if ( trans && trans2 ) { + nsString textPlainFlavor ( "text/plain" ); + trans->AddDataFlavor(&textPlainFlavor); + nsString dragText = "Drag Text"; + PRUint32 len = 9; + trans->SetTransferData(&textPlainFlavor, dragText.ToNewCString(), len); // transferable consumes the data - trans2->AddDataFlavor(&textPlainFlavor); - nsString dragText2 = "More Drag Text"; - len = 14; - trans2->SetTransferData(&textPlainFlavor, dragText2.ToNewCString(), len); // transferable consumes the data + trans2->AddDataFlavor(&textPlainFlavor); + nsString dragText2 = "More Drag Text"; + len = 14; + trans2->SetTransferData(&textPlainFlavor, dragText2.ToNewCString(), len); // transferable consumes the data - nsCOMPtr items; - NS_NewISupportsArray(getter_AddRefs(items)); - if ( items ) { - items->AppendElement(trans); - items->AppendElement(trans2); - dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE); - } - } - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); - } -//--------------------------------------------------- + nsCOMPtr items; + NS_NewISupportsArray(getter_AddRefs(items)); + if ( items ) { + items->AppendElement(trans); + items->AppendElement(trans2); + dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE); + } + } + nsServiceManager::ReleaseService(kCDragServiceCID, dragService); + } + //--------------------------------------------------- #endif + } } } - } - } - else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) { - if (((nsMouseEvent*)aEvent)->clickCount > 1) { - HandleMultiplePress(aPresContext, aEvent, aEventStatus); - } - else { + }break; + case NS_MOUSE_LEFT_BUTTON_DOWN: + { + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection) + frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here HandlePress(aPresContext, aEvent, aEventStatus); - } - } - else if (aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK) { - HandleMultiplePress(aPresContext, aEvent, aEventStatus); - } - - + }break; + default: + break; + }//end switch return NS_OK; } @@ -811,8 +811,8 @@ nsFrame::HandlePress(nsIPresContext& aPresContext, return NS_OK; } nsMouseEvent *me = (nsMouseEvent *)aEvent; - if (me->clickCount >2 ) - return nsFrame::HandleMultiplePress(aPresContext,aEvent,aEventStatus); + if (me->clickCount >1 ) + return HandleMultiplePress(aPresContext,aEvent,aEventStatus); nsCOMPtr shell; nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); @@ -848,12 +848,13 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext, 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; @@ -1027,7 +1028,7 @@ NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aCX, if (aXCoord > (rect.width + rect.x)) aContentOffset++; #endif - aContentOffsetEnd = aContentOffset; + aContentOffsetEnd = aContentOffset+1; } return result; } @@ -1900,6 +1901,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, if (NS_FAILED(result)) return result; nsISupports *isupports = nsnull; + PRInt32 contentOffsetEnd;//not used nsIFrame *storeOldResultFrame = resultFrame; while ( !found ){ nsCOMPtr context; @@ -1908,7 +1910,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, result = resultFrame->GetPosition(*(context.get()),aDesiredX, aResultContent, *aContentOffset, - *aContentOffset); + contentOffsetEnd); if (NS_SUCCEEDED(result)) found = PR_TRUE; else { @@ -1939,7 +1941,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, result = resultFrame->GetPosition(*(context.get()),aDesiredX, aResultContent, *aContentOffset, - *aContentOffset); + contentOffsetEnd); if (NS_SUCCEEDED(result)) found = PR_TRUE; else { @@ -1979,7 +1981,19 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) if (!aPos || !aPos->mTracker ) return NS_ERROR_NULL_POINTER; nsresult result = NS_ERROR_FAILURE; + PRInt32 endoffset; switch (aPos->mAmount){ + case eSelectNoAmount: + { + nsCOMPtr context; + result = aPos->mTracker->GetPresContext(getter_AddRefs(context)); + if (NS_FAILED(result) || !context) + return result; + result = GetPosition(*(context.get()),0, + getter_AddRefs(aPos->mResultContent), + aPos->mContentOffset, + endoffset); + }break; case eSelectLine : { nsCOMPtr it; @@ -2095,7 +2109,7 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) result = firstFrame->GetPosition(*(context.get()),0, getter_AddRefs(aPos->mResultContent), aPos->mContentOffset, - aPos->mContentOffset); + endoffset); } } else @@ -2119,7 +2133,7 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) 2*usedRect.width,//2* just to be sure we are off the edge getter_AddRefs(aPos->mResultContent), aPos->mContentOffset, - aPos->mContentOffset); + endoffset); if (NS_SUCCEEDED(result)) found = PR_TRUE; else @@ -2197,6 +2211,8 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) } } + if (aPos->mAmount == eSelectDir) + aPos->mAmount = eSelectNoAmount;//just get to next frame. nsCOMPtr frameTraversal; result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this); if (NS_FAILED(result)) diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index f435a504d26..9dd2fbc0ff5 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -160,7 +160,8 @@ enum nsSelectionAmount { eSelectLine = 2, //previous drawn line in flow. eSelectBeginLine = 3, eSelectEndLine = 4, - eSelectNoAmount = 5 //just bounce back current offset. + eSelectNoAmount = 5, //just bounce back current offset. + eSelectDir = 6 //select next/previous frame based on direction }; enum nsDirection { diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 005159f4071..a2e09ac08c9 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -2088,8 +2088,29 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos) switch (aPos->mAmount){ case eSelectNoAmount: { - aPos->mContentOffset = aPos->mStartOffset; - result = NS_OK; + // Transform text from content into renderable form + nsIDocument* doc; + result = mContent->GetDocument(doc); + if (NS_FAILED(result) || !doc) { + return result; + } + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + NS_RELEASE(doc); + + nsTextTransformer tx(lb, nsnull); + PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength); + + if (textLength)//if no renderable length, you cant park here. + { + aPos->mContentOffset = aPos->mStartOffset; + result = NS_OK; + } + else + { + aPos->mAmount = eSelectDir;//go to "next" or previous frame based on direction not THIS frame + result = nsFrame::PeekOffset(aPos); + } } break; diff --git a/layout/html/base/src/nsFrame.cpp b/layout/html/base/src/nsFrame.cpp index f9701405d65..f98ec88b314 100644 --- a/layout/html/base/src/nsFrame.cpp +++ b/layout/html/base/src/nsFrame.cpp @@ -731,9 +731,12 @@ nsFrame::HandleEvent(nsIPresContext& aPresContext, } } */ - if (aEvent->message == NS_MOUSE_MOVE) { - nsCOMPtr shell; - nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + nsCOMPtr shell; + nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); + switch (aEvent->message) + { + case NS_MOUSE_MOVE: + { if (NS_SUCCEEDED(rv)){ nsCOMPtr frameselection; if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ @@ -743,59 +746,56 @@ nsFrame::HandleEvent(nsIPresContext& aPresContext, #if NORMAL_DRAG_HANDLING HandleDrag(aPresContext, aEvent, aEventStatus); #else - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { - nsCOMPtr trans; - rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, - nsITransferable::GetIID(), getter_AddRefs(trans)); - nsCOMPtr trans2; - rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, - nsITransferable::GetIID(), getter_AddRefs(trans2)); - if ( trans && trans2 ) { - nsString textPlainFlavor ( "text/plain" ); - trans->AddDataFlavor(&textPlainFlavor); - nsString dragText = "Drag Text"; - PRUint32 len = 9; - trans->SetTransferData(&textPlainFlavor, dragText.ToNewCString(), len); // transferable consumes the data + nsIDragService* dragService; + nsresult rv = nsServiceManager::GetService(kCDragServiceCID, + nsIDragService::GetIID(), + (nsISupports **)&dragService); + if (NS_OK == rv) { + nsCOMPtr trans; + rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, + nsITransferable::GetIID(), getter_AddRefs(trans)); + nsCOMPtr trans2; + rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, + nsITransferable::GetIID(), getter_AddRefs(trans2)); + if ( trans && trans2 ) { + nsString textPlainFlavor ( "text/plain" ); + trans->AddDataFlavor(&textPlainFlavor); + nsString dragText = "Drag Text"; + PRUint32 len = 9; + trans->SetTransferData(&textPlainFlavor, dragText.ToNewCString(), len); // transferable consumes the data - trans2->AddDataFlavor(&textPlainFlavor); - nsString dragText2 = "More Drag Text"; - len = 14; - trans2->SetTransferData(&textPlainFlavor, dragText2.ToNewCString(), len); // transferable consumes the data + trans2->AddDataFlavor(&textPlainFlavor); + nsString dragText2 = "More Drag Text"; + len = 14; + trans2->SetTransferData(&textPlainFlavor, dragText2.ToNewCString(), len); // transferable consumes the data - nsCOMPtr items; - NS_NewISupportsArray(getter_AddRefs(items)); - if ( items ) { - items->AppendElement(trans); - items->AppendElement(trans2); - dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE); - } - } - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); - } -//--------------------------------------------------- + nsCOMPtr items; + NS_NewISupportsArray(getter_AddRefs(items)); + if ( items ) { + items->AppendElement(trans); + items->AppendElement(trans2); + dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE); + } + } + nsServiceManager::ReleaseService(kCDragServiceCID, dragService); + } + //--------------------------------------------------- #endif + } } } - } - } - else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) { - if (((nsMouseEvent*)aEvent)->clickCount > 1) { - HandleMultiplePress(aPresContext, aEvent, aEventStatus); - } - else { + }break; + case NS_MOUSE_LEFT_BUTTON_DOWN: + { + nsCOMPtr frameselection; + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection) + frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here HandlePress(aPresContext, aEvent, aEventStatus); - } - } - else if (aEvent->message == NS_MOUSE_LEFT_DOUBLECLICK) { - HandleMultiplePress(aPresContext, aEvent, aEventStatus); - } - - + }break; + default: + break; + }//end switch return NS_OK; } @@ -811,8 +811,8 @@ nsFrame::HandlePress(nsIPresContext& aPresContext, return NS_OK; } nsMouseEvent *me = (nsMouseEvent *)aEvent; - if (me->clickCount >2 ) - return nsFrame::HandleMultiplePress(aPresContext,aEvent,aEventStatus); + if (me->clickCount >1 ) + return HandleMultiplePress(aPresContext,aEvent,aEventStatus); nsCOMPtr shell; nsresult rv = aPresContext.GetShell(getter_AddRefs(shell)); @@ -848,12 +848,13 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext, 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; @@ -1027,7 +1028,7 @@ NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aCX, if (aXCoord > (rect.width + rect.x)) aContentOffset++; #endif - aContentOffsetEnd = aContentOffset; + aContentOffsetEnd = aContentOffset+1; } return result; } @@ -1900,6 +1901,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, if (NS_FAILED(result)) return result; nsISupports *isupports = nsnull; + PRInt32 contentOffsetEnd;//not used nsIFrame *storeOldResultFrame = resultFrame; while ( !found ){ nsCOMPtr context; @@ -1908,7 +1910,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, result = resultFrame->GetPosition(*(context.get()),aDesiredX, aResultContent, *aContentOffset, - *aContentOffset); + contentOffsetEnd); if (NS_SUCCEEDED(result)) found = PR_TRUE; else { @@ -1939,7 +1941,7 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIFocusTracker *aTracker, result = resultFrame->GetPosition(*(context.get()),aDesiredX, aResultContent, *aContentOffset, - *aContentOffset); + contentOffsetEnd); if (NS_SUCCEEDED(result)) found = PR_TRUE; else { @@ -1979,7 +1981,19 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) if (!aPos || !aPos->mTracker ) return NS_ERROR_NULL_POINTER; nsresult result = NS_ERROR_FAILURE; + PRInt32 endoffset; switch (aPos->mAmount){ + case eSelectNoAmount: + { + nsCOMPtr context; + result = aPos->mTracker->GetPresContext(getter_AddRefs(context)); + if (NS_FAILED(result) || !context) + return result; + result = GetPosition(*(context.get()),0, + getter_AddRefs(aPos->mResultContent), + aPos->mContentOffset, + endoffset); + }break; case eSelectLine : { nsCOMPtr it; @@ -2095,7 +2109,7 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) result = firstFrame->GetPosition(*(context.get()),0, getter_AddRefs(aPos->mResultContent), aPos->mContentOffset, - aPos->mContentOffset); + endoffset); } } else @@ -2119,7 +2133,7 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) 2*usedRect.width,//2* just to be sure we are off the edge getter_AddRefs(aPos->mResultContent), aPos->mContentOffset, - aPos->mContentOffset); + endoffset); if (NS_SUCCEEDED(result)) found = PR_TRUE; else @@ -2197,6 +2211,8 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos) } } + if (aPos->mAmount == eSelectDir) + aPos->mAmount = eSelectNoAmount;//just get to next frame. nsCOMPtr frameTraversal; result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this); if (NS_FAILED(result)) diff --git a/layout/html/base/src/nsTextFrame.cpp b/layout/html/base/src/nsTextFrame.cpp index 005159f4071..a2e09ac08c9 100644 --- a/layout/html/base/src/nsTextFrame.cpp +++ b/layout/html/base/src/nsTextFrame.cpp @@ -2088,8 +2088,29 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos) switch (aPos->mAmount){ case eSelectNoAmount: { - aPos->mContentOffset = aPos->mStartOffset; - result = NS_OK; + // Transform text from content into renderable form + nsIDocument* doc; + result = mContent->GetDocument(doc); + if (NS_FAILED(result) || !doc) { + return result; + } + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + NS_RELEASE(doc); + + nsTextTransformer tx(lb, nsnull); + PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength); + + if (textLength)//if no renderable length, you cant park here. + { + aPos->mContentOffset = aPos->mStartOffset; + result = NS_OK; + } + else + { + aPos->mAmount = eSelectDir;//go to "next" or previous frame based on direction not THIS frame + result = nsFrame::PeekOffset(aPos); + } } break;