Composer bugs: Drag and drop problems (47399, r=anthonyd), workaround for bad dragNdrop event (50703, r=nisheeth)

git-svn-id: svn://10.0.0.236/trunk@78187 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
cmanske%netscape.com 2000-09-05 23:26:48 +00:00
parent 1465df6c2d
commit 06f0642f0b
12 changed files with 691 additions and 372 deletions

View File

@ -474,9 +474,12 @@ nsRemoveListCommand::IsCommandEnabled(const PRUnichar *aCommand, nsISupports * r
PRUnichar *tagStr;
nsresult rv = editorShell->GetListState(&bMixed, &tagStr);
if (NS_FAILED(rv)) return rv;
*outCmdEnabled = (tagStr && *tagStr != nsnull);
if (bMixed)
*outCmdEnabled = PR_TRUE;
else
*outCmdEnabled = (tagStr && *tagStr);
if (tagStr) nsCRT::free(tagStr);
}

View File

@ -682,11 +682,11 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
{
nsresult rv;
NS_WITH_SERVICE(nsIDragService, dragService, "component://netscape/widget/dragservice", &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
if (dragSession)
{
{
PRBool flavorSupported = PR_FALSE;
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
if ( !flavorSupported )
@ -696,54 +696,73 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
if ( !flavorSupported )
dragSession->IsDataFlavorSupported(kJPEGImageMime, &flavorSupported);
if (! flavorSupported )
return NS_OK;
}
return NS_OK;
}
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
if (!nsuiEvent) return NS_OK;
//some day we want to use another way to stop this from bubbling.
aMouseEvent->PreventBubble();
aMouseEvent->PreventDefault();
/* for bug 47399, when dropping a drag session, if you are over your original
selection, nothing should happen. */
nsCOMPtr<nsIDOMSelection> tempSelection;
rv = mEditor->GetSelection(getter_AddRefs(tempSelection));
if (NS_FAILED(rv) || !tempSelection)
selection, nothing should happen.
cmanske: But do this only if drag source is not the same as target (current) document!
*/
nsCOMPtr<nsIDOMSelection> selection;
rv = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv) || !selection)
return rv?rv:NS_ERROR_FAILURE;
PRInt32 rangeCount;
rv = tempSelection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = do_QueryInterface(htmlEditor);
nsCOMPtr<nsIDOMDocument> domdoc;
rv = editor->GetDocument(getter_AddRefs(domdoc));
if (NS_FAILED(rv)) return rv;
for(int i = 0; i < rangeCount; i++)
nsCOMPtr<nsIDOMDocument> sourceDoc;
rv = dragSession->GetSourceDocument(getter_AddRefs(sourceDoc));
if (NS_FAILED(rv)) return rv;
if (domdoc == sourceDoc)
{
nsCOMPtr<nsIDOMRange> range;
PRBool isCollapsed;
rv = selection->GetIsCollapsed(&isCollapsed);
if (NS_FAILED(rv)) return rv;
// Don't bother if collapsed - can always drop
if (!isCollapsed)
{
nsCOMPtr<nsIDOMNode> parent;
rv = nsuiEvent->GetRangeParent(getter_AddRefs(parent));
if (NS_FAILED(rv)) return rv;
if (!parent) return NS_ERROR_FAILURE;
rv = tempSelection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue;//dont bail yet, iterate through them all
PRInt32 offset = 0;
rv = nsuiEvent->GetRangeOffset(&offset);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue;//dont bail yet, iterate through them all
PRInt32 rangeCount;
rv = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
if (!nsuiEvent)
continue;//dont bail yet, iterate through them all
for (PRInt32 i = 0; i < rangeCount; i++)
{
nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsIDOMNode> parent;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeParent(getter_AddRefs(parent))))
continue;//dont bail yet, iterate through them all
rv = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue;//dont bail yet, iterate through them all
PRInt32 offset = 0;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeOffset(&offset)))
continue;//dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue;//dont bail yet, iterate through them all
PRBool inrange;
rv = nsrange->IsPointInRange(parent, offset, &inrange);
if(inrange)
return NS_ERROR_FAILURE;//okay, now you can bail, we are over the orginal selection
PRBool inrange;
rv = nsrange->IsPointInRange(parent, offset, &inrange);
if(inrange)
return NS_ERROR_FAILURE;//okay, now you can bail, we are over the orginal selection
}
}
}
// if we are not over orginal selection, drop that baby!
return htmlEditor->InsertFromDrop(aMouseEvent);

View File

