зеркало из https://github.com/mozilla/gecko-dev.git
Bug 539476, use the system event group for editor drop listeners, so that the default action can be prevented, r=smaug
This commit is contained in:
Родитель
f6cd0b6d60
Коммит
cfa97b3d01
|
@ -374,16 +374,16 @@ nsEditor::InstallEventListeners()
|
||||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(piTarget));
|
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(piTarget));
|
||||||
if (target) {
|
if (target) {
|
||||||
// See bug 455215, we cannot use the standard dragstart event yet
|
// See bug 455215, we cannot use the standard dragstart event yet
|
||||||
rv |= target->AddEventListener(NS_LITERAL_STRING("draggesture"),
|
rv |= elmP->AddEventListenerByType(mEventListener, NS_LITERAL_STRING("draggesture"),
|
||||||
mEventListener, PR_FALSE);
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
rv |= target->AddEventListener(NS_LITERAL_STRING("dragenter"),
|
rv |= elmP->AddEventListenerByType(mEventListener, NS_LITERAL_STRING("dragenter"),
|
||||||
mEventListener, PR_FALSE);
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
rv |= target->AddEventListener(NS_LITERAL_STRING("dragover"),
|
rv |= elmP->AddEventListenerByType(mEventListener, NS_LITERAL_STRING("dragover"),
|
||||||
mEventListener, PR_FALSE);
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
rv |= target->AddEventListener(NS_LITERAL_STRING("dragleave"),
|
rv |= elmP->AddEventListenerByType(mEventListener, NS_LITERAL_STRING("dragleave"),
|
||||||
mEventListener, PR_FALSE);
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
rv |= target->AddEventListener(NS_LITERAL_STRING("drop"),
|
rv |= elmP->AddEventListenerByType(mEventListener, NS_LITERAL_STRING("drop"),
|
||||||
mEventListener, PR_FALSE);
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
|
@ -417,9 +417,17 @@ nsEditor::RemoveEventListeners()
|
||||||
{
|
{
|
||||||
elmP->RemoveEventListenerByType(mEventListener,
|
elmP->RemoveEventListenerByType(mEventListener,
|
||||||
NS_LITERAL_STRING("keypress"),
|
NS_LITERAL_STRING("keypress"),
|
||||||
NS_EVENT_FLAG_BUBBLE |
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
NS_PRIV_EVENT_UNTRUSTED_PERMITTED,
|
elmP->RemoveEventListenerByType(mEventListener, NS_LITERAL_STRING("draggesture"),
|
||||||
sysGroup);
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
|
elmP->RemoveEventListenerByType(mEventListener, NS_LITERAL_STRING("dragenter"),
|
||||||
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
|
elmP->RemoveEventListenerByType(mEventListener, NS_LITERAL_STRING("dragover"),
|
||||||
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
|
elmP->RemoveEventListenerByType(mEventListener, NS_LITERAL_STRING("dragleave"),
|
||||||
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
|
elmP->RemoveEventListenerByType(mEventListener, NS_LITERAL_STRING("drop"),
|
||||||
|
NS_EVENT_FLAG_BUBBLE, sysGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
piTarget->RemoveEventListenerByIID(mEventListener,
|
piTarget->RemoveEventListenerByIID(mEventListener,
|
||||||
|
@ -434,20 +442,6 @@ nsEditor::RemoveEventListeners()
|
||||||
|
|
||||||
piTarget->RemoveEventListenerByIID(mEventListener,
|
piTarget->RemoveEventListenerByIID(mEventListener,
|
||||||
NS_GET_IID(nsIDOMCompositionListener));
|
NS_GET_IID(nsIDOMCompositionListener));
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(piTarget));
|
|
||||||
if (target) {
|
|
||||||
target->RemoveEventListener(NS_LITERAL_STRING("draggesture"),
|
|
||||||
mEventListener, PR_FALSE);
|
|
||||||
target->RemoveEventListener(NS_LITERAL_STRING("dragenter"),
|
|
||||||
mEventListener, PR_FALSE);
|
|
||||||
target->RemoveEventListener(NS_LITERAL_STRING("dragover"),
|
|
||||||
mEventListener, PR_FALSE);
|
|
||||||
target->RemoveEventListener(NS_LITERAL_STRING("dragleave"),
|
|
||||||
mEventListener, PR_FALSE);
|
|
||||||
target->RemoveEventListener(NS_LITERAL_STRING("drop"),
|
|
||||||
mEventListener, PR_FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "nsEditor.h"
|
#include "nsEditor.h"
|
||||||
#include "nsIPlaintextEditor.h"
|
#include "nsIPlaintextEditor.h"
|
||||||
|
|
||||||
|
#include "nsIDOMDOMStringList.h"
|
||||||
#include "nsIDOMEvent.h"
|
#include "nsIDOMEvent.h"
|
||||||
#include "nsIDOMNSEvent.h"
|
#include "nsIDOMNSEvent.h"
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIDOMDocument.h"
|
||||||
|
@ -73,6 +74,7 @@
|
||||||
#include "nsIDOMDragEvent.h"
|
#include "nsIDOMDragEvent.h"
|
||||||
#include "nsIFocusManager.h"
|
#include "nsIFocusManager.h"
|
||||||
#include "nsIDOMWindow.h"
|
#include "nsIDOMWindow.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
nsEditorEventListener::nsEditorEventListener(nsEditor* aEditor) :
|
nsEditorEventListener::nsEditorEventListener(nsEditor* aEditor) :
|
||||||
mEditor(aEditor), mCaretDrawn(PR_FALSE), mCommitText(PR_FALSE),
|
mEditor(aEditor), mCaretDrawn(PR_FALSE), mCommitText(PR_FALSE),
|
||||||
|
@ -488,19 +490,14 @@ nsEditorEventListener::DragEnter(nsIDOMDragEvent* aDragEvent)
|
||||||
nsresult
|
nsresult
|
||||||
nsEditorEventListener::DragOver(nsIDOMDragEvent* aDragEvent)
|
nsEditorEventListener::DragOver(nsIDOMDragEvent* aDragEvent)
|
||||||
{
|
{
|
||||||
// XXX cache this between drag events?
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
|
|
||||||
if (!dragService) return rv;
|
|
||||||
|
|
||||||
// does the drag have flavors we can accept?
|
|
||||||
nsCOMPtr<nsIDragSession> dragSession;
|
|
||||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
|
||||||
if (!dragSession) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> parent;
|
nsCOMPtr<nsIDOMNode> parent;
|
||||||
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent = do_QueryInterface(aDragEvent);
|
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent = do_QueryInterface(aDragEvent);
|
||||||
if (nsuiEvent) {
|
if (nsuiEvent) {
|
||||||
|
PRBool defaultPrevented;
|
||||||
|
nsuiEvent->GetPreventDefault(&defaultPrevented);
|
||||||
|
if (defaultPrevented)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
nsuiEvent->GetRangeParent(getter_AddRefs(parent));
|
nsuiEvent->GetRangeParent(getter_AddRefs(parent));
|
||||||
nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
|
nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
|
||||||
if (!dropParent)
|
if (!dropParent)
|
||||||
|
@ -511,18 +508,14 @@ nsEditorEventListener::DragOver(nsIDOMDragEvent* aDragEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool canDrop = CanDrop(aDragEvent);
|
PRBool canDrop = CanDrop(aDragEvent);
|
||||||
dragSession->SetCanDrop(canDrop);
|
|
||||||
|
|
||||||
if (canDrop)
|
if (canDrop)
|
||||||
{
|
{
|
||||||
// We need to consume the event to prevent the browser's
|
|
||||||
// default drag listeners from being fired. (Bug 199133)
|
|
||||||
aDragEvent->PreventDefault(); // consumed
|
aDragEvent->PreventDefault(); // consumed
|
||||||
|
|
||||||
if (mCaret && nsuiEvent)
|
if (mCaret && nsuiEvent)
|
||||||
{
|
{
|
||||||
PRInt32 offset = 0;
|
PRInt32 offset = 0;
|
||||||
rv = nsuiEvent->GetRangeOffset(&offset);
|
nsresult rv = nsuiEvent->GetRangeOffset(&offset);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// to avoid flicker, we could track the node and offset to see if we moved
|
// to avoid flicker, we could track the node and offset to see if we moved
|
||||||
|
@ -586,6 +579,11 @@ nsEditorEventListener::Drop(nsIDOMDragEvent* aMouseEvent)
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent = do_QueryInterface(aMouseEvent);
|
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent = do_QueryInterface(aMouseEvent);
|
||||||
if (nsuiEvent) {
|
if (nsuiEvent) {
|
||||||
|
PRBool defaultPrevented;
|
||||||
|
nsuiEvent->GetPreventDefault(&defaultPrevented);
|
||||||
|
if (defaultPrevented)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> parent;
|
nsCOMPtr<nsIDOMNode> parent;
|
||||||
nsuiEvent->GetRangeParent(getter_AddRefs(parent));
|
nsuiEvent->GetRangeParent(getter_AddRefs(parent));
|
||||||
nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
|
nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
|
||||||
|
@ -628,43 +626,54 @@ nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX cache this between drag events?
|
nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
|
||||||
nsresult rv;
|
aEvent->GetDataTransfer(getter_AddRefs(dataTransfer));
|
||||||
nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
|
if (!dataTransfer)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
// does the drag have flavors we can accept?
|
nsCOMPtr<nsIDOMDOMStringList> types;
|
||||||
nsCOMPtr<nsIDragSession> dragSession;
|
dataTransfer->GetTypes(getter_AddRefs(types));
|
||||||
if (dragService)
|
if (!types)
|
||||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
return PR_FALSE;
|
||||||
if (!dragSession) return PR_FALSE;
|
|
||||||
|
|
||||||
PRBool flavorSupported = PR_FALSE;
|
// Plaintext editors only support dropping text. Otherwise, HTML and files
|
||||||
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
// can be dropped as well.
|
||||||
|
PRBool typeSupported;
|
||||||
if (!flavorSupported)
|
types->Contains(NS_LITERAL_STRING(kTextMime), &typeSupported);
|
||||||
dragSession->IsDataFlavorSupported(kMozTextInternal, &flavorSupported);
|
if (!typeSupported) {
|
||||||
|
types->Contains(NS_LITERAL_STRING(kMozTextInternal), &typeSupported);
|
||||||
// if we aren't plaintext editing, we can accept more flavors
|
if (!typeSupported && !editor->IsPlaintextEditor()) {
|
||||||
if (!flavorSupported && !editor->IsPlaintextEditor())
|
types->Contains(NS_LITERAL_STRING(kHTMLMime), &typeSupported);
|
||||||
{
|
if (!typeSupported) {
|
||||||
dragSession->IsDataFlavorSupported(kHTMLMime, &flavorSupported);
|
types->Contains(NS_LITERAL_STRING(kFileMime), &typeSupported);
|
||||||
if (!flavorSupported)
|
}
|
||||||
dragSession->IsDataFlavorSupported(kFileMime, &flavorSupported);
|
}
|
||||||
#if 0
|
|
||||||
if (!flavorSupported)
|
|
||||||
dragSession->IsDataFlavorSupported(kJPEGImageMime, &flavorSupported);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flavorSupported)
|
if (!typeSupported)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS(do_QueryInterface(dataTransfer));
|
||||||
|
if (!dataTransferNS)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// If there is no source node, this is probably an external drag and the
|
||||||
|
// drop is allowed. The later checks rely on checking if the drag target
|
||||||
|
// is the same as the drag source.
|
||||||
|
nsCOMPtr<nsIDOMNode> sourceNode;
|
||||||
|
dataTransferNS->GetMozSourceNode(getter_AddRefs(sourceNode));
|
||||||
|
if (!sourceNode)
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
// There is a source node, so compare the source documents and this document.
|
||||||
|
// Disallow drops on the same document.
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||||
rv = mEditor->GetDocument(getter_AddRefs(domdoc));
|
nsresult rv = mEditor->GetDocument(getter_AddRefs(domdoc));
|
||||||
if (NS_FAILED(rv)) return PR_FALSE;
|
if (NS_FAILED(rv)) return PR_FALSE;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> sourceDoc;
|
nsCOMPtr<nsIDOMDocument> sourceDoc;
|
||||||
rv = dragSession->GetSourceDocument(getter_AddRefs(sourceDoc));
|
rv = sourceNode->GetOwnerDocument(getter_AddRefs(sourceDoc));
|
||||||
if (NS_FAILED(rv)) return PR_FALSE;
|
if (NS_FAILED(rv)) return PR_FALSE;
|
||||||
if (domdoc == sourceDoc) // source and dest are the same document; disallow drops within the selection
|
if (domdoc == sourceDoc) // source and dest are the same document; disallow drops within the selection
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче