зеркало из https://github.com/mozilla/gecko-dev.git
cleanup transferable hooks in editor; defer selection manipulation in plain text; ensure hooks are properly positioned (bug 203062) r=kaie, kin; sr=smfr
This commit is contained in:
Родитель
a8b6dc06df
Коммит
8795f96966
|
@ -45,6 +45,14 @@
|
|||
#include "nsIEnumerator.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
// hooks
|
||||
#include "nsIClipboardDragDropHooks.h"
|
||||
#include "nsIClipboardDragDropHookList.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* nsAutoSelectionReset
|
||||
|
@ -238,3 +246,141 @@ nsEditorUtils::IsLeafNode(nsIDOMNode *aNode)
|
|||
aNode->HasChildNodes(&hasChildren);
|
||||
return !hasChildren;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* utility methods for drag/drop/copy/paste hooks
|
||||
*****************************************************************************/
|
||||
|
||||
nsresult
|
||||
nsEditorHookUtils::GetHookEnumeratorFromDocument(nsIDOMDocument *aDoc,
|
||||
nsISimpleEnumerator **aResult)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
doc->GetContainer(getter_AddRefs(isupp));
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(isupp);
|
||||
nsCOMPtr<nsIClipboardDragDropHookList> hookObj = do_GetInterface(docShell);
|
||||
if (!hookObj) return NS_ERROR_FAILURE;
|
||||
|
||||
return hookObj->GetHookEnumerator(aResult);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoAllowDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aDragEvent)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool canDrag = PR_TRUE;
|
||||
nsresult hookres = override->AllowStartDrag(aDragEvent, &canDrag);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookres), "hook failure in AllowStartDrag");
|
||||
if (!canDrag)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoDragHook(nsIDOMDocument *aDoc, nsITransferable *aTrans)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool canInvokeDrag = PR_TRUE;
|
||||
nsresult hookResult = override->OnCopyOrDrag(aTrans, &canInvokeDrag);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in OnCopyOrDrag");
|
||||
if (!canInvokeDrag)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoAllowDropHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsIDragSession *aSession)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool allowDrop = PR_TRUE;
|
||||
nsresult hookResult = override->AllowDrop(aEvent, aSession, &allowDrop);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in AllowDrop");
|
||||
if (!allowDrop)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoInsertionHook(nsIDOMDocument *aDoc, nsIDOMEvent *aDropEvent,
|
||||
nsITransferable *aTrans)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool doInsert = PR_TRUE;
|
||||
nsresult hookResult = override->OnPasteOrDrop(aDropEvent, aTrans, &doInsert);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in OnPasteOrDrop");
|
||||
if (!doInsert)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -266,4 +266,24 @@ class nsEditorUtils
|
|||
static PRBool IsLeafNode(nsIDOMNode *aNode);
|
||||
};
|
||||
|
||||
|
||||
class nsIDragSession;
|
||||
class nsITransferable;
|
||||
class nsIDOMEvent;
|
||||
class nsISimpleEnumerator;
|
||||
|
||||
class nsEditorHookUtils
|
||||
{
|
||||
public:
|
||||
static PRBool DoAllowDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent);
|
||||
static PRBool DoDragHook(nsIDOMDocument *aDoc, nsITransferable *aTrans);
|
||||
static PRBool DoAllowDropHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsIDragSession *aSession);
|
||||
static PRBool DoInsertionHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsITransferable *aTrans);
|
||||
private:
|
||||
static nsresult GetHookEnumeratorFromDocument(nsIDOMDocument *aDoc,
|
||||
nsISimpleEnumerator **aEnumerator);
|
||||
};
|
||||
|
||||
#endif // nsEditorUtils_h__
|
||||
|
|
|
@ -1073,7 +1073,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable
|
|||
stuffToPaste.Assign(text.get(), len / 2);
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
// need to provide a hook from this point
|
||||
rv = InsertText(stuffToPaste);
|
||||
rv = InsertTextAt(stuffToPaste, aDestinationNode, aDestOffset, aDoDeleteSelection);
|
||||
}
|
||||
}
|
||||
else if (flavor.Equals(NS_LITERAL_STRING(kFileMime)))
|
||||
|
@ -1164,8 +1164,9 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
if (!dragSession) return NS_OK;
|
||||
|
||||
// transferable hooks here
|
||||
PRBool isAllowed = PR_TRUE;
|
||||
DoAllowDropHook(aDropEvent, dragSession, &isAllowed);
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
PRBool isAllowed = nsEditorHookUtils::DoAllowDropHook(domdoc, aDropEvent, dragSession);
|
||||
if (!isAllowed)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -1181,12 +1182,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
if (!trans) return NS_OK; // NS_ERROR_FAILURE; SHOULD WE FAIL?
|
||||
|
||||
// handle transferable hooks
|
||||
PRBool doInsert = PR_TRUE;
|
||||
DoInsertionHook(aDropEvent, trans, &doInsert);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 numItems = 0;
|
||||
rv = dragSession->GetNumDropItems(&numItems);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -1194,6 +1189,11 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
// Combine any deletion and drop insertion into one transaction
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// We never have to delete if selection is already collapsed
|
||||
PRBool deleteSelection = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> newSelectionParent;
|
||||
PRInt32 newSelectionOffset = 0;
|
||||
|
||||
PRUint32 i;
|
||||
PRBool doPlaceCaret = PR_TRUE;
|
||||
for (i = 0; i < numItems; ++i)
|
||||
|
@ -1238,11 +1238,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
infoStr.Assign(text.get(), infoLen / 2);
|
||||
}
|
||||
|
||||
// We never have to delete if selection is already collapsed
|
||||
PRBool deleteSelection = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> newSelectionParent;
|
||||
PRInt32 newSelectionOffset = 0;
|
||||
|
||||
if (doPlaceCaret)
|
||||
{
|
||||
// check if the user pressed the key to force a copy rather than a move
|
||||
|
@ -1372,6 +1367,11 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
doPlaceCaret = PR_FALSE;
|
||||
}
|
||||
|
||||
// handle transferable hooks
|
||||
PRBool doInsert = nsEditorHookUtils::DoInsertionHook(domdoc, aDropEvent, trans);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
rv = InsertFromTransferable(trans, contextStr, infoStr, newSelectionParent,
|
||||
newSelectionOffset, deleteSelection);
|
||||
}
|
||||
|
@ -1541,12 +1541,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
|||
rv = PrepareHTMLTransferable(getter_AddRefs(trans), bHavePrivateHTMLFlavor);
|
||||
if (NS_SUCCEEDED(rv) && trans)
|
||||
{
|
||||
// handle transferable hooks
|
||||
PRBool doInsert = PR_TRUE;
|
||||
DoInsertionHook(nsnull, trans, &doInsert);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
// Get the Data from the clipboard
|
||||
if (NS_SUCCEEDED(clipboard->GetData(trans, aSelectionType)) && IsModifiable())
|
||||
{
|
||||
|
@ -1590,6 +1584,14 @@ NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
|||
infoStr.Assign(text.get(), infoLen / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// handle transferable hooks
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
PRBool doInsert = nsEditorHookUtils::DoInsertionHook(domdoc, nsnull, trans);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
rv = InsertFromTransferable(trans, contextStr, infoStr,
|
||||
nsnull, 0, PR_TRUE);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ REQUIRES = xpcom \
|
|||
gfx \
|
||||
widget \
|
||||
unicharutil \
|
||||
docshell \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsIDOMNSRange.h"
|
||||
#include "nsEditorUtils.h"
|
||||
|
||||
// Drag & Drop, Clipboard Support
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
@ -661,6 +662,13 @@ nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent)
|
|||
if (!dragSession) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool canDrop = CanDrop(aDragEvent);
|
||||
if (canDrop)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
mEditor->GetDocument(getter_AddRefs(domdoc));
|
||||
canDrop = nsEditorHookUtils::DoAllowDropHook(domdoc, aDragEvent, dragSession);
|
||||
}
|
||||
|
||||
dragSession->SetCanDrop(canDrop);
|
||||
|
||||
// We need to consume the event to prevent the browser's
|
||||
|
|
|
@ -35,95 +35,45 @@
|
|||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsICaret.h"
|
||||
|
||||
|
||||
#include "nsPlaintextEditor.h"
|
||||
#include "nsTextEditUtils.h"
|
||||
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIServiceManagerUtils.h"
|
||||
|
||||
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIHTMLContentContainer.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsIDocumentObserver.h"
|
||||
#include "nsIDocumentStateListener.h"
|
||||
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsEditorCID.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDOMNSRange.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsAOLCiter.h"
|
||||
#include "nsInternetCiter.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
// netwerk
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
// Drag & Drop, Clipboard
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIClipboardDragDropHooks.h"
|
||||
#include "nsIClipboardDragDropHookList.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
// Misc
|
||||
#include "nsEditorUtils.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
const PRUnichar nbsp = 160;
|
||||
|
||||
// Drag & Drop, Clipboard Support
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
static NS_DEFINE_CID(kCHTMLFormatConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
// private clipboard data flavors for html copy/paste
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
|
||||
#if defined(NS_DEBUG) && defined(DEBUG_buster)
|
||||
static PRBool gNoisy = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gNoisy = PR_FALSE;
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::PrepareTransferable(nsITransferable **transferable)
|
||||
{
|
||||
|
@ -139,13 +89,47 @@ NS_IMETHODIMP nsPlaintextEditor::PrepareTransferable(nsITransferable **transfera
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::InsertTextFromTransferable(nsITransferable *transferable)
|
||||
nsresult nsPlaintextEditor::InsertTextAt(const nsAString &aStringToInsert,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
PRBool aDoDeleteSelection)
|
||||
{
|
||||
if (aDestinationNode)
|
||||
{
|
||||
nsresult res;
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> targetNode = aDestinationNode;
|
||||
PRInt32 targetOffset = aDestOffset;
|
||||
|
||||
if (aDoDeleteSelection)
|
||||
{
|
||||
// Use an auto tracker so that our drop point is correctly
|
||||
// positioned after the delete.
|
||||
nsAutoTrackDOMPoint tracker(mRangeUpdater, &targetNode, &targetOffset);
|
||||
res = DeleteSelection(eNone);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
|
||||
res = selection->Collapse(targetNode, targetOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
|
||||
return InsertText(aStringToInsert);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::InsertTextFromTransferable(nsITransferable *aTransferable,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
PRBool aDoDeleteSelection)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
char* bestFlavor = nsnull;
|
||||
nsCOMPtr<nsISupports> genericDataObj;
|
||||
PRUint32 len = 0;
|
||||
if ( NS_SUCCEEDED(transferable->GetAnyTransferData(&bestFlavor, getter_AddRefs(genericDataObj), &len)) )
|
||||
if ( NS_SUCCEEDED(aTransferable->GetAnyTransferData(&bestFlavor, getter_AddRefs(genericDataObj), &len)) )
|
||||
{
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(this);
|
||||
nsAutoString flavor, stuffToPaste;
|
||||
|
@ -160,7 +144,7 @@ NS_IMETHODIMP nsPlaintextEditor::InsertTextFromTransferable(nsITransferable *tra
|
|||
NS_ASSERTION(text.Length() <= (len/2), "Invalid length!");
|
||||
stuffToPaste.Assign ( text.get(), len / 2 );
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
rv = InsertText(stuffToPaste);
|
||||
rv = InsertTextAt(stuffToPaste, aDestinationNode, aDestOffset, aDoDeleteSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,8 +171,9 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
if (!dragSession) return NS_OK;
|
||||
|
||||
// transferable hooks
|
||||
PRBool isAllowed = PR_TRUE;
|
||||
DoAllowDropHook(aDropEvent, dragSession, &isAllowed);
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
PRBool isAllowed = nsEditorHookUtils::DoAllowDropHook(domdoc, aDropEvent, dragSession);
|
||||
if (!isAllowed)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -198,11 +183,6 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
if (!trans) return NS_OK; // NS_ERROR_FAILURE; SHOULD WE FAIL?
|
||||
|
||||
PRBool doInsert = PR_TRUE;
|
||||
DoInsertionHook(aDropEvent, trans, &doInsert);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 numItems = 0;
|
||||
rv = dragSession->GetNumDropItems(&numItems);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -210,6 +190,10 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
// Combine any deletion and drop insertion into one transaction
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
PRBool deleteSelection = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> newSelectionParent;
|
||||
PRInt32 newSelectionOffset = 0;
|
||||
|
||||
PRUint32 i;
|
||||
PRBool doPlaceCaret = PR_TRUE;
|
||||
for (i = 0; i < numItems; ++i)
|
||||
|
@ -255,8 +239,6 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
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;
|
||||
|
@ -265,7 +247,6 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
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
|
||||
|
@ -320,27 +301,15 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||
}
|
||||
}
|
||||
|
||||
if (deleteSelection)
|
||||
{
|
||||
// Use an auto tracker so that our drop point is correctly
|
||||
// positioned after the delete.
|
||||
nsAutoTrackDOMPoint tracker(mRangeUpdater, &newSelectionParent, &newSelectionOffset);
|
||||
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 = InsertTextFromTransferable(trans);
|
||||
PRBool doInsert = nsEditorHookUtils::DoInsertionHook(domdoc, aDropEvent, trans);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
rv = InsertTextFromTransferable(trans, newSelectionParent, newSelectionOffset, deleteSelection);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -403,37 +372,7 @@ NS_IMETHODIMP nsPlaintextEditor::CanDrag(nsIDOMEvent *aDragEvent, PRBool *aCanDr
|
|||
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
doc->GetContainer(getter_AddRefs(isupp));
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(isupp);
|
||||
nsCOMPtr<nsIClipboardDragDropHookList> hookObj = do_GetInterface(docShell);
|
||||
if (!hookObj) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
hookObj->GetHookEnumerator(getter_AddRefs(enumerator));
|
||||
if (!enumerator) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override;
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks))
|
||||
&& hasMoreHooks)
|
||||
{
|
||||
res = enumerator->GetNext(getter_AddRefs(isupp));
|
||||
if (NS_FAILED(res)) break;
|
||||
override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
res = override->AllowStartDrag(aDragEvent, aCanDrag);
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "hook failure in AllowStartDrag");
|
||||
}
|
||||
|
||||
if (!*aCanDrag)
|
||||
break;
|
||||
}
|
||||
|
||||
*aCanDrag = nsEditorHookUtils::DoAllowDragHook(domdoc, aDragEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -464,38 +403,8 @@ NS_IMETHODIMP nsPlaintextEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|||
// check our transferable hooks (if any)
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
doc->GetContainer(getter_AddRefs(isupp));
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(isupp);
|
||||
nsCOMPtr<nsIClipboardDragDropHookList> hookObj = do_GetInterface(docShell);
|
||||
if (!hookObj) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
hookObj->GetHookEnumerator(getter_AddRefs(enumerator));
|
||||
if (!enumerator) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override;
|
||||
PRBool canInvokeDrag = PR_TRUE;
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks))
|
||||
&& hasMoreHooks)
|
||||
{
|
||||
rv = enumerator->GetNext(getter_AddRefs(isupp));
|
||||
if (NS_FAILED(rv)) break;
|
||||
override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
nsresult hookResult = override->OnCopyOrDrag(trans, &canInvokeDrag);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in OnCopyOrDrag");
|
||||
}
|
||||
|
||||
// if one of our overrides says we can't invoke drag, return now
|
||||
if (!canInvokeDrag)
|
||||
return NS_OK;
|
||||
}
|
||||
if (!nsEditorHookUtils::DoDragHook(domdoc, trans))
|
||||
return NS_OK;
|
||||
|
||||
/* invoke drag */
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
|
@ -532,16 +441,17 @@ NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
|||
rv = PrepareTransferable(getter_AddRefs(trans));
|
||||
if (NS_SUCCEEDED(rv) && trans)
|
||||
{
|
||||
// handle transferable hooks
|
||||
PRBool doInsert = PR_TRUE;
|
||||
DoInsertionHook(nsnull, trans, &doInsert);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
// Get the Data from the clipboard
|
||||
if (NS_SUCCEEDED(clipboard->GetData(trans, aSelectionType)) && IsModifiable())
|
||||
{
|
||||
rv = InsertTextFromTransferable(trans);
|
||||
// handle transferable hooks
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
PRBool doInsert = nsEditorHookUtils::DoInsertionHook(domdoc, nsnull, trans);
|
||||
if (!doInsert)
|
||||
return NS_OK;
|
||||
|
||||
rv = InsertTextFromTransferable(trans, nsnull, nsnull, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -707,84 +617,3 @@ nsPlaintextEditor::PutDragDataInTransferable(nsITransferable **aTransferable)
|
|||
NS_ADDREF(*aTransferable);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlaintextEditor::DoAllowDropHook(nsIDOMEvent* aDropEvent,
|
||||
nsIDragSession *aSession, PRBool *aAllowDrop)
|
||||
{
|
||||
*aAllowDrop = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
doc->GetContainer(getter_AddRefs(isupp));
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(isupp);
|
||||
nsCOMPtr<nsIClipboardDragDropHookList> hookObj = do_GetInterface(docShell);
|
||||
if (!hookObj) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
hookObj->GetHookEnumerator(getter_AddRefs(enumerator));
|
||||
if (!enumerator) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override;
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
nsresult res = NS_OK;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
res = enumerator->GetNext(getter_AddRefs(isupp));
|
||||
if (NS_FAILED(res)) break;
|
||||
override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
nsresult hookResult = override->AllowDrop(aDropEvent, aSession, aAllowDrop);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in AllowDrop");
|
||||
}
|
||||
|
||||
if (!*aAllowDrop)
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsPlaintextEditor::DoInsertionHook(nsIDOMEvent* aDropEvent,
|
||||
nsITransferable *aTrans, PRBool *aDoInsert)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
doc->GetContainer(getter_AddRefs(isupp));
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(isupp);
|
||||
nsCOMPtr<nsIClipboardDragDropHookList> hookObj = do_GetInterface(docShell);
|
||||
if (!hookObj) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
hookObj->GetHookEnumerator(getter_AddRefs(enumerator));
|
||||
if (!enumerator) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override;
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
nsresult res = NS_OK;
|
||||
while (*aDoInsert &&
|
||||
NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
res = enumerator->GetNext(getter_AddRefs(isupp));
|
||||
if (NS_FAILED(res)) break;
|
||||
override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
nsresult hookResult = override->OnPasteOrDrop(aDropEvent, aTrans, aDoInsert);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in OnPasteOrDrop");
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ class nsIDOMKeyEvent;
|
|||
class nsITransferable;
|
||||
class nsIDOMEventReceiver;
|
||||
class nsIDocumentEncoder;
|
||||
class nsIDragSession;
|
||||
|
||||
/**
|
||||
* The text editor implementation.
|
||||
|
@ -186,6 +185,11 @@ public:
|
|||
PRInt32 &aOutStartOffset,
|
||||
PRInt32 &aEndOffset);
|
||||
|
||||
nsresult InsertTextAt(const nsAString &aStringToInsert,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
PRBool aDoDeleteSelection);
|
||||
|
||||
protected:
|
||||
|
||||
NS_IMETHOD InitRules();
|
||||
|
@ -226,12 +230,12 @@ protected:
|
|||
|
||||
// factored methods for handling insertion of data from transferables (drag&drop or clipboard)
|
||||
NS_IMETHOD PrepareTransferable(nsITransferable **transferable);
|
||||
NS_IMETHOD InsertTextFromTransferable(nsITransferable *transferable);
|
||||
NS_IMETHOD InsertTextFromTransferable(nsITransferable *transferable,
|
||||
nsIDOMNode *aDestinationNode,
|
||||
PRInt32 aDestOffset,
|
||||
PRBool aDoDeleteSelection);
|
||||
virtual nsresult SetupDocEncoder(nsIDocumentEncoder **aDocEncoder);
|
||||
virtual nsresult PutDragDataInTransferable(nsITransferable **aTransferable);
|
||||
virtual nsresult DoAllowDropHook(nsIDOMEvent* aDropEvent, nsIDragSession *aSession, PRBool *aAllowDrop);
|
||||
virtual nsresult DoInsertionHook(nsIDOMEvent* aDropEvent,
|
||||
nsITransferable *aTrans, PRBool *aDoInsert);
|
||||
|
||||
/** simple utility to handle any error with event listener allocation or registration */
|
||||
void HandleEventListenerError();
|
||||
|
|
Загрузка…
Ссылка в новой задаче