@ -31,10 +31,16 @@
#include "nsIDOMCharacterData.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMSelection.h"
#include "nsIDOMRange.h"
#include "nsIDOMNSRange.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMHTMLTableElement.h"
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIEditor.h"
#include "nsIHTMLEditor.h"
/*
* nsEditorShellMouseListener implementation
*/
@ -160,104 +166,144 @@ nsEditorShellMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
//non-ui event passed in. bad things.
return NS_OK;
}
PRUint16 buttonNumber;
nsresult res = mouseEvent->GetButton(&buttonNumber);
// Don't do anything special if not an HTML editor
nsCOMPtr<nsIEditor> editor;
nsresult res = mEditorShell->GetEditor(getter_AddRefs(editor));
if (NS_FAILED(res)) return res;
PRBool isContextClick;
// Test if special 'table selection' key is pressed when double-clicking
// so we look for an enclosing cell or table
PRBool tableMode = PR_FALSE;
#ifdef XP_MAC
// Cmd is Mac table-select key
res = mouseEvent->GetMetaKey(&tableMode);
if (NS_FAILED(res)) return res;
// Ctrl+Click for context menu
res = mouseEvent->GetCtrlKey(&isContextClick);
#else
// Right mouse button for Windows, UNIX
isContextClick = buttonNumber == 3;
res = mouseEvent->GetCtrlKey(&tableMode);
#endif
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMEventTarget> target;
res = aMouseEvent->GetTarget(getter_AddRefs(target));
if (NS_FAILED(res)) return res;
if (!target) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
PRInt32 clickCount;
res = mouseEvent->GetDetail(&clickCount);
if (NS_FAILED(res)) return res;
PRBool NodeIsInSelection = PR_FALSE;
if (isContextClick || (buttonNumber == 1 && clickCount == 2))
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor);
if (htmlEditor)
{
// Context menu or double click
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
if (node)
PRUint16 buttonNumber;
res = mouseEvent->GetButton(&buttonNumber);
if (NS_FAILED(res)) return res;
PRBool isContextClick;
// Test if special 'table selection' key is pressed when double-clicking
// so we look for an enclosing cell or table
PRBool tableMode = PR_FALSE;
#ifdef XP_MAC
// Cmd is Mac table-select key
res = mouseEvent->GetMetaKey(&tableMode);
if (NS_FAILED(res)) return res;
// Ctrl+Click for context menu
res = mouseEvent->GetCtrlKey(&isContextClick);
#else
// Right mouse button for Windows, UNIX
isContextClick = buttonNumber == 3;
res = mouseEvent->GetCtrlKey(&tableMode);
#endif
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMEventTarget> target;
res = aMouseEvent->GetTarget(getter_AddRefs(target));
if (NS_FAILED(res)) return res;
if (!target) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
PRInt32 clickCount;
res = mouseEvent->GetDetail(&clickCount);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMSelection> selection;
mEditorShell->GetEditorSelection(getter_AddRefs(selection));
if (!selection) return NS_OK;
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset = 0;
// Get location of mouse within target node
nsCOMPtr<nsIDOMNSUIEvent> uiEvent = do_QueryInterface(aMouseEvent);
if (!uiEvent) return NS_ERROR_FAILURE;
res = uiEvent->GetRangeParent(getter_AddRefs(parent));
if (NS_FAILED(res)) return res;
if (!parent) return NS_ERROR_FAILURE;
res = uiEvent->GetRangeOffset(&offset);
if (NS_FAILED(res)) return res;
// Detect if mouse point is withing current selection
PRBool NodeIsInSelection = PR_FALSE;
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
if (!isCollapsed)
{
nsCOMPtr<nsIDOMSelection> selection;
mEditorShell->GetEditorSelection(getter_AddRefs(selection));
if (selection)
PRInt32 rangeCount;
res = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(res)) return res;
for (PRInt32 i = 0; i < rangeCount; i++)
{
res = selection->ContainsNode(node, PR_TRUE, &NodeIsInSelection);
// Kludge: We really want to reposition the caret exactly as done for
// left mouse button, but we never reach the frame's HandlePress method.
// Thus for text nodes, the best we can do is reposition to the start of the node,
// but only if not already selected, of course
if (!NodeIsInSelection)
selection->Collapse(node, 0);
nsCOMPtr<nsIDOMRange> range;
res = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(res) || !range)
continue;//dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(res) || !nsrange)
continue;//dont bail yet, iterate through them all
res = nsrange->IsPointInRange(parent, offset, &NodeIsInSelection);
}
// Get enclosing link
nsCOMPtr<nsIDOMElement> linkElement;
res = mEditorShell->GetElementOrParentByTagName(NS_LITERAL_STRING("href"), node, getter_AddRefs(linkElement));
if (NS_FAILED(res)) return res;
if (linkElement)
element = linkElement;
}
}
if (isContextClick)
{
// Set selection to node clicked on if NOT within an existing selection
if (element && !NodeIsInSelection)
mEditorShell->SelectElement(element);
// Always fall through to do other actions, such as context menu
}
else if (buttonNumber == 1)
{
#ifdef DEBUG_cmanske
// printf("nsEditorShellMouseListener::MouseDown: clickCount=%d\n",clickCount);
#endif
if (tableMode && clickCount == 2)
if (isContextClick || (buttonNumber == 1 && clickCount == 2))
{
if (!GetParentCell(aMouseEvent, getter_AddRefs(element)))
GetParentTable(aMouseEvent, getter_AddRefs(element));
// Context menu or double click
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
if (node && !NodeIsInSelection)
{
selection->Collapse(parent, offset);
// Get enclosing link
nsCOMPtr<nsIDOMElement> linkElement;
res = mEditorShell->GetElementOrParentByTagName(NS_LITERAL_STRING("href"), node, getter_AddRefs(linkElement));
if (NS_FAILED(res)) return res;
if (linkElement)
element = linkElement;
}
}
// No table or cell -- look for other element (ignore text nodes)
if (element)
if (isContextClick)
{
PRInt32 x,y;
res = mouseEvent->GetClientX(&x);
if (NS_FAILED(res)) return res;
// Set selection to node clicked on if NOT within an existing selection
if (element && !NodeIsInSelection)
mEditorShell->SelectElement(element);
// Always fall through to do other actions, such as context menu
}
else if (buttonNumber == 1)
{
if (tableMode && clickCount == 2)
{
if (!GetParentCell(aMouseEvent, getter_AddRefs(element)))
GetParentTable(aMouseEvent, getter_AddRefs(element));
}
// No table or cell -- look for other element (ignore text nodes)
if (element)
{
PRInt32 x,y;
res = mouseEvent->GetClientX(&x);
if (NS_FAILED(res)) return res;
res = mouseEvent->GetClientY(&y);
if (NS_FAILED(res)) return res;
res = mouseEvent->GetClientY(&y);
if (NS_FAILED(res)) return res;
// Let editor decide what to do with this
PRBool handled = PR_FALSE;
mEditorShell->HandleMouseClickOnElement(element, clickCount, x, y, &handled);
// KLUDGE to work around bug 50703: Prevent drag/drop events until we are done
if (clickCount == 2)
htmlEditor->IgnoreSpuriousDragEvent(PR_TRUE);
if (handled)
mouseEvent->PreventDefault();
// Let editor decide what to do with this
PRBool handled = PR_FALSE;
mEditorShell->HandleMouseClickOnElement(element, clickCount, x, y, &handled);
if (handled)
mouseEvent->PreventDefault();
}
}
}
@ -267,10 +313,7 @@ nsEditorShellMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
nsresult
nsEditorShellMouseListener::MouseUp(nsIDOMEvent* aMouseEvent)
{
#ifdef DEBUG_cmanske
printf("* nsEditorShellMouseListener::MouseUp message\n");
#endif
return NS_OK; // didn't handle event
return NS_OK;
}
nsresult

