Bug 458089: Kill VISUALSELECTION code. r=smontagu, sr=roc.

This commit is contained in:
Uri Bernstein 2008-10-09 12:05:30 +02:00
Родитель dab1586173
Коммит 361456a3f9
2 изменённых файлов: 2 добавлений и 472 удалений

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

@ -570,27 +570,6 @@ private:
PRUint32 aContentOffset,
HINT aHint,
PRBool aJumpLines) const;
#ifdef VISUALSELECTION
NS_IMETHOD VisualSelectFrames(nsIFrame* aCurrentFrame,
nsPeekOffsetStruct aPos);
NS_IMETHOD VisualSequence(nsIFrame* aSelectFrame,
nsIFrame* aCurrentFrame,
nsPeekOffsetStruct* aPos,
PRBool* aNeedVisualSelection);
NS_IMETHOD SelectToEdge(nsIFrame *aFrame,
nsIContent *aContent,
PRInt32 aOffset,
PRInt32 aEdge,
PRBool aMultipleSelection);
NS_IMETHOD SelectLines(nsDirection aSelectionDirection,
nsIDOMNode *aAnchorNode,
nsIFrame* aAnchorFrame,
PRInt32 aAnchorOffset,
nsIDOMNode *aCurrentNode,
nsIFrame* aCurrentFrame,
PRInt32 aCurrentOffset,
nsPeekOffsetStruct aPos);
#endif // VISUALSELECTION
PRBool AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset);

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

@ -1406,21 +1406,7 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
else
BidiLevelFromMove(mShell, pos.mResultContent, pos.mContentOffset, aKeycode, tHint);
}
#ifdef VISUALSELECTION
// Handle visual selection
if (aContinueSelection)
{
result = VisualSelectFrames(theFrame, pos);
if (NS_FAILED(result)) // Back out by collapsing the selection to the current position
result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, PR_FALSE, PR_FALSE);
}
else
result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, aContinueSelection, PR_FALSE);
}
else
#else
}
#endif // VISUALSELECTION
result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, aContinueSelection, PR_FALSE);
} else if (aKeycode == nsIDOMKeyEvent::DOM_VK_RIGHT && !aContinueSelection) {
// Collapse selection if PeekOffset failed, we either
@ -1529,418 +1515,6 @@ nsTypedSelection::GetInterlinePosition(PRBool *aHintRight)
return NS_OK;
}
#ifdef VISUALSELECTION
static nsDirection
ReverseDirection(nsDirection aDirection)
{
return (eDirNext == aDirection) ? eDirPrevious : eDirNext;
}
static nsresult
FindLineContaining(nsIFrame* aFrame, nsIFrame** aBlock, PRInt32* aLine)
{
nsIFrame *blockFrame = aFrame;
nsIFrame *thisBlock = nsnull;
nsCOMPtr<nsILineIteratorNavigator> it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
blockFrame = blockFrame->GetParent();
if (blockFrame) {
it = do_QueryInterface(blockFrame, &result);
}
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
*aBlock = blockFrame;
return it->FindLineContaining(thisBlock, aLine);
}
NS_IMETHODIMP
nsFrameSelection::VisualSequence(nsIFrame* aSelectFrame,
nsIFrame* aCurrentFrame,
nsPeekOffsetStruct* aPos,
PRBool* aNeedVisualSelection)
{
nsVoidArray frameArray;
PRInt32 frameStart, frameEnd;
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
nsresult result = nsnull;
PRUint8 currentLevel = NS_GET_EMBEDDING_LEVEL(aCurrentFrame);
result = aSelectFrame->PeekOffset(aPos);
while (aCurrentFrame != (aSelectFrame = aPos->mResultFrame))
{
if (NS_FAILED(result))
return NS_OK; // we have passed the end of the line, and we will carry on from there
if (!aSelectFrame)
return NS_ERROR_FAILURE;
if (frameArray.IndexOf(aSelectFrame) > -1)
// If we have already seen this frame, we must be in an infinite loop
return NS_OK;
else
frameArray.AppendElement(aSelectFrame);
aSelectFrame->GetOffsets(frameStart, frameEnd);
PRUint8 bidiLevel = NS_GET_EMBEDDING_LEVEL(aSelectFrame);
if (currentLevel != bidiLevel)
*aNeedVisualSelection = PR_TRUE;
if ((eDirNext == aPos->mDirection) == (bidiLevel & 1))
{
mDomSelections[index]->SetDirection(eDirPrevious);
result = TakeFocus(aPos->mResultContent, frameEnd, frameStart, PR_FALSE, PR_TRUE);
}
else
{
mDomSelections[index]->SetDirection(eDirNext);
result = TakeFocus(aPos->mResultContent, frameStart, frameEnd, PR_FALSE, PR_TRUE);
}
if (NS_FAILED(result))
return result;
aPos->mAmount = eSelectDir; // reset this because PeekOffset will have changed it to eSelectNoAmount
aPos->mContentOffset = 0;
result = aSelectFrame->PeekOffset(aPos);
}
return NS_OK;
}
NS_IMETHODIMP
nsFrameSelection::SelectToEdge(nsIFrame *aFrame,
nsIContent *aContent,
PRInt32 aOffset,
PRInt32 aEdge,
PRBool aMultipleSelection)
{
PRInt32 frameStart, frameEnd;
aFrame->GetOffsets(frameStart, frameEnd);
if (0 == aEdge)
aEdge = frameStart;
else if (-1 == aEdge)
aEdge = frameEnd;
if (0 == aOffset)
aOffset = frameStart;
else if (-1 == aOffset)
aOffset = frameEnd;
return TakeFocus(aContent, aOffset, aEdge, PR_FALSE, aMultipleSelection);
}
NS_IMETHODIMP
nsFrameSelection::SelectLines(nsDirection aSelectionDirection,
nsIDOMNode *aAnchorNode,
nsIFrame* aAnchorFrame,
PRInt32 aAnchorOffset,
nsIDOMNode *aCurrentNode,
nsIFrame* aCurrentFrame,
PRInt32 aCurrentOffset,
nsPeekOffsetStruct aPos)
{
nsIFrame *startFrame, *endFrame;
PRInt32 startOffset, endOffset;
PRInt32 relativePosition;
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
nsIContent *startContent;
nsIContent *endContent;
nsresult result;
// normalize the order before we start to avoid piles of conditions later
relativePosition = CompareDOMPoints(aAnchorNode, aAnchorOffset,
aCurrentNode, aCurrentOffset);
if (0 == relativePosition)
return NS_ERROR_FAILURE;
else if (relativePosition < 0)
{
startNode = aAnchorNode;
startFrame = aAnchorFrame;
startOffset = aAnchorOffset;
endNode = aCurrentNode;
endFrame = aCurrentFrame;
endOffset = aCurrentOffset;
}
else
{
startNode = aCurrentNode;
startFrame = aCurrentFrame;
startOffset = aCurrentOffset;
endNode = aAnchorNode;
endFrame = aAnchorFrame;
endOffset = aAnchorOffset;
}
aPos.mStartOffset = startOffset;
aPos.mDirection = eDirNext;
aPos.mAmount = eSelectLine;
result = startFrame->PeekOffset(&aPos);
if (NS_FAILED(result))
return result;
startFrame = aPos.mResultFrame;
aPos.mStartOffset = aPos.mContentOffset;
aPos.mAmount = eSelectBeginLine;
result = startFrame->PeekOffset(&aPos);
if (NS_FAILED(result))
return result;
nsIFrame *theFrame;
PRInt32 currentOffset, frameStart, frameEnd;
theFrame = GetFrameForNodeOffset(aPos.mResultContent, aPos.mContentOffset,
HINTLEFT, &currentOffset);
if (!theFrame)
return NS_ERROR_FAILURE;
theFrame->GetOffsets(frameStart, frameEnd);
startOffset = frameStart;
startContent = aPos.mResultContent;
startNode = do_QueryInterface(startContent);
// If we have already overshot the endpoint, back out
if (CompareDOMPoints(startNode, startOffset, endNode, endOffset) >= 0)
return NS_ERROR_FAILURE;
aPos.mStartOffset = endOffset;
aPos.mDirection = eDirPrevious;
aPos.mAmount = eSelectLine;
result = endFrame->PeekOffset(&aPos);
if (NS_FAILED(result))
return result;
endFrame = aPos.mResultFrame;
aPos.mStartOffset = aPos.mContentOffset;
aPos.mAmount = eSelectEndLine;
result = endFrame->PeekOffset(&aPos);
if (NS_FAILED(result))
return result;
theFrame = GetFrameForNodeOffset(aPos.mResultContent, aPos.mContentOffset,
HINTRIGHT, &currentOffset);
if (!theFrame)
return NS_ERROR_FAILURE;
theFrame->GetOffsets(frameStart, frameEnd);
endOffset = frameEnd;
endContent = aPos.mResultContent;
endNode = do_QueryInterface(endContent);
if (CompareDOMPoints(startNode, startOffset, endNode, endOffset) < 0)
{
TakeFocus(startContent, startOffset, startOffset, PR_FALSE, PR_TRUE);
return TakeFocus(endContent, endOffset, endOffset, PR_TRUE, PR_TRUE);
}
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsFrameSelection::VisualSelectFrames(nsIFrame* aCurrentFrame,
nsPeekOffsetStruct aPos)
{
nsCOMPtr<nsIContent> anchorContent;
nsCOMPtr<nsIDOMNode> anchorNode;
PRInt32 anchorOffset;
nsIFrame* anchorFrame;
nsCOMPtr<nsIContent> focusContent;
nsCOMPtr<nsIDOMNode> focusNode;
PRInt32 focusOffset;
nsIFrame* focusFrame;
nsCOMPtr<nsIContent> currentContent;
nsCOMPtr<nsIDOMNode> currentNode;
PRInt32 currentOffset;
nsresult result;
nsIFrame* startFrame;
PRBool needVisualSelection = PR_FALSE;
nsDirection selectionDirection;
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
result = mDomSelections[index]->GetOriginalAnchorPoint(getter_AddRefs(anchorNode), &anchorOffset);
if (NS_FAILED(result))
return result;
anchorContent = do_QueryInterface(anchorNode);
anchorFrame = GetFrameForNodeOffset(anchorContent, anchorOffset,
mHint, &anchorOffset);
if (!anchorFrame)
return NS_ERROR_FAILURE;
PRUint8 anchorLevel = NS_GET_EMBEDDING_LEVEL(anchorFrame);
currentContent = aPos.mResultContent;
currentNode = do_QueryInterface(currentContent);
currentOffset = aPos.mContentOffset;
PRUint8 currentLevel = NS_GET_EMBEDDING_LEVEL(aCurrentFrame);
// Moving from simplest case to more complicated:
// case 1: selection starts and ends in the same frame: no special treatment
if (anchorFrame == aCurrentFrame) {
mDomSelections[index]->SetTrueDirection(!(anchorLevel & 1));
return TakeFocus(currentContent, anchorOffset, currentOffset, PR_FALSE, PR_FALSE);
}
focusOffset = mDomSelections[index]->FetchFocusOffset();
focusNode = mDomSelections[index]->FetchFocusNode();
focusContent = do_QueryInterface(focusNode);
HINT hint;
if ((HINTLEFT == mHint) == (currentLevel & 1))
hint = HINTRIGHT;
else
hint = HINTLEFT;
focusFrame = GetFrameForNodeOffset(focusContent, focusOffset,
hint, &focusOffset);
if (!focusFrame)
return NS_ERROR_FAILURE;
PRUint8 focusLevel = NS_GET_EMBEDDING_LEVEL(focusFrame);
if (currentLevel != anchorLevel)
needVisualSelection = PR_TRUE;
// Make sure of the selection direction
selectionDirection = mDomSelections[index]->GetDirection();
if (!mDomSelections[index]->GetTrueDirection()) {
selectionDirection = ReverseDirection(selectionDirection);
mDomSelections[index]->SetDirection(selectionDirection);
}
PRInt32 anchorLine, currentLine;
nsIFrame* anchorBlock = nsnull;
nsIFrame* currentBlock = nsnull;
FindLineContaining(anchorFrame, &anchorBlock, &anchorLine);
FindLineContaining(aCurrentFrame, &currentBlock, &currentLine);
if (anchorBlock==currentBlock && anchorLine==currentLine)
{
// case 2: selection starts and ends in the same line
// Select from the anchor point to the edge of the frame
// Which edge? If the selection direction is forward the right edge, if it is backward the left edge
// For rtl frames the right edge is the beginning of the frame, for ltr frames it is the end and vice versa
if ((eDirNext == selectionDirection) == (anchorLevel & 1))
result = SelectToEdge(anchorFrame, anchorContent, anchorOffset, 0, PR_FALSE);
else
result = SelectToEdge(anchorFrame, anchorContent, anchorOffset, -1, PR_FALSE);
if (NS_FAILED(result))
return result;
// Walk the frames in visual order until we reach the current frame, selecting each frame as we go
InvalidateDesiredX();
aPos.mAmount = eSelectDir;
aPos.mStartOffset = anchorOffset;
aPos.mDirection = selectionDirection;
result = anchorFrame->PeekOffset(&aPos);
if (NS_FAILED(result))
return result;
startFrame = aPos.mResultFrame;
result = VisualSequence(startFrame, aCurrentFrame, &aPos, &needVisualSelection);
if (NS_FAILED(result))
return result;
if (!needVisualSelection)
{
if (currentLevel & 1)
mDomSelections[index]->SetDirection(ReverseDirection(selectionDirection));
// all the frames we passed through had the same Bidi level, so we can back out and do an ordinary selection
result = TakeFocus(anchorContent, anchorOffset, anchorOffset, PR_FALSE, PR_FALSE);
if (NS_FAILED(result))
return result;
result = TakeFocus(currentContent, currentOffset, currentOffset, PR_TRUE, PR_FALSE);
if (NS_FAILED(result))
return result;
}
else {
if ((currentLevel & 1) != (focusLevel & 1))
mDomSelections[index]->SetDirection(ReverseDirection(selectionDirection));
// Select from the current point to the edge of the frame
if ((eDirNext == selectionDirection) == (currentLevel & 1))
result = SelectToEdge(aCurrentFrame, currentContent, -1, currentOffset, PR_TRUE);
else
result = SelectToEdge(aCurrentFrame, currentContent, 0, currentOffset, PR_TRUE);
if (NS_FAILED(result))
return result;
}
}
else {
// case 3: selection starts and ends in different lines
// If selection direction is forwards:
// Select from the anchor point to the edge of the frame in the direction of the end of the line
// i.e. the rightmost character if the current paragraph embedding level is even (LTR paragraph)
// or the leftmost character if the current paragraph embedding level is odd (RTL paragraph)
//
// As before, for rtl frames the right edge is the beginning of the frame, for ltr frames it is the end and vice versa
//
// If selection direction is backwards, vice versa throughout
//
PRUint8 anchorBaseLevel = NS_GET_BASE_LEVEL(anchorFrame);
if ((eDirNext == selectionDirection) != ((anchorLevel & 1) == (anchorBaseLevel & 1)))
result = SelectToEdge(anchorFrame, anchorContent, anchorOffset, 0, PR_FALSE);
else
result = SelectToEdge(anchorFrame, anchorContent, anchorOffset, -1, PR_FALSE);
if (NS_FAILED(result))
return result;
// Walk the frames in visual order until we reach the end of the line
aPos.mJumpLines = PR_FALSE;
aPos.mAmount = eSelectDir;
aPos.mStartOffset = anchorOffset;
aPos.mDirection = selectionDirection;
if (anchorBaseLevel & 1)
aPos.mDirection = ReverseDirection(aPos.mDirection);
result = VisualSequence(anchorFrame, aCurrentFrame, &aPos, &needVisualSelection);
if (NS_FAILED(result))
return result;
// Select all the lines between the line containing the anchor point and the line containing the current point
aPos.mJumpLines = PR_TRUE;
result = SelectLines(selectionDirection, anchorNode, anchorFrame,
anchorOffset, currentNode, aCurrentFrame, currentOffset,
aPos);
if (NS_FAILED(result))
return result;
// Go to the current point
PRUint8 currentBaseLevel = NS_GET_BASE_LEVEL(aCurrentFrame);
// Walk the frames in visual order until we reach the beginning of the line
aPos.mJumpLines = PR_FALSE;
if ((currentBaseLevel & 1) == (anchorBaseLevel & 1))
aPos.mDirection = ReverseDirection(aPos.mDirection);
aPos.mStartOffset = currentOffset;
result = VisualSequence(aCurrentFrame, anchorFrame, &aPos, &needVisualSelection);
if (NS_FAILED(result))
return result;
// Select from the current point to the edge of the frame
if (currentLevel & 1)
mDomSelections[index]->SetDirection(ReverseDirection(selectionDirection));
if ((eDirPrevious == selectionDirection) != ((currentLevel & 1) == (currentBaseLevel & 1)))
result = SelectToEdge(aCurrentFrame, currentContent, 0, currentOffset, PR_TRUE);
else
result = SelectToEdge(aCurrentFrame, currentContent, -1, currentOffset, PR_TRUE);
if (NS_FAILED(result))
return result;
// restore original selection direction
// mDomSelections[index]->SetDirection(selectionDirection);
}
// Sometimes we have to lie about the selection direction, so we will have to remember when we are doing so
mDomSelections[index]->SetTrueDirection(mDomSelections[index]->GetDirection() == selectionDirection);
mDomSelections[index]->SetOriginalAnchorPoint(anchorNode, anchorOffset);
NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL);
return NS_OK;
}
#endif // VISUALSELECTION
nsPrevNextBidiLevels
nsFrameSelection::GetPrevNextBidiLevels(nsIContent *aNode,
PRUint32 aContentOffset,
@ -2321,31 +1895,8 @@ nsFrameSelection::HandleDrag(nsIFrame *aFrame, nsPoint aPoint)
}
}
// XXX Code not up to date
#ifdef VISUALSELECTION
if (mShell->GetPresContext()->BidiEnabled()) {
PRUint8 level;
nsPeekOffsetStruct pos;
//set data using mLimiter to stop on scroll views. If we have a limiter then we stop peeking
//when we hit scrollable views. If no limiter then just let it go ahead
pos.SetData(eSelectDir, eDirNext, startPos, 0,
PR_TRUE, mLimiter != nsnull, PR_FALSE, PR_TRUE);
mHint = HINT(beginOfContent);
HINT saveHint = mHint;
if (NS_GET_EMBEDDING_LEVEL(newFrame) & 1)
mHint = (mHint==HINTLEFT) ? HINTRIGHT : HINTLEFT;
pos.mResultContent = newContent;
pos.mContentOffset = contentOffsetEnd;
result = VisualSelectFrames(newFrame, pos);
if (NS_FAILED(result))
HandleClick(newContent, startPos, contentOffsetEnd, PR_TRUE,
PR_FALSE, beginOfContent);
mHint = saveHint;
}
else
#endif // VISUALSELECTION
HandleClick(offsets.content, offsets.offset, offsets.offset,
PR_TRUE, PR_FALSE, offsets.associateWithNext);
HandleClick(offsets.content, offsets.offset, offsets.offset,
PR_TRUE, PR_FALSE, offsets.associateWithNext);
}
nsresult