Part 1 of fix for bug #39821: Drag and Drop interferes with selection.

layout/base/public/nsIFrameSelection.h
  layout/base/src/nsSelection.cpp
  layout/events/src/nsEventStateManager.cpp
  layout/html/base/src/nsFrame.cpp
  layout/html/forms/src/nsGfxTextControlFrame2.cpp
  xpfe/browser/resources/content/navigatorDD.js

r=brade@netscape.com,cmanske@netscape.com a=beppe@netscape.com,waterson@netscape.com
This commit is contained in:
kin%netscape.com 2000-05-25 20:04:02 +00:00
Родитель da27f7fefd
Коммит 2303aabdcb
11 изменённых файлов: 510 добавлений и 134 удалений

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

@ -291,6 +291,10 @@ public:
NS_IMETHOD SelectAll();
NS_IMETHOD SetDisplaySelection(PRInt16 aState);
NS_IMETHOD GetDisplaySelection(PRInt16 *aState);
NS_IMETHOD SetDelayCaretOverExistingSelection(PRBool aDelay);
NS_IMETHOD GetDelayCaretOverExistingSelection(PRBool *aDelay);
NS_IMETHOD SetDelayedCaretData(nsMouseEvent *aMouseEvent);
NS_IMETHOD GetDelayedCaretData(nsMouseEvent **aMouseEvent);
/*END nsIFrameSelection interfacse*/
@ -372,6 +376,11 @@ private:
PRBool mDesiredXSet;
enum HINT {HINTLEFT=0,HINTRIGHT=1}mHint;//end of this line or beginning of next
nsIScrollableView *mScrollView;
PRBool mDelayCaretOverExistingSelection;
PRBool mDelayedMouseEventValid;
nsMouseEvent mDelayedMouseEvent;
public:
static nsIAtom *sTableAtom;
static nsIAtom *sCellAtom;
@ -798,6 +807,9 @@ nsSelection::nsSelection()
autoCopyService->Listen(mDomSelections[index]);
}
mDisplaySelection = nsISelectionController::SELECTION_OFF;
mDelayCaretOverExistingSelection = PR_TRUE;
mDelayedMouseEventValid = PR_FALSE;
}
@ -2783,6 +2795,61 @@ nsSelection::GetDisplaySelection(PRInt16 *aToggle)
return NS_OK;
}
NS_IMETHODIMP
nsSelection::SetDelayCaretOverExistingSelection(PRBool aDelay)
{
mDelayCaretOverExistingSelection = aDelay;
if (! aDelay)
mDelayedMouseEventValid = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::GetDelayCaretOverExistingSelection(PRBool *aDelay)
{
if (!aDelay)
return NS_ERROR_NULL_POINTER;
*aDelay = mDelayCaretOverExistingSelection;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::SetDelayedCaretData(nsMouseEvent *aMouseEvent)
{
if (aMouseEvent)
{
mDelayedMouseEventValid = PR_TRUE;
mDelayedMouseEvent = *aMouseEvent;
// XXX: Hmmm, should we AddRef mDelayedMouseEvent->widget?
// Doing so might introduce a leak if things in the app
// are not released in the correct order though, so for now
// don't do anything.
}
else
mDelayedMouseEventValid = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::GetDelayedCaretData(nsMouseEvent **aMouseEvent)
{
if (!aMouseEvent)
return NS_ERROR_NULL_POINTER;
if (mDelayedMouseEventValid)
*aMouseEvent = &mDelayedMouseEvent;
else
*aMouseEvent = 0;
return NS_OK;
}
//END nsIDOMSelection interface implementations
#ifdef XP_MAC

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

@ -686,6 +686,25 @@ nsEventStateManager :: GenerateDragGesture ( nsIPresContext* aPresContext, nsGUI
{
NS_WARN_IF_FALSE(aPresContext, "This shouldn't happen.");
if ( IsTrackingDragGesture() ) {
// Check if selection is tracking drag gestures, if so
// don't interfere!
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
nsCOMPtr<nsIFrameSelection> frameSel;
rv = shell->GetFrameSelection(getter_AddRefs(frameSel));
if (NS_SUCCEEDED(rv) && frameSel){
PRBool mouseDownState = PR_TRUE;
frameSel->GetMouseDownState(&mouseDownState);
if (mouseDownState) {
StopTrackingDragGesture();
return;
}
}
}
// figure out the delta in twips, since that is how it is in the event.
// Do we need to do this conversion every time? Will the pres context really change on
// us or can we cache it?

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

@ -309,6 +309,46 @@ public:
NS_IMETHOD SetDisplaySelection(PRInt16 aState)=0;
NS_IMETHOD GetDisplaySelection(PRInt16 *aState)=0;
/** Allow applications to specify how we should place the caret
* when the user clicks over an existing selection. A aDelay
* value of PR_TRUE means delay clearing the selection and
* placing the caret until MouseUp, when the user clicks over
* an existing selection. This is especially usefull when applications
* want to support Drag & Drop of the current selection. A value
* of PR_FALSE means place the caret immediately. If the application
* never calls this method, the nsIFrameSelection implementation
* assumes the default value is PR_TRUE.
* @param aDelay PR_TRUE if we should delay caret placement.
*/
NS_IMETHOD SetDelayCaretOverExistingSelection(PRBool aDelay)=0;
/** Get the current delay caret setting. If aDelay contains
* a return value of PR_TRUE, the caret is placed on MouseUp
* when clicking over an existing selection. If PR_FALSE,
* the selection is cleared and caret is placed immediately
* in all cases.
* @param aDelay will contain the return value.
*/
NS_IMETHOD GetDelayCaretOverExistingSelection(PRBool *aDelay)=0;
/** If we are delaying caret placement til MouseUp (see
* Set/GetDelayCaretOverExistingSelection()), this method
* can be used to store the data received during the MouseDown
* so that we can place the caret during the MouseUp event.
* @aMouseEvent the event received by the selection MouseDown
* handling method. A NULL value can be use to tell this method
* that any data is storing is no longer valid.
*/
NS_IMETHOD SetDelayedCaretData(nsMouseEvent *aMouseEvent)=0;
/** Get the delayed MouseDown event data neccessary to place the
* caret during MouseUp processing.
* @aMouseEvent will contain a pointer to the event received
* by the selection during MouseDown processing. It can be NULL
* if the data is no longer valid.
*/
NS_IMETHOD GetDelayedCaretData(nsMouseEvent **aMouseEvent)=0;
};

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

@ -309,6 +309,46 @@ public:
NS_IMETHOD SetDisplaySelection(PRInt16 aState)=0;
NS_IMETHOD GetDisplaySelection(PRInt16 *aState)=0;
/** Allow applications to specify how we should place the caret
* when the user clicks over an existing selection. A aDelay
* value of PR_TRUE means delay clearing the selection and
* placing the caret until MouseUp, when the user clicks over
* an existing selection. This is especially usefull when applications
* want to support Drag & Drop of the current selection. A value
* of PR_FALSE means place the caret immediately. If the application
* never calls this method, the nsIFrameSelection implementation
* assumes the default value is PR_TRUE.
* @param aDelay PR_TRUE if we should delay caret placement.
*/
NS_IMETHOD SetDelayCaretOverExistingSelection(PRBool aDelay)=0;
/** Get the current delay caret setting. If aDelay contains
* a return value of PR_TRUE, the caret is placed on MouseUp
* when clicking over an existing selection. If PR_FALSE,
* the selection is cleared and caret is placed immediately
* in all cases.
* @param aDelay will contain the return value.
*/
NS_IMETHOD GetDelayCaretOverExistingSelection(PRBool *aDelay)=0;
/** If we are delaying caret placement til MouseUp (see
* Set/GetDelayCaretOverExistingSelection()), this method
* can be used to store the data received during the MouseDown
* so that we can place the caret during the MouseUp event.
* @aMouseEvent the event received by the selection MouseDown
* handling method. A NULL value can be use to tell this method
* that any data is storing is no longer valid.
*/
NS_IMETHOD SetDelayedCaretData(nsMouseEvent *aMouseEvent)=0;
/** Get the delayed MouseDown event data neccessary to place the
* caret during MouseUp processing.
* @aMouseEvent will contain a pointer to the event received
* by the selection during MouseDown processing. It can be NULL
* if the data is no longer valid.
*/
NS_IMETHOD GetDelayedCaretData(nsMouseEvent **aMouseEvent)=0;
};

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

@ -291,6 +291,10 @@ public:
NS_IMETHOD SelectAll();
NS_IMETHOD SetDisplaySelection(PRInt16 aState);
NS_IMETHOD GetDisplaySelection(PRInt16 *aState);
NS_IMETHOD SetDelayCaretOverExistingSelection(PRBool aDelay);
NS_IMETHOD GetDelayCaretOverExistingSelection(PRBool *aDelay);
NS_IMETHOD SetDelayedCaretData(nsMouseEvent *aMouseEvent);
NS_IMETHOD GetDelayedCaretData(nsMouseEvent **aMouseEvent);
/*END nsIFrameSelection interfacse*/
@ -372,6 +376,11 @@ private:
PRBool mDesiredXSet;
enum HINT {HINTLEFT=0,HINTRIGHT=1}mHint;//end of this line or beginning of next
nsIScrollableView *mScrollView;
PRBool mDelayCaretOverExistingSelection;
PRBool mDelayedMouseEventValid;
nsMouseEvent mDelayedMouseEvent;
public:
static nsIAtom *sTableAtom;
static nsIAtom *sCellAtom;
@ -798,6 +807,9 @@ nsSelection::nsSelection()
autoCopyService->Listen(mDomSelections[index]);
}
mDisplaySelection = nsISelectionController::SELECTION_OFF;
mDelayCaretOverExistingSelection = PR_TRUE;
mDelayedMouseEventValid = PR_FALSE;
}
@ -2783,6 +2795,61 @@ nsSelection::GetDisplaySelection(PRInt16 *aToggle)
return NS_OK;
}
NS_IMETHODIMP
nsSelection::SetDelayCaretOverExistingSelection(PRBool aDelay)
{
mDelayCaretOverExistingSelection = aDelay;
if (! aDelay)
mDelayedMouseEventValid = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::GetDelayCaretOverExistingSelection(PRBool *aDelay)
{
if (!aDelay)
return NS_ERROR_NULL_POINTER;
*aDelay = mDelayCaretOverExistingSelection;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::SetDelayedCaretData(nsMouseEvent *aMouseEvent)
{
if (aMouseEvent)
{
mDelayedMouseEventValid = PR_TRUE;
mDelayedMouseEvent = *aMouseEvent;
// XXX: Hmmm, should we AddRef mDelayedMouseEvent->widget?
// Doing so might introduce a leak if things in the app
// are not released in the correct order though, so for now
// don't do anything.
}
else
mDelayedMouseEventValid = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::GetDelayedCaretData(nsMouseEvent **aMouseEvent)
{
if (!aMouseEvent)
return NS_ERROR_NULL_POINTER;
if (mDelayedMouseEventValid)
*aMouseEvent = &mDelayedMouseEvent;
else
*aMouseEvent = 0;
return NS_OK;
}
//END nsIDOMSelection interface implementations
#ifdef XP_MAC

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

@ -686,6 +686,25 @@ nsEventStateManager :: GenerateDragGesture ( nsIPresContext* aPresContext, nsGUI
{
NS_WARN_IF_FALSE(aPresContext, "This shouldn't happen.");
if ( IsTrackingDragGesture() ) {
// Check if selection is tracking drag gestures, if so
// don't interfere!
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
nsCOMPtr<nsIFrameSelection> frameSel;
rv = shell->GetFrameSelection(getter_AddRefs(frameSel));
if (NS_SUCCEEDED(rv) && frameSel){
PRBool mouseDownState = PR_TRUE;
frameSel->GetMouseDownState(&mouseDownState);
if (mouseDownState) {
StopTrackingDragGesture();
return;
}
}
}
// figure out the delta in twips, since that is how it is in the event.
// Do we need to do this conversion every time? Will the pres context really change on
// us or can we cache it?

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

@ -1007,57 +1007,65 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
if (NS_FAILED(rv))
return rv;
#ifdef DRAG_AND_DROP_FRIENDLY_SELECTION
PRBool supportsDelay = PR_FALSE;
// Check if any part of this frame is selected, and if the
// user clicked inside the selected region. If so, we delay
// starting a new selection since the user may be trying to
// drag the selected region to some other app.
frameselection->GetDelayCaretOverExistingSelection(&supportsDelay);
frameselection->SetDelayedCaretData(0);
SelectionDetails *details = 0;
nsFrameState frameState;
GetFrameState(&frameState);
PRBool isSelected = ((frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT);
if (isSelected)
if (supportsDelay)
{
rv = frameselection->LookUpSelection(content, 0, endOffset, &details, PR_FALSE);
// Check if any part of this frame is selected, and if the
// user clicked inside the selected region. If so, we delay
// starting a new selection since the user may be trying to
// drag the selected region to some other app.
if (NS_FAILED(rv))
return rv;
SelectionDetails *details = 0;
nsFrameState frameState;
GetFrameState(&frameState);
PRBool isSelected = ((frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT);
//
// If there are any details, check to see if the user clicked
// within any selected region of the frame.
//
if (details)
if (isSelected)
{
SelectionDetails *curDetail = details;
rv = frameselection->LookUpSelection(content, 0, endOffset, &details, PR_FALSE);
while (curDetail)
if (NS_FAILED(rv))
return rv;
//
// If there are any details, check to see if the user clicked
// within any selected region of the frame.
//
if (details)
{
//
// If the user clicked inside a selection, then just
// return without doing anything. We will handle placing
// the caret later on when the mouse is released.
//
if (curDetail->mStart <= startOffset && endOffset <= curDetail->mEnd)
SelectionDetails *curDetail = details;
while (curDetail)
{
delete details;
rv = frameselection->SetMouseDownState( PR_FALSE );
return NS_OK;
//
// If the user clicked inside a selection, then just
// return without doing anything. We will handle placing
// the caret later on when the mouse is released.
//
if (curDetail->mStart <= startOffset && endOffset <= curDetail->mEnd)
{
delete details;
rv = frameselection->SetMouseDownState( PR_FALSE );
if (NS_FAILED(rv))
return rv;
return frameselection->SetDelayedCaretData(me);
}
curDetail = curDetail->mNext;
}
curDetail = curDetail->mNext;
delete details;
}
delete details;
}
}
#endif // DRAG_AND_DROP_FRIENDLY_SELECTION
rv = frameselection->SetMouseDownState( PR_TRUE );
if (NS_FAILED(rv))
@ -1311,46 +1319,56 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsIPresContext* aPresContext,
if (!frameselection)
return NS_ERROR_FAILURE;
#ifdef DRAG_AND_DROP_FRIENDLY_SELECTION
PRBool supportsDelay = PR_FALSE;
// Check if the frameselection recorded the mouse going down.
// If not, the user must have clicked in a part of the selection.
// Place the caret before continuing!
frameselection->GetDelayCaretOverExistingSelection(&supportsDelay);
PRBool mouseDown = PR_FALSE;
result = frameselection->GetMouseDownState(&mouseDown);
nsMouseEvent *me = (nsMouseEvent *)aEvent;
if (NS_SUCCEEDED(result) && me->clickCount < 2 && !mouseDown)
if (supportsDelay)
{
result = frameselection->SetMouseDownState( PR_TRUE );
// Check if the frameselection recorded the mouse going down.
// If not, the user must have clicked in a part of the selection.
// Place the caret before continuing!
nsCOMPtr<nsIContent>parentContent;
PRInt32 contentOffset;
PRUint32 target;
PRBool mouseDown = PR_FALSE;
result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target);
result = frameselection->GetMouseDownState(&mouseDown);
if (NS_SUCCEEDED(result) && parentContent)
result = frameselection->HandleTableSelection(parentContent, contentOffset, target, me);
else
if (NS_FAILED(result))
return result;
nsMouseEvent *me = 0;
result = frameselection->GetDelayedCaretData(&me);
if (NS_SUCCEEDED(result) && !mouseDown && me && me->clickCount < 2)
{
nsCOMPtr<nsIContent> content;
PRInt32 startOffset = 0, endOffset = 0;
PRBool beginFrameContent = PR_FALSE;
result = frameselection->SetMouseDownState( PR_TRUE );
result = GetContentAndOffsetsFromPoint(aPresContext, aEvent->point, getter_AddRefs(content), startOffset, endOffset, beginFrameContent);
nsCOMPtr<nsIContent>parentContent;
PRInt32 contentOffset;
PRUint32 target;
if (NS_FAILED(result))
return result;
result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target);
result = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, PR_FALSE, beginFrameContent);
if (NS_SUCCEEDED(result) && parentContent)
result = frameselection->HandleTableSelection(parentContent, contentOffset, target, me);
else
{
nsCOMPtr<nsIContent> content;
PRInt32 startOffset = 0, endOffset = 0;
PRBool beginFrameContent = PR_FALSE;
result = GetContentAndOffsetsFromPoint(aPresContext, me->point, getter_AddRefs(content), startOffset, endOffset, beginFrameContent);
if (NS_FAILED(result))
return result;
result = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, PR_FALSE, beginFrameContent);
}
}
}
#endif // DRAG_AND_DROP_FRIENDLY_SELECTION
result = frameselection->SetDelayedCaretData(0);
}
// Now handle the normal HandleRelase business.

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

@ -291,6 +291,10 @@ public:
NS_IMETHOD SelectAll();
NS_IMETHOD SetDisplaySelection(PRInt16 aState);
NS_IMETHOD GetDisplaySelection(PRInt16 *aState);
NS_IMETHOD SetDelayCaretOverExistingSelection(PRBool aDelay);
NS_IMETHOD GetDelayCaretOverExistingSelection(PRBool *aDelay);
NS_IMETHOD SetDelayedCaretData(nsMouseEvent *aMouseEvent);
NS_IMETHOD GetDelayedCaretData(nsMouseEvent **aMouseEvent);
/*END nsIFrameSelection interfacse*/
@ -372,6 +376,11 @@ private:
PRBool mDesiredXSet;
enum HINT {HINTLEFT=0,HINTRIGHT=1}mHint;//end of this line or beginning of next
nsIScrollableView *mScrollView;
PRBool mDelayCaretOverExistingSelection;
PRBool mDelayedMouseEventValid;
nsMouseEvent mDelayedMouseEvent;
public:
static nsIAtom *sTableAtom;
static nsIAtom *sCellAtom;
@ -798,6 +807,9 @@ nsSelection::nsSelection()
autoCopyService->Listen(mDomSelections[index]);
}
mDisplaySelection = nsISelectionController::SELECTION_OFF;
mDelayCaretOverExistingSelection = PR_TRUE;
mDelayedMouseEventValid = PR_FALSE;
}
@ -2783,6 +2795,61 @@ nsSelection::GetDisplaySelection(PRInt16 *aToggle)
return NS_OK;
}
NS_IMETHODIMP
nsSelection::SetDelayCaretOverExistingSelection(PRBool aDelay)
{
mDelayCaretOverExistingSelection = aDelay;
if (! aDelay)
mDelayedMouseEventValid = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::GetDelayCaretOverExistingSelection(PRBool *aDelay)
{
if (!aDelay)
return NS_ERROR_NULL_POINTER;
*aDelay = mDelayCaretOverExistingSelection;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::SetDelayedCaretData(nsMouseEvent *aMouseEvent)
{
if (aMouseEvent)
{
mDelayedMouseEventValid = PR_TRUE;
mDelayedMouseEvent = *aMouseEvent;
// XXX: Hmmm, should we AddRef mDelayedMouseEvent->widget?
// Doing so might introduce a leak if things in the app
// are not released in the correct order though, so for now
// don't do anything.
}
else
mDelayedMouseEventValid = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSelection::GetDelayedCaretData(nsMouseEvent **aMouseEvent)
{
if (!aMouseEvent)
return NS_ERROR_NULL_POINTER;
if (mDelayedMouseEventValid)
*aMouseEvent = &mDelayedMouseEvent;
else
*aMouseEvent = 0;
return NS_OK;
}
//END nsIDOMSelection interface implementations
#ifdef XP_MAC

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

@ -1007,57 +1007,65 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
if (NS_FAILED(rv))
return rv;
#ifdef DRAG_AND_DROP_FRIENDLY_SELECTION
PRBool supportsDelay = PR_FALSE;
// Check if any part of this frame is selected, and if the
// user clicked inside the selected region. If so, we delay
// starting a new selection since the user may be trying to
// drag the selected region to some other app.
frameselection->GetDelayCaretOverExistingSelection(&supportsDelay);
frameselection->SetDelayedCaretData(0);
SelectionDetails *details = 0;
nsFrameState frameState;
GetFrameState(&frameState);
PRBool isSelected = ((frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT);
if (isSelected)
if (supportsDelay)
{
rv = frameselection->LookUpSelection(content, 0, endOffset, &details, PR_FALSE);
// Check if any part of this frame is selected, and if the
// user clicked inside the selected region. If so, we delay
// starting a new selection since the user may be trying to
// drag the selected region to some other app.
if (NS_FAILED(rv))
return rv;
SelectionDetails *details = 0;
nsFrameState frameState;
GetFrameState(&frameState);
PRBool isSelected = ((frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT);
//
// If there are any details, check to see if the user clicked
// within any selected region of the frame.
//
if (details)
if (isSelected)
{
SelectionDetails *curDetail = details;
rv = frameselection->LookUpSelection(content, 0, endOffset, &details, PR_FALSE);
while (curDetail)
if (NS_FAILED(rv))
return rv;
//
// If there are any details, check to see if the user clicked
// within any selected region of the frame.
//
if (details)
{
//
// If the user clicked inside a selection, then just
// return without doing anything. We will handle placing
// the caret later on when the mouse is released.
//
if (curDetail->mStart <= startOffset && endOffset <= curDetail->mEnd)
SelectionDetails *curDetail = details;
while (curDetail)
{
delete details;
rv = frameselection->SetMouseDownState( PR_FALSE );
return NS_OK;
//
// If the user clicked inside a selection, then just
// return without doing anything. We will handle placing
// the caret later on when the mouse is released.
//
if (curDetail->mStart <= startOffset && endOffset <= curDetail->mEnd)
{
delete details;
rv = frameselection->SetMouseDownState( PR_FALSE );
if (NS_FAILED(rv))
return rv;
return frameselection->SetDelayedCaretData(me);
}
curDetail = curDetail->mNext;
}
curDetail = curDetail->mNext;
delete details;
}
delete details;
}
}
#endif // DRAG_AND_DROP_FRIENDLY_SELECTION
rv = frameselection->SetMouseDownState( PR_TRUE );
if (NS_FAILED(rv))
@ -1311,46 +1319,56 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsIPresContext* aPresContext,
if (!frameselection)
return NS_ERROR_FAILURE;
#ifdef DRAG_AND_DROP_FRIENDLY_SELECTION
PRBool supportsDelay = PR_FALSE;
// Check if the frameselection recorded the mouse going down.
// If not, the user must have clicked in a part of the selection.
// Place the caret before continuing!
frameselection->GetDelayCaretOverExistingSelection(&supportsDelay);
PRBool mouseDown = PR_FALSE;
result = frameselection->GetMouseDownState(&mouseDown);
nsMouseEvent *me = (nsMouseEvent *)aEvent;
if (NS_SUCCEEDED(result) && me->clickCount < 2 && !mouseDown)
if (supportsDelay)
{
result = frameselection->SetMouseDownState( PR_TRUE );
// Check if the frameselection recorded the mouse going down.
// If not, the user must have clicked in a part of the selection.
// Place the caret before continuing!
nsCOMPtr<nsIContent>parentContent;
PRInt32 contentOffset;
PRUint32 target;
PRBool mouseDown = PR_FALSE;
result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target);
result = frameselection->GetMouseDownState(&mouseDown);
if (NS_SUCCEEDED(result) && parentContent)
result = frameselection->HandleTableSelection(parentContent, contentOffset, target, me);
else
if (NS_FAILED(result))
return result;
nsMouseEvent *me = 0;
result = frameselection->GetDelayedCaretData(&me);
if (NS_SUCCEEDED(result) && !mouseDown && me && me->clickCount < 2)
{
nsCOMPtr<nsIContent> content;
PRInt32 startOffset = 0, endOffset = 0;
PRBool beginFrameContent = PR_FALSE;
result = frameselection->SetMouseDownState( PR_TRUE );
result = GetContentAndOffsetsFromPoint(aPresContext, aEvent->point, getter_AddRefs(content), startOffset, endOffset, beginFrameContent);
nsCOMPtr<nsIContent>parentContent;
PRInt32 contentOffset;
PRUint32 target;
if (NS_FAILED(result))
return result;
result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target);
result = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, PR_FALSE, beginFrameContent);
if (NS_SUCCEEDED(result) && parentContent)
result = frameselection->HandleTableSelection(parentContent, contentOffset, target, me);
else
{
nsCOMPtr<nsIContent> content;
PRInt32 startOffset = 0, endOffset = 0;
PRBool beginFrameContent = PR_FALSE;
result = GetContentAndOffsetsFromPoint(aPresContext, me->point, getter_AddRefs(content), startOffset, endOffset, beginFrameContent);
if (NS_FAILED(result))
return result;
result = frameselection->HandleClick(content, startOffset , endOffset, me->isShift, PR_FALSE, beginFrameContent);
}
}
}
#endif // DRAG_AND_DROP_FRIENDLY_SELECTION
result = frameselection->SetDelayedCaretData(0);
}
// Now handle the normal HandleRelase business.

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

@ -134,6 +134,10 @@ public:
SelectionDetails **aReturnDetails, PRBool aSlowCheck);
NS_IMETHOD SetMouseDownState(PRBool aState);
NS_IMETHOD GetMouseDownState(PRBool *aState);
NS_IMETHOD SetDelayCaretOverExistingSelection(PRBool aDelay);
NS_IMETHOD GetDelayCaretOverExistingSelection(PRBool *aDelay);
NS_IMETHOD SetDelayedCaretData(nsMouseEvent *aMouseEvent);
NS_IMETHOD GetDelayedCaretData(nsMouseEvent **aMouseEvent);
NS_IMETHOD GetTableCellSelection(PRBool *aState);
NS_IMETHOD GetTableCellSelectionStyleColor(const nsStyleColor **aStyleColor);
NS_IMETHOD GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame, PRInt32 *aReturnOffset);
@ -418,6 +422,29 @@ nsTextAreaSelectionImpl::GetMouseDownState(PRBool *aState)
return mFrameSelection->GetMouseDownState(aState);
}
NS_IMETHODIMP
nsTextAreaSelectionImpl::SetDelayCaretOverExistingSelection(PRBool aDelay)
{
return mFrameSelection->SetDelayCaretOverExistingSelection(aDelay);
}
NS_IMETHODIMP
nsTextAreaSelectionImpl::GetDelayCaretOverExistingSelection(PRBool *aDelay)
{
return mFrameSelection->GetDelayCaretOverExistingSelection(aDelay);
}
NS_IMETHODIMP
nsTextAreaSelectionImpl::SetDelayedCaretData(nsMouseEvent *aMouseEvent)
{
return mFrameSelection->SetDelayedCaretData(aMouseEvent);
}
NS_IMETHODIMP
nsTextAreaSelectionImpl::GetDelayedCaretData(nsMouseEvent **aMouseEvent)
{
return mFrameSelection->GetDelayedCaretData(aMouseEvent);
}
NS_IMETHODIMP
nsTextAreaSelectionImpl::GetTableCellSelection(PRBool *aState)

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

@ -302,12 +302,6 @@ function BeginDragContentArea ( event )
// dump(domselection);
htmlstring = domselection.toString("text/html", 128+256, 0);
textstring = domselection.toString("text/plain", 0, 0);
// The following return disables the ability to drag & drop
// the current selection. This temporarily fixes bug #39821
// so that others are unblocked. Remove it when drag & drop and
// selection cooperate better.
return;
}
else
{