View File

@ -239,6 +239,7 @@ nsHTMLEditor::nsHTMLEditor()
, mIsComposing(PR_FALSE)
, mMaxTextLength(-1)
, mSelectedCellIndex(0)
, mIgnoreSpuriousDragEvent(PR_FALSE)
{
// Done in nsEditor
// NS_INIT_REFCNT();
@ -2620,7 +2621,7 @@ nsHTMLEditor::ReplaceHeadContentsWithHTML(const nsString &aSourceToInsert)
res = nsrange->CreateContextualFragment(inputString,
getter_AddRefs(docfrag));
//XXXX BUG: This is not returning the text between <title> ... </title>
//XXXX BUG 50965: This is not returning the text between <title> ... </title>
// Special code is needed in JS to handle title anyway, so it really doesn't matter!
if (NS_FAILED(res))
@ -5000,7 +5001,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable
return rv;
}
NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
{
ForceCompositionEnd();
@ -5011,74 +5011,150 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
if (dragSession)
if (!dragSession) return NS_OK;
// Get the nsITransferable interface for getting the data from the drop
nsCOMPtr<nsITransferable> trans;
rv = PrepareTransferable(getter_AddRefs(trans));
if (NS_FAILED(rv)) return rv;
if (!trans) return NS_OK; // NS_ERROR_FAILURE; SHOULD WE FAIL?
PRUint32 numItems = 0;
rv = dragSession->GetNumDropItems(&numItems);
if (NS_FAILED(rv)) return rv;
// Combine any deletion and drop insertion into one transaction
nsAutoEditBatch beginBatching(this);
PRUint32 i;
PRBool doPlaceCaret = PR_TRUE;
for (i = 0; i < numItems; ++i)
{
// Get the nsITransferable interface for getting the data from the drop
nsCOMPtr<nsITransferable> trans;
rv = PrepareTransferable(getter_AddRefs(trans));
if (NS_SUCCEEDED(rv) && trans)
rv = dragSession->GetData(trans, i);
if (NS_FAILED(rv)) return rv;
if (!trans) return NS_OK; // NS_ERROR_FAILURE; Should we fail?
if ( doPlaceCaret )
{
PRUint32 numItems = 0;
if (NS_SUCCEEDED(dragSession->GetNumDropItems(&numItems)))
{
PRUint32 i;
PRBool doPlaceCaret = PR_TRUE;
for (i = 0; i < numItems; ++i)
{
if (NS_SUCCEEDED(dragSession->GetData(trans, i)))
{
if ( doPlaceCaret )
{
// check if the user pressed the key to force a copy rather than a move
// if we run into problems here, we'll just assume the user doesn't want a copy
PRBool userWantsCopy = PR_FALSE;
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aDropEvent) );
if (mouseEvent)
// check if the user pressed the key to force a copy rather than a move
// if we run into problems here, we'll just assume the user doesn't want a copy
PRBool userWantsCopy = PR_FALSE;
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aDropEvent));
if (!nsuiEvent) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aDropEvent) );
if (mouseEvent)
#ifdef XP_MAC
mouseEvent->GetAltKey(&userWantsCopy); // check modifiers here
mouseEvent->GetAltKey(&userWantsCopy);
#else
mouseEvent->GetCtrlKey(&userWantsCopy); // check modifiers here
mouseEvent->GetCtrlKey(&userWantsCopy);
#endif
nsCOMPtr<nsIDOMDocument> srcdomdoc;
dragSession->GetSourceDocument(getter_AddRefs(srcdomdoc));
if (srcdomdoc)
{
// do deletion of selection if sourcedocument is current document && appropriate modifier isn't pressed
nsCOMPtr<nsIDOMDocument>destdomdoc;
rv = GetDocument(getter_AddRefs(destdomdoc));
if ( NS_SUCCEEDED(rv) && !userWantsCopy && (srcdomdoc == destdomdoc) )
{
rv = DeleteSelection(eNone);
if (NS_FAILED(rv))
return rv;
}
}
// Source doc is null if source is *not* the current editor document
nsCOMPtr<nsIDOMDocument> srcdomdoc;
rv = dragSession->GetSourceDocument(getter_AddRefs(srcdomdoc));
if (NS_FAILED(rv)) return rv;
// Set the selection to the point under the mouse cursor:
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aDropEvent));
// Current doc is destination
nsCOMPtr<nsIDOMDocument>destdomdoc;
rv = GetDocument(getter_AddRefs(destdomdoc));
if (NS_FAILED(rv)) return rv;
if (!nsuiEvent)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parent;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeParent(getter_AddRefs(parent))))
return NS_ERROR_NULL_POINTER;
PRInt32 offset = 0;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeOffset(&offset)))
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMSelection> selection;
rv = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv)) return rv;
if (!selection) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(GetSelection(getter_AddRefs(selection))))
(void)selection->Collapse(parent, offset);
PRBool isCollapsed;
rv = selection->GetIsCollapsed(&isCollapsed);
if (NS_FAILED(rv)) return rv;
// Parent and offset under the mouse cursor
nsCOMPtr<nsIDOMNode> newSelectionParent;
PRInt32 newSelectionOffset = 0;
rv = nsuiEvent->GetRangeParent(getter_AddRefs(newSelectionParent));
if (NS_FAILED(rv)) return rv;
if (!newSelectionParent) return NS_ERROR_FAILURE;
doPlaceCaret = PR_FALSE;
}
rv = InsertFromTransferable(trans);
rv = nsuiEvent->GetRangeOffset(&newSelectionOffset);
if (NS_FAILED(rv)) return rv;
// We never have to delete if selection is already collapsed
PRBool deleteSelection = PR_FALSE;
PRBool cursorIsInSelection = PR_FALSE;
// Check if mouse is in the selection
if (!isCollapsed)
{
PRInt32 rangeCount;
rv = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
for (PRInt32 j = 0; j < rangeCount; j++)
{
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(j, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue;//dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue;//dont bail yet, iterate through them all
rv = nsrange->IsPointInRange(newSelectionParent, newSelectionOffset, &cursorIsInSelection);
if(cursorIsInSelection)
break;
}
if (cursorIsInSelection)
{
// Dragging within same doc can't drop on itself -- leave!
// (We shouldn't get here - drag event shouldn't have started if over selection)
if (srcdomdoc == destdomdoc)
return NS_OK;
// Dragging from another window onto a selection
// XXX Decision made to NOT do this,
// note that 4.x does replace if dropped on
//deleteSelection = PR_TRUE;
}
else
{
// We are NOT over the selection
if (srcdomdoc == destdomdoc)
{
// Within the same doc: delete if user doesn't want to copy
deleteSelection = !userWantsCopy;
}
else
{
// Different source doc: Don't delete
deleteSelection = PR_FALSE;
}
}
}
if (deleteSelection)
{
rv = DeleteSelection(eNone);
if (NS_FAILED(rv)) return rv;
}
// If we deleted the selection because we dropped from another doc,
// then we don't have to relocate the caret (insert at the deletion point)
if (!(deleteSelection && srcdomdoc != destdomdoc))
{
// Move the selection to the point under the mouse cursor
selection->Collapse(newSelectionParent, newSelectionOffset);
}
// We have to figure out whether to delete and relocate caret only once
doPlaceCaret = PR_FALSE;
}
rv = InsertFromTransferable(trans);
}
return rv;
@ -5090,7 +5166,19 @@ NS_IMETHODIMP nsHTMLEditor::CanDrag(nsIDOMEvent *aDragEvent, PRBool &aCanDrag)
* that particular point is actually within the selection (not just that there is a selection)
*/
aCanDrag = PR_FALSE;
// KLUDGE to work around bug 50703
// After double click and object property editing,
// we get a spurious drag event
if (mIgnoreSpuriousDragEvent)
{
#ifdef DEBUG_cmanske
printf(" *** IGNORING SPURIOUS DRAG EVENT!\n");
#endif
mIgnoreSpuriousDragEvent = PR_FALSE;
return NS_OK;
}
nsCOMPtr<nsIDOMSelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res)) return res;

