зеркало из https://github.com/mozilla/gecko-dev.git
patch from mjudge to maintainselection; r/sr=dbaron, bug=56401
This commit is contained in:
Родитель
92f7210d18
Коммит
e6dbb06ce4
|
@ -373,8 +373,8 @@ public:
|
|||
nsDirection aDirection,
|
||||
PRUint8 aBidiLevel,
|
||||
nsIFrame **aFrameOut);
|
||||
|
||||
/*END nsIFrameSelection interfacse*/
|
||||
NS_IMETHOD MaintainSelection();
|
||||
/*END nsIFrameSelection interfaces */
|
||||
|
||||
|
||||
|
||||
|
@ -422,6 +422,8 @@ private:
|
|||
nsPeekOffsetStruct aPos);
|
||||
#endif // VISUALSELECTION
|
||||
|
||||
PRBool AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset);
|
||||
|
||||
// post and pop reasons for notifications. we may stack these later
|
||||
void PostReason(PRInt16 aReason) { mSelectionChangeReason = aReason; }
|
||||
PRInt16 PopReason()
|
||||
|
@ -486,6 +488,9 @@ private:
|
|||
PRInt32 mSelectingTableCellMode;
|
||||
PRInt32 mSelectedCellIndex;
|
||||
|
||||
// maintain selection
|
||||
nsCOMPtr<nsIDOMRange> mMaintainRange;
|
||||
|
||||
//batching
|
||||
PRInt32 mBatching;
|
||||
|
||||
|
@ -2451,6 +2456,37 @@ NS_IMETHODIMP nsSelection::GetFrameFromLevel(nsIPresContext *aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSelection::MaintainSelection()
|
||||
{
|
||||
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult rv = mDomSelections[index]->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!range)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
nsCOMPtr<nsIDOMNode> endNode;
|
||||
PRInt32 startOffset;
|
||||
PRInt32 endOffset;
|
||||
range->GetStartContainer(getter_AddRefs(startNode));
|
||||
range->GetEndContainer(getter_AddRefs(endNode));
|
||||
range->GetStartOffset(&startOffset);
|
||||
range->GetEndOffset(&endOffset);
|
||||
|
||||
mMaintainRange = nsnull;
|
||||
NS_NewRange(getter_AddRefs(mMaintainRange));
|
||||
if (!mMaintainRange)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mMaintainRange->SetStart(startNode, startOffset);
|
||||
return mMaintainRange->SetEnd(endNode, endOffset);
|
||||
}
|
||||
|
||||
|
||||
/** After moving the caret, its Bidi level is set according to the following rules:
|
||||
*
|
||||
* After moving over a character with left/right arrow, set to the Bidi level of the last moved over character.
|
||||
|
@ -2538,6 +2574,62 @@ void nsSelection::BidiLevelFromClick(nsIContent *aNode, PRUint32 aContentOffset)
|
|||
shell->SetCaretBidiLevel(frameLevel);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsSelection::AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset)
|
||||
{
|
||||
// Is the desired content and offset currently in selection?
|
||||
// If the double click flag is set then don't continue selection if the
|
||||
// desired content and offset are currently inside a selection.
|
||||
// This will stop double click then mouse-drag from undoing the desired
|
||||
// selecting of a word.
|
||||
if (!mMaintainRange)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> rangenode;
|
||||
PRInt32 rangeOffset;
|
||||
mMaintainRange->GetStartContainer(getter_AddRefs(rangenode));
|
||||
mMaintainRange->GetStartOffset(&rangeOffset);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aContent);
|
||||
if (domNode)
|
||||
{
|
||||
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
nsCOMPtr<nsIDOMNSRange> nsrange = do_QueryInterface(mMaintainRange);
|
||||
if (nsrange)
|
||||
{
|
||||
PRBool insideSelection = PR_FALSE;
|
||||
nsrange->IsPointInRange(domNode, aOffset, &insideSelection);
|
||||
|
||||
// Done when we find a range that we are in
|
||||
if (insideSelection)
|
||||
{
|
||||
mDomSelections[index]->Collapse(rangenode, rangeOffset);
|
||||
mMaintainRange->GetEndContainer(getter_AddRefs(rangenode));
|
||||
mMaintainRange->GetEndOffset(&rangeOffset);
|
||||
mDomSelections[index]->Extend(rangenode,rangeOffset);
|
||||
return PR_TRUE; // dragging in selection aborted
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 relativePosition = ComparePoints(rangenode, rangeOffset, domNode, aOffset);
|
||||
// if == 0 or -1 do nothing if < 0 then we need to swap direction
|
||||
if (relativePosition > 0
|
||||
&& (mDomSelections[index]->GetDirection() == eDirNext))
|
||||
{
|
||||
mMaintainRange->GetEndContainer(getter_AddRefs(rangenode));
|
||||
mMaintainRange->GetEndOffset(&rangeOffset);
|
||||
mDomSelections[index]->Collapse(rangenode, rangeOffset);
|
||||
}
|
||||
else if (relativePosition < 0
|
||||
&& (mDomSelections[index]->GetDirection() == eDirPrevious))
|
||||
mDomSelections[index]->Collapse(rangenode, rangeOffset);
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
|
||||
PRUint32 aContentEndOffset, PRBool aContinueSelection,
|
||||
|
@ -2545,14 +2637,22 @@ nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
|
|||
{
|
||||
if (!aNewFocus)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
InvalidateDesiredX();
|
||||
|
||||
|
||||
if (!aContinueSelection)
|
||||
mMaintainRange = nsnull;
|
||||
|
||||
mHint = HINT(aHint);
|
||||
// Don't take focus when dragging off of a table
|
||||
if (!mDragSelectingCells)
|
||||
{
|
||||
BidiLevelFromClick(aNewFocus, aContentOffset);
|
||||
PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON);
|
||||
if (aContinueSelection &&
|
||||
AdjustForMaintainedSelection(aNewFocus, aContentOffset))
|
||||
return NS_OK; //shift clicked to maintained selection. rejected.
|
||||
|
||||
return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection);
|
||||
}
|
||||
|
||||
|
@ -2569,22 +2669,12 @@ nsSelection::HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
|
|||
nsIFrame *newFrame = 0;
|
||||
nsPoint newPoint;
|
||||
|
||||
|
||||
result = ConstrainFrameAndPointToAnchorSubtree(aPresContext, aFrame, aPoint, &newFrame, newPoint);
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
if (!newFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
|
||||
result = aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
PRInt32 startPos = 0;
|
||||
PRInt32 contentOffsetEnd = 0;
|
||||
PRBool beginOfContent;
|
||||
|
@ -2594,57 +2684,9 @@ nsSelection::HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
|
|||
getter_AddRefs(newContent),
|
||||
startPos, contentOffsetEnd, beginOfContent);
|
||||
|
||||
//Is the desired content and offset currently in selection?
|
||||
//if the double click flag is set then dont continue selection if the desired content and offset
|
||||
//are currently inside a selection.
|
||||
//this will stop double click then mouse-drag from undo-ing the desired selecting of a word.
|
||||
if (mMouseDoubleDownState)
|
||||
{
|
||||
nsFrameState frameState;
|
||||
newFrame->GetFrameState(&frameState);
|
||||
PRBool insideSelection(PR_FALSE);
|
||||
if ((frameState & NS_FRAME_SELECTED_CONTENT))
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
mDomSelections[index]->GetIsCollapsed(&isCollapsed);
|
||||
if (!isCollapsed)
|
||||
{
|
||||
PRInt32 rangeCount;
|
||||
result = mDomSelections[index]->GetRangeCount(&rangeCount);
|
||||
if (NS_FAILED(result)) return result;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
domNode = do_QueryInterface(newContent);
|
||||
if (domNode)
|
||||
{
|
||||
for (PRInt32 i = 0; i < rangeCount; i++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
|
||||
result = mDomSelections[index]->GetRangeAt(i, getter_AddRefs(range));
|
||||
if (NS_FAILED(result) || !range)
|
||||
continue;//dont bail yet, iterate through them all
|
||||
|
||||
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
|
||||
if (NS_FAILED(result) || !nsrange)
|
||||
continue;//dont bail yet, iterate through them all
|
||||
|
||||
nsrange->IsPointInRange(domNode, startPos, &insideSelection);
|
||||
|
||||
// Done when we find a range that we are in
|
||||
if (insideSelection)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!insideSelection)
|
||||
mMouseDoubleDownState = PR_FALSE;
|
||||
else
|
||||
return NS_OK; //dragging in selection aborted
|
||||
}
|
||||
if ((newFrame->GetStateBits() & NS_FRAME_SELECTED_CONTENT) &&
|
||||
AdjustForMaintainedSelection(newContent, startPos))
|
||||
return NS_OK;
|
||||
|
||||
// do we have CSS that changes selection behaviour?
|
||||
{
|
||||
|
|
|
@ -423,6 +423,14 @@ public:
|
|||
*/
|
||||
NS_IMETHOD GetMouseDoubleDown(PRBool *aDoubleDown)=0;
|
||||
|
||||
/**
|
||||
* MaintainSelection will track the current selection as being "sticky".
|
||||
* Dragging or extending selection will never allow for a subset
|
||||
* (or the whole) of the maintained selection to become unselected.
|
||||
* Primary use: double click selecting then dragging on second click
|
||||
*/
|
||||
NS_IMETHOD MaintainSelection()=0;
|
||||
|
||||
#ifdef IBMBIDI
|
||||
/** GetPrevNextBidiLevels will return the frames and associated Bidi levels of the characters
|
||||
* logically before and after a (collapsed) selection.
|
||||
|
|
|
@ -423,6 +423,14 @@ public:
|
|||
*/
|
||||
NS_IMETHOD GetMouseDoubleDown(PRBool *aDoubleDown)=0;
|
||||
|
||||
/**
|
||||
* MaintainSelection will track the current selection as being "sticky".
|
||||
* Dragging or extending selection will never allow for a subset
|
||||
* (or the whole) of the maintained selection to become unselected.
|
||||
* Primary use: double click selecting then dragging on second click
|
||||
*/
|
||||
NS_IMETHOD MaintainSelection()=0;
|
||||
|
||||
#ifdef IBMBIDI
|
||||
/** GetPrevNextBidiLevels will return the frames and associated Bidi levels of the characters
|
||||
* logically before and after a (collapsed) selection.
|
||||
|
|
|
@ -473,6 +473,7 @@ public:
|
|||
NS_IMETHOD CommonPageMove(PRBool aForward, PRBool aExtend, nsIScrollableView *aScrollableView, nsIFrameSelection *aFrameSel);
|
||||
NS_IMETHOD SetMouseDoubleDown(PRBool aDoubleDown);
|
||||
NS_IMETHOD GetMouseDoubleDown(PRBool *aDoubleDown);
|
||||
NS_IMETHOD MaintainSelection();
|
||||
#ifdef IBMBIDI
|
||||
NS_IMETHOD GetPrevNextBidiLevels(nsIPresContext *aPresContext,
|
||||
nsIContent *aNode,
|
||||
|
@ -1065,6 +1066,11 @@ NS_IMETHODIMP nsTextInputSelectionImpl::GetMouseDoubleDown(PRBool *aDoubleDown)
|
|||
return mFrameSelection->GetMouseDoubleDown(aDoubleDown);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputSelectionImpl::MaintainSelection()
|
||||
{
|
||||
return mFrameSelection->MaintainSelection();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputSelectionImpl::CommonPageMove(PRBool aForward, PRBool aExtend, nsIScrollableView *aScrollableView, nsIFrameSelection *aFrameSel)
|
||||
{
|
||||
return mFrameSelection->CommonPageMove(aForward, aExtend, aScrollableView, this);
|
||||
|
|
|
@ -1549,6 +1549,9 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (startOffset != endOffset)
|
||||
frameselection->MaintainSelection();
|
||||
|
||||
if (isEditor && !me->isShift && (endOffset - startOffset) == 1)
|
||||
{
|
||||
// A single node is selected and we aren't extending an existing
|
||||
|
@ -1762,7 +1765,17 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
|||
return rv;
|
||||
}
|
||||
//no release
|
||||
return NS_OK;
|
||||
|
||||
// maintain selection
|
||||
nsCOMPtr<nsIFrameSelection> frameselection = do_QueryInterface(selcon); //this MAY implement
|
||||
if (!frameselection)
|
||||
{
|
||||
rv = aPresContext->GetPresShell()->GetFrameSelection(getter_AddRefs(frameselection));
|
||||
if (NS_FAILED(rv) || !frameselection)
|
||||
return NS_OK; // return NS_OK; we don't care if this fails
|
||||
}
|
||||
|
||||
return frameselection->MaintainSelection();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -373,8 +373,8 @@ public:
|
|||
nsDirection aDirection,
|
||||
PRUint8 aBidiLevel,
|
||||
nsIFrame **aFrameOut);
|
||||
|
||||
/*END nsIFrameSelection interfacse*/
|
||||
NS_IMETHOD MaintainSelection();
|
||||
/*END nsIFrameSelection interfaces */
|
||||
|
||||
|
||||
|
||||
|
@ -422,6 +422,8 @@ private:
|
|||
nsPeekOffsetStruct aPos);
|
||||
#endif // VISUALSELECTION
|
||||
|
||||
PRBool AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset);
|
||||
|
||||
// post and pop reasons for notifications. we may stack these later
|
||||
void PostReason(PRInt16 aReason) { mSelectionChangeReason = aReason; }
|
||||
PRInt16 PopReason()
|
||||
|
@ -486,6 +488,9 @@ private:
|
|||
PRInt32 mSelectingTableCellMode;
|
||||
PRInt32 mSelectedCellIndex;
|
||||
|
||||
// maintain selection
|
||||
nsCOMPtr<nsIDOMRange> mMaintainRange;
|
||||
|
||||
//batching
|
||||
PRInt32 mBatching;
|
||||
|
||||
|
@ -2451,6 +2456,37 @@ NS_IMETHODIMP nsSelection::GetFrameFromLevel(nsIPresContext *aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSelection::MaintainSelection()
|
||||
{
|
||||
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult rv = mDomSelections[index]->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!range)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
nsCOMPtr<nsIDOMNode> endNode;
|
||||
PRInt32 startOffset;
|
||||
PRInt32 endOffset;
|
||||
range->GetStartContainer(getter_AddRefs(startNode));
|
||||
range->GetEndContainer(getter_AddRefs(endNode));
|
||||
range->GetStartOffset(&startOffset);
|
||||
range->GetEndOffset(&endOffset);
|
||||
|
||||
mMaintainRange = nsnull;
|
||||
NS_NewRange(getter_AddRefs(mMaintainRange));
|
||||
if (!mMaintainRange)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mMaintainRange->SetStart(startNode, startOffset);
|
||||
return mMaintainRange->SetEnd(endNode, endOffset);
|
||||
}
|
||||
|
||||
|
||||
/** After moving the caret, its Bidi level is set according to the following rules:
|
||||
*
|
||||
* After moving over a character with left/right arrow, set to the Bidi level of the last moved over character.
|
||||
|
@ -2538,6 +2574,62 @@ void nsSelection::BidiLevelFromClick(nsIContent *aNode, PRUint32 aContentOffset)
|
|||
shell->SetCaretBidiLevel(frameLevel);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsSelection::AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset)
|
||||
{
|
||||
// Is the desired content and offset currently in selection?
|
||||
// If the double click flag is set then don't continue selection if the
|
||||
// desired content and offset are currently inside a selection.
|
||||
// This will stop double click then mouse-drag from undoing the desired
|
||||
// selecting of a word.
|
||||
if (!mMaintainRange)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> rangenode;
|
||||
PRInt32 rangeOffset;
|
||||
mMaintainRange->GetStartContainer(getter_AddRefs(rangenode));
|
||||
mMaintainRange->GetStartOffset(&rangeOffset);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aContent);
|
||||
if (domNode)
|
||||
{
|
||||
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
nsCOMPtr<nsIDOMNSRange> nsrange = do_QueryInterface(mMaintainRange);
|
||||
if (nsrange)
|
||||
{
|
||||
PRBool insideSelection = PR_FALSE;
|
||||
nsrange->IsPointInRange(domNode, aOffset, &insideSelection);
|
||||
|
||||
// Done when we find a range that we are in
|
||||
if (insideSelection)
|
||||
{
|
||||
mDomSelections[index]->Collapse(rangenode, rangeOffset);
|
||||
mMaintainRange->GetEndContainer(getter_AddRefs(rangenode));
|
||||
mMaintainRange->GetEndOffset(&rangeOffset);
|
||||
mDomSelections[index]->Extend(rangenode,rangeOffset);
|
||||
return PR_TRUE; // dragging in selection aborted
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 relativePosition = ComparePoints(rangenode, rangeOffset, domNode, aOffset);
|
||||
// if == 0 or -1 do nothing if < 0 then we need to swap direction
|
||||
if (relativePosition > 0
|
||||
&& (mDomSelections[index]->GetDirection() == eDirNext))
|
||||
{
|
||||
mMaintainRange->GetEndContainer(getter_AddRefs(rangenode));
|
||||
mMaintainRange->GetEndOffset(&rangeOffset);
|
||||
mDomSelections[index]->Collapse(rangenode, rangeOffset);
|
||||
}
|
||||
else if (relativePosition < 0
|
||||
&& (mDomSelections[index]->GetDirection() == eDirPrevious))
|
||||
mDomSelections[index]->Collapse(rangenode, rangeOffset);
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
|
||||
PRUint32 aContentEndOffset, PRBool aContinueSelection,
|
||||
|
@ -2545,14 +2637,22 @@ nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
|
|||
{
|
||||
if (!aNewFocus)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
InvalidateDesiredX();
|
||||
|
||||
|
||||
if (!aContinueSelection)
|
||||
mMaintainRange = nsnull;
|
||||
|
||||
mHint = HINT(aHint);
|
||||
// Don't take focus when dragging off of a table
|
||||
if (!mDragSelectingCells)
|
||||
{
|
||||
BidiLevelFromClick(aNewFocus, aContentOffset);
|
||||
PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON);
|
||||
if (aContinueSelection &&
|
||||
AdjustForMaintainedSelection(aNewFocus, aContentOffset))
|
||||
return NS_OK; //shift clicked to maintained selection. rejected.
|
||||
|
||||
return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection);
|
||||
}
|
||||
|
||||
|
@ -2569,22 +2669,12 @@ nsSelection::HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
|
|||
nsIFrame *newFrame = 0;
|
||||
nsPoint newPoint;
|
||||
|
||||
|
||||
result = ConstrainFrameAndPointToAnchorSubtree(aPresContext, aFrame, aPoint, &newFrame, newPoint);
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
if (!newFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
|
||||
result = aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
PRInt32 startPos = 0;
|
||||
PRInt32 contentOffsetEnd = 0;
|
||||
PRBool beginOfContent;
|
||||
|
@ -2594,57 +2684,9 @@ nsSelection::HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint&
|
|||
getter_AddRefs(newContent),
|
||||
startPos, contentOffsetEnd, beginOfContent);
|
||||
|
||||
//Is the desired content and offset currently in selection?
|
||||
//if the double click flag is set then dont continue selection if the desired content and offset
|
||||
//are currently inside a selection.
|
||||
//this will stop double click then mouse-drag from undo-ing the desired selecting of a word.
|
||||
if (mMouseDoubleDownState)
|
||||
{
|
||||
nsFrameState frameState;
|
||||
newFrame->GetFrameState(&frameState);
|
||||
PRBool insideSelection(PR_FALSE);
|
||||
if ((frameState & NS_FRAME_SELECTED_CONTENT))
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
mDomSelections[index]->GetIsCollapsed(&isCollapsed);
|
||||
if (!isCollapsed)
|
||||
{
|
||||
PRInt32 rangeCount;
|
||||
result = mDomSelections[index]->GetRangeCount(&rangeCount);
|
||||
if (NS_FAILED(result)) return result;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
domNode = do_QueryInterface(newContent);
|
||||
if (domNode)
|
||||
{
|
||||
for (PRInt32 i = 0; i < rangeCount; i++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
|
||||
result = mDomSelections[index]->GetRangeAt(i, getter_AddRefs(range));
|
||||
if (NS_FAILED(result) || !range)
|
||||
continue;//dont bail yet, iterate through them all
|
||||
|
||||
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
|
||||
if (NS_FAILED(result) || !nsrange)
|
||||
continue;//dont bail yet, iterate through them all
|
||||
|
||||
nsrange->IsPointInRange(domNode, startPos, &insideSelection);
|
||||
|
||||
// Done when we find a range that we are in
|
||||
if (insideSelection)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!insideSelection)
|
||||
mMouseDoubleDownState = PR_FALSE;
|
||||
else
|
||||
return NS_OK; //dragging in selection aborted
|
||||
}
|
||||
if ((newFrame->GetStateBits() & NS_FRAME_SELECTED_CONTENT) &&
|
||||
AdjustForMaintainedSelection(newContent, startPos))
|
||||
return NS_OK;
|
||||
|
||||
// do we have CSS that changes selection behaviour?
|
||||
{
|
||||
|
|
|
@ -1549,6 +1549,9 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (startOffset != endOffset)
|
||||
frameselection->MaintainSelection();
|
||||
|
||||
if (isEditor && !me->isShift && (endOffset - startOffset) == 1)
|
||||
{
|
||||
// A single node is selected and we aren't extending an existing
|
||||
|
@ -1762,7 +1765,17 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
|||
return rv;
|
||||
}
|
||||
//no release
|
||||
return NS_OK;
|
||||
|
||||
// maintain selection
|
||||
nsCOMPtr<nsIFrameSelection> frameselection = do_QueryInterface(selcon); //this MAY implement
|
||||
if (!frameselection)
|
||||
{
|
||||
rv = aPresContext->GetPresShell()->GetFrameSelection(getter_AddRefs(frameselection));
|
||||
if (NS_FAILED(rv) || !frameselection)
|
||||
return NS_OK; // return NS_OK; we don't care if this fails
|
||||
}
|
||||
|
||||
return frameselection->MaintainSelection();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -473,6 +473,7 @@ public:
|
|||
NS_IMETHOD CommonPageMove(PRBool aForward, PRBool aExtend, nsIScrollableView *aScrollableView, nsIFrameSelection *aFrameSel);
|
||||
NS_IMETHOD SetMouseDoubleDown(PRBool aDoubleDown);
|
||||
NS_IMETHOD GetMouseDoubleDown(PRBool *aDoubleDown);
|
||||
NS_IMETHOD MaintainSelection();
|
||||
#ifdef IBMBIDI
|
||||
NS_IMETHOD GetPrevNextBidiLevels(nsIPresContext *aPresContext,
|
||||
nsIContent *aNode,
|
||||
|
@ -1065,6 +1066,11 @@ NS_IMETHODIMP nsTextInputSelectionImpl::GetMouseDoubleDown(PRBool *aDoubleDown)
|
|||
return mFrameSelection->GetMouseDoubleDown(aDoubleDown);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputSelectionImpl::MaintainSelection()
|
||||
{
|
||||
return mFrameSelection->MaintainSelection();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputSelectionImpl::CommonPageMove(PRBool aForward, PRBool aExtend, nsIScrollableView *aScrollableView, nsIFrameSelection *aFrameSel)
|
||||
{
|
||||
return mFrameSelection->CommonPageMove(aForward, aExtend, aScrollableView, this);
|
||||
|
|
Загрузка…
Ссылка в новой задаче