View File

@ -577,6 +577,10 @@ protected:
nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver);
//XXX Kludge: Used to suppress spurious drag/drop events (bug 50703)
PRBool mIgnoreSpuriousDragEvent;
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;}
// Data members
protected:

View File

@ -474,9 +474,12 @@ nsRemoveListCommand::IsCommandEnabled(const PRUnichar *aCommand, nsISupports * r
PRUnichar *tagStr;
nsresult rv = editorShell->GetListState(&bMixed, &tagStr);
if (NS_FAILED(rv)) return rv;
*outCmdEnabled = (tagStr && *tagStr != nsnull);
if (bMixed)
*outCmdEnabled = PR_TRUE;
else
*outCmdEnabled = (tagStr && *tagStr);
if (tagStr) nsCRT::free(tagStr);
}

View File

@ -31,10 +31,16 @@
#include "nsIDOMCharacterData.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMSelection.h"
#include "nsIDOMRange.h"
#include "nsIDOMNSRange.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMHTMLTableElement.h"
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIEditor.h"
#include "nsIHTMLEditor.h"
/*
* nsEditorShellMouseListener implementation
*/
@ -160,104 +166,144 @@ nsEditorShellMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
//non-ui event passed in. bad things.
return NS_OK;
}
PRUint16 buttonNumber;
nsresult res = mouseEvent->GetButton(&buttonNumber);
// Don't do anything special if not an HTML editor
nsCOMPtr<nsIEditor> editor;
nsresult res = mEditorShell->GetEditor(getter_AddRefs(editor));
if (NS_FAILED(res)) return res;
PRBool isContextClick;
// Test if special 'table selection' key is pressed when double-clicking
// so we look for an enclosing cell or table
PRBool tableMode = PR_FALSE;
#ifdef XP_MAC
// Cmd is Mac table-select key
res = mouseEvent->GetMetaKey(&tableMode);
if (NS_FAILED(res)) return res;
// Ctrl+Click for context menu
res = mouseEvent->GetCtrlKey(&isContextClick);
#else
// Right mouse button for Windows, UNIX
isContextClick = buttonNumber == 3;
res = mouseEvent->GetCtrlKey(&tableMode);
#endif
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMEventTarget> target;
res = aMouseEvent->GetTarget(getter_AddRefs(target));
if (NS_FAILED(res)) return res;
if (!target) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
PRInt32 clickCount;
res = mouseEvent->GetDetail(&clickCount);
if (NS_FAILED(res)) return res;
PRBool NodeIsInSelection = PR_FALSE;
if (isContextClick || (buttonNumber == 1 && clickCount == 2))
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor);
if (htmlEditor)
{
// Context menu or double click
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
if (node)
PRUint16 buttonNumber;
res = mouseEvent->GetButton(&buttonNumber);
if (NS_FAILED(res)) return res;
PRBool isContextClick;
// Test if special 'table selection' key is pressed when double-clicking
// so we look for an enclosing cell or table
PRBool tableMode = PR_FALSE;
#ifdef XP_MAC
// Cmd is Mac table-select key
res = mouseEvent->GetMetaKey(&tableMode);
if (NS_FAILED(res)) return res;
// Ctrl+Click for context menu
res = mouseEvent->GetCtrlKey(&isContextClick);
#else
// Right mouse button for Windows, UNIX
isContextClick = buttonNumber == 3;
res = mouseEvent->GetCtrlKey(&tableMode);
#endif
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMEventTarget> target;
res = aMouseEvent->GetTarget(getter_AddRefs(target));
if (NS_FAILED(res)) return res;
if (!target) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
PRInt32 clickCount;
res = mouseEvent->GetDetail(&clickCount);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMSelection> selection;
mEditorShell->GetEditorSelection(getter_AddRefs(selection));
if (!selection) return NS_OK;
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset = 0;
// Get location of mouse within target node
nsCOMPtr<nsIDOMNSUIEvent> uiEvent = do_QueryInterface(aMouseEvent);
if (!uiEvent) return NS_ERROR_FAILURE;
res = uiEvent->GetRangeParent(getter_AddRefs(parent));
if (NS_FAILED(res)) return res;
if (!parent) return NS_ERROR_FAILURE;
res = uiEvent->GetRangeOffset(&offset);
if (NS_FAILED(res)) return res;
// Detect if mouse point is withing current selection
PRBool NodeIsInSelection = PR_FALSE;
PRBool isCollapsed;
selection->GetIsCollapsed(&isCollapsed);
if (!isCollapsed)
{
nsCOMPtr<nsIDOMSelection> selection;
mEditorShell->GetEditorSelection(getter_AddRefs(selection));
if (selection)
PRInt32 rangeCount;
res = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(res)) return res;
for (PRInt32 i = 0; i < rangeCount; i++)
{
res = selection->ContainsNode(node, PR_TRUE, &NodeIsInSelection);
// Kludge: We really want to reposition the caret exactly as done for
// left mouse button, but we never reach the frame's HandlePress method.
// Thus for text nodes, the best we can do is reposition to the start of the node,
// but only if not already selected, of course
if (!NodeIsInSelection)
selection->Collapse(node, 0);
nsCOMPtr<nsIDOMRange> range;
res = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(res) || !range)
continue;//dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(res) || !nsrange)
continue;//dont bail yet, iterate through them all
res = nsrange->IsPointInRange(parent, offset, &NodeIsInSelection);
}
// Get enclosing link
nsCOMPtr<nsIDOMElement> linkElement;
res = mEditorShell->GetElementOrParentByTagName(NS_LITERAL_STRING("href"), node, getter_AddRefs(linkElement));
if (NS_FAILED(res)) return res;
if (linkElement)
element = linkElement;
}
}
if (isContextClick)
{
// Set selection to node clicked on if NOT within an existing selection
if (element && !NodeIsInSelection)
mEditorShell->SelectElement(element);
// Always fall through to do other actions, such as context menu
}
else if (buttonNumber == 1)
{
#ifdef DEBUG_cmanske
// printf("nsEditorShellMouseListener::MouseDown: clickCount=%d\n",clickCount);
#endif
if (tableMode && clickCount == 2)
if (isContextClick || (buttonNumber == 1 && clickCount == 2))
{
if (!GetParentCell(aMouseEvent, getter_AddRefs(element)))
GetParentTable(aMouseEvent, getter_AddRefs(element));
// Context menu or double click
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
if (node && !NodeIsInSelection)
{
selection->Collapse(parent, offset);
// Get enclosing link
nsCOMPtr<nsIDOMElement> linkElement;
res = mEditorShell->GetElementOrParentByTagName(NS_LITERAL_STRING("href"), node, getter_AddRefs(linkElement));
if (NS_FAILED(res)) return res;
if (linkElement)
element = linkElement;
}
}
// No table or cell -- look for other element (ignore text nodes)
if (element)
if (isContextClick)
{
PRInt32 x,y;
res = mouseEvent->GetClientX(&x);
if (NS_FAILED(res)) return res;
// Set selection to node clicked on if NOT within an existing selection
if (element && !NodeIsInSelection)
mEditorShell->SelectElement(element);
// Always fall through to do other actions, such as context menu
}
else if (buttonNumber == 1)
{
if (tableMode && clickCount == 2)
{
if (!GetParentCell(aMouseEvent, getter_AddRefs(element)))
GetParentTable(aMouseEvent, getter_AddRefs(element));
}
// No table or cell -- look for other element (ignore text nodes)
if (element)
{
PRInt32 x,y;
res = mouseEvent->GetClientX(&x);
if (NS_FAILED(res)) return res;
res = mouseEvent->GetClientY(&y);
if (NS_FAILED(res)) return res;
res = mouseEvent->GetClientY(&y);
if (NS_FAILED(res)) return res;
// Let editor decide what to do with this
PRBool handled = PR_FALSE;
mEditorShell->HandleMouseClickOnElement(element, clickCount, x, y, &handled);
// KLUDGE to work around bug 50703: Prevent drag/drop events until we are done
if (clickCount == 2)
htmlEditor->IgnoreSpuriousDragEvent(PR_TRUE);
if (handled)
mouseEvent->PreventDefault();
// Let editor decide what to do with this
PRBool handled = PR_FALSE;
mEditorShell->HandleMouseClickOnElement(element, clickCount, x, y, &handled);
if (handled)
mouseEvent->PreventDefault();
}
}
}
@ -267,10 +313,7 @@ nsEditorShellMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
nsresult
nsEditorShellMouseListener::MouseUp(nsIDOMEvent* aMouseEvent)
{
#ifdef DEBUG_cmanske
printf("* nsEditorShellMouseListener::MouseUp message\n");
#endif
return NS_OK; // didn't handle event
return NS_OK;
}
nsresult

View File

@ -239,6 +239,7 @@ nsHTMLEditor::nsHTMLEditor()
, mIsComposing(PR_FALSE)
, mMaxTextLength(-1)
, mSelectedCellIndex(0)
, mIgnoreSpuriousDragEvent(PR_FALSE)
{
// Done in nsEditor
// NS_INIT_REFCNT();
@ -2620,7 +2621,7 @@ nsHTMLEditor::ReplaceHeadContentsWithHTML(const nsString &aSourceToInsert)
res = nsrange->CreateContextualFragment(inputString,
getter_AddRefs(docfrag));
//XXXX BUG: This is not returning the text between <title> ... </title>
//XXXX BUG 50965: This is not returning the text between <title> ... </title>
// Special code is needed in JS to handle title anyway, so it really doesn't matter!
if (NS_FAILED(res))
@ -5000,7 +5001,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable
return rv;
}
NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
{
ForceCompositionEnd();
@ -5011,74 +5011,150 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
if (dragSession)
if (!dragSession) return NS_OK;
// Get the nsITransferable interface for getting the data from the drop
nsCOMPtr<nsITransferable> trans;
rv = PrepareTransferable(getter_AddRefs(trans));
if (NS_FAILED(rv)) return rv;
if (!trans) return NS_OK; // NS_ERROR_FAILURE; SHOULD WE FAIL?
PRUint32 numItems = 0;
rv = dragSession->GetNumDropItems(&numItems);
if (NS_FAILED(rv)) return rv;
// Combine any deletion and drop insertion into one transaction
nsAutoEditBatch beginBatching(this);
PRUint32 i;
PRBool doPlaceCaret = PR_TRUE;
for (i = 0; i < numItems; ++i)
{
// Get the nsITransferable interface for getting the data from the drop
nsCOMPtr<nsITransferable> trans;
rv = PrepareTransferable(getter_AddRefs(trans));
if (NS_SUCCEEDED(rv) && trans)
rv = dragSession->GetData(trans, i);
if (NS_FAILED(rv)) return rv;
if (!trans) return NS_OK; // NS_ERROR_FAILURE; Should we fail?
if ( doPlaceCaret )
{
PRUint32 numItems = 0;
if (NS_SUCCEEDED(dragSession->GetNumDropItems(&numItems)))
{
PRUint32 i;
PRBool doPlaceCaret = PR_TRUE;
for (i = 0; i < numItems; ++i)
{
if (NS_SUCCEEDED(dragSession->GetData(trans, i)))
{
if ( doPlaceCaret )
{
// check if the user pressed the key to force a copy rather than a move
// if we run into problems here, we'll just assume the user doesn't want a copy
PRBool userWantsCopy = PR_FALSE;
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aDropEvent) );
if (mouseEvent)
// check if the user pressed the key to force a copy rather than a move
// if we run into problems here, we'll just assume the user doesn't want a copy
PRBool userWantsCopy = PR_FALSE;
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aDropEvent));
if (!nsuiEvent) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aDropEvent) );
if (mouseEvent)
#ifdef XP_MAC
mouseEvent->GetAltKey(&userWantsCopy); // check modifiers here
mouseEvent->GetAltKey(&userWantsCopy);
#else
mouseEvent->GetCtrlKey(&userWantsCopy); // check modifiers here
mouseEvent->GetCtrlKey(&userWantsCopy);
#endif
nsCOMPtr<nsIDOMDocument> srcdomdoc;
dragSession->GetSourceDocument(getter_AddRefs(srcdomdoc));
if (srcdomdoc)
{
// do deletion of selection if sourcedocument is current document && appropriate modifier isn't pressed
nsCOMPtr<nsIDOMDocument>destdomdoc;
rv = GetDocument(getter_AddRefs(destdomdoc));
if ( NS_SUCCEEDED(rv) && !userWantsCopy && (srcdomdoc == destdomdoc) )
{
rv = DeleteSelection(eNone);
if (NS_FAILED(rv))
return rv;
}
}
// Source doc is null if source is *not* the current editor document
nsCOMPtr<nsIDOMDocument> srcdomdoc;
rv = dragSession->GetSourceDocument(getter_AddRefs(srcdomdoc));
if (NS_FAILED(rv)) return rv;
// Set the selection to the point under the mouse cursor:
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aDropEvent));
// Current doc is destination
nsCOMPtr<nsIDOMDocument>destdomdoc;
rv = GetDocument(getter_AddRefs(destdomdoc));
if (NS_FAILED(rv)) return rv;
if (!nsuiEvent)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parent;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeParent(getter_AddRefs(parent))))
return NS_ERROR_NULL_POINTER;
PRInt32 offset = 0;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeOffset(&offset)))
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMSelection> selection;
rv = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv)) return rv;
if (!selection) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(GetSelection(getter_AddRefs(selection))))
(void)selection->Collapse(parent, offset);
PRBool isCollapsed;
rv = selection->GetIsCollapsed(&isCollapsed);
if (NS_FAILED(rv)) return rv;
// Parent and offset under the mouse cursor
nsCOMPtr<nsIDOMNode> newSelectionParent;
PRInt32 newSelectionOffset = 0;
rv = nsuiEvent->GetRangeParent(getter_AddRefs(newSelectionParent));
if (NS_FAILED(rv)) return rv;
if (!newSelectionParent) return NS_ERROR_FAILURE;
doPlaceCaret = PR_FALSE;
}
rv = InsertFromTransferable(trans);
rv = nsuiEvent->GetRangeOffset(&newSelectionOffset);
if (NS_FAILED(rv)) return rv;
// We never have to delete if selection is already collapsed
PRBool deleteSelection = PR_FALSE;
PRBool cursorIsInSelection = PR_FALSE;
// Check if mouse is in the selection
if (!isCollapsed)
{
PRInt32 rangeCount;
rv = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
for (PRInt32 j = 0; j < rangeCount; j++)
{
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(j, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue;//dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue;//dont bail yet, iterate through them all
rv = nsrange->IsPointInRange(newSelectionParent, newSelectionOffset, &cursorIsInSelection);
if(cursorIsInSelection)
break;
}
if (cursorIsInSelection)
{
// Dragging within same doc can't drop on itself -- leave!
// (We shouldn't get here - drag event shouldn't have started if over selection)
if (srcdomdoc == destdomdoc)
return NS_OK;
// Dragging from another window onto a selection
// XXX Decision made to NOT do this,
// note that 4.x does replace if dropped on
//deleteSelection = PR_TRUE;
}
else
{
// We are NOT over the selection
if (srcdomdoc == destdomdoc)
{
// Within the same doc: delete if user doesn't want to copy
deleteSelection = !userWantsCopy;
}
else
{
// Different source doc: Don't delete
deleteSelection = PR_FALSE;
}
}
}
if (deleteSelection)
{
rv = DeleteSelection(eNone);
if (NS_FAILED(rv)) return rv;
}
// If we deleted the selection because we dropped from another doc,
// then we don't have to relocate the caret (insert at the deletion point)
if (!(deleteSelection && srcdomdoc != destdomdoc))
{
// Move the selection to the point under the mouse cursor
selection->Collapse(newSelectionParent, newSelectionOffset);
}
// We have to figure out whether to delete and relocate caret only once
doPlaceCaret = PR_FALSE;
}
rv = InsertFromTransferable(trans);
}
return rv;
@ -5090,7 +5166,19 @@ NS_IMETHODIMP nsHTMLEditor::CanDrag(nsIDOMEvent *aDragEvent, PRBool &aCanDrag)
* that particular point is actually within the selection (not just that there is a selection)
*/
aCanDrag = PR_FALSE;
// KLUDGE to work around bug 50703
// After double click and object property editing,
// we get a spurious drag event
if (mIgnoreSpuriousDragEvent)
{
#ifdef DEBUG_cmanske
printf(" *** IGNORING SPURIOUS DRAG EVENT!\n");
#endif
mIgnoreSpuriousDragEvent = PR_FALSE;
return NS_OK;
}
nsCOMPtr<nsIDOMSelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res)) return res;

View File

@ -577,6 +577,10 @@ protected:
nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver);
//XXX Kludge: Used to suppress spurious drag/drop events (bug 50703)
PRBool mIgnoreSpuriousDragEvent;
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;}
// Data members
protected:

View File

@ -682,11 +682,11 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
{
nsresult rv;
NS_WITH_SERVICE(nsIDragService, dragService, "component://netscape/widget/dragservice", &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
if (dragSession)
{
{
PRBool flavorSupported = PR_FALSE;
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
if ( !flavorSupported )
@ -696,54 +696,73 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
if ( !flavorSupported )
dragSession->IsDataFlavorSupported(kJPEGImageMime, &flavorSupported);
if (! flavorSupported )
return NS_OK;
}
return NS_OK;
}
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
if (!nsuiEvent) return NS_OK;
//some day we want to use another way to stop this from bubbling.
aMouseEvent->PreventBubble();
aMouseEvent->PreventDefault();
/* for bug 47399, when dropping a drag session, if you are over your original
selection, nothing should happen. */
nsCOMPtr<nsIDOMSelection> tempSelection;
rv = mEditor->GetSelection(getter_AddRefs(tempSelection));
if (NS_FAILED(rv) || !tempSelection)
selection, nothing should happen.
cmanske: But do this only if drag source is not the same as target (current) document!
*/
nsCOMPtr<nsIDOMSelection> selection;
rv = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv) || !selection)
return rv?rv:NS_ERROR_FAILURE;
PRInt32 rangeCount;
rv = tempSelection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = do_QueryInterface(htmlEditor);
nsCOMPtr<nsIDOMDocument> domdoc;
rv = editor->GetDocument(getter_AddRefs(domdoc));
if (NS_FAILED(rv)) return rv;
for(int i = 0; i < rangeCount; i++)
nsCOMPtr<nsIDOMDocument> sourceDoc;
rv = dragSession->GetSourceDocument(getter_AddRefs(sourceDoc));
if (NS_FAILED(rv)) return rv;
if (domdoc == sourceDoc)
{
nsCOMPtr<nsIDOMRange> range;
PRBool isCollapsed;
rv = selection->GetIsCollapsed(&isCollapsed);
if (NS_FAILED(rv)) return rv;
// Don't bother if collapsed - can always drop
if (!isCollapsed)
{
nsCOMPtr<nsIDOMNode> parent;
rv = nsuiEvent->GetRangeParent(getter_AddRefs(parent));
if (NS_FAILED(rv)) return rv;
if (!parent) return NS_ERROR_FAILURE;
rv = tempSelection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue;//dont bail yet, iterate through them all
PRInt32 offset = 0;
rv = nsuiEvent->GetRangeOffset(&offset);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue;//dont bail yet, iterate through them all
PRInt32 rangeCount;
rv = selection->GetRangeCount(&rangeCount);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
if (!nsuiEvent)
continue;//dont bail yet, iterate through them all
for (PRInt32 i = 0; i < rangeCount; i++)
{
nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsIDOMNode> parent;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeParent(getter_AddRefs(parent))))
continue;//dont bail yet, iterate through them all
rv = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue;//dont bail yet, iterate through them all
PRInt32 offset = 0;
if (!NS_SUCCEEDED(nsuiEvent->GetRangeOffset(&offset)))
continue;//dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue;//dont bail yet, iterate through them all
PRBool inrange;
rv = nsrange->IsPointInRange(parent, offset, &inrange);
if(inrange)
return NS_ERROR_FAILURE;//okay, now you can bail, we are over the orginal selection
PRBool inrange;
rv = nsrange->IsPointInRange(parent, offset, &inrange);
if(inrange)
return NS_ERROR_FAILURE;//okay, now you can bail, we are over the orginal selection
}
}
}
// if we are not over orginal selection, drop that baby!
return htmlEditor->InsertFromDrop(aMouseEvent);

View File

@ -466,19 +466,26 @@ public:
*/
NS_IMETHOD InsertLinkAroundSelection(nsIDOMElement* aAnchorElement)=0;
/**
* Document me!
*
*/
/** Set the value of the "bgcolor" attribute on the document's <body> element
*
* @param aColor The HTML color string, such as "#ffccff" or "yellow"
*/
NS_IMETHOD SetBackgroundColor(const nsString& aColor)=0;
/**
* Document me!
*
*/
/** Set an attribute on the document's <body> element
* such as text, link, background colors
*
* 8/31/00 THIS ISN'T BEING USED? SHOULD WE DROP IT?
*
* @param aAttr The attribute to be set
* @param aValue The value of the attribute
*/
NS_IMETHOD SetBodyAttribute(const nsString& aAttr, const nsString& aValue)=0;
//XXX Used to suppress spurious drag/drop events to workaround bug 50703
// Don't use this method! It will go away after first release!
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent)=0;
};

View File

@ -362,8 +362,6 @@ function ValidateAndPreviewImage(ShowErrorMessage)
}
else backgroundImage = null;
dump("ValidateAndPreviewImage: styleValue ="+styleValue+"\n");
// Set style on preview (removes image if not valid)
dialog.ColorPreview.setAttribute(styleStr, styleValue);