зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1199729 - Part 3: Clear the DataTransfer after handling Drag and Clipboard events, r=baku
This commit is contained in:
Родитель
f116f4037e
Коммит
18e36b497a
|
@ -840,17 +840,20 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
||||||
doDefault = (status != nsEventStatus_eConsumeNoDefault);
|
doDefault = (status != nsEventStatus_eConsumeNoDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When this function exits, the event dispatch is over. We want to disconnect
|
||||||
|
// our DataTransfer, which means setting its mode to `Protected` and clearing
|
||||||
|
// all stored data, before we return.
|
||||||
|
auto clearAfter = MakeScopeExit([&] {
|
||||||
|
if (clipboardData) {
|
||||||
|
clipboardData->SetMode(DataTransfer::Mode::Protected);
|
||||||
|
clipboardData->ClearAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// No need to do anything special during a paste. Either an event listener
|
// No need to do anything special during a paste. Either an event listener
|
||||||
// took care of it and cancelled the event, or the caller will handle it.
|
// took care of it and cancelled the event, or the caller will handle it.
|
||||||
// Return true to indicate that the event wasn't cancelled.
|
// Return true to indicate that the event wasn't cancelled.
|
||||||
if (originalEventMessage == ePaste) {
|
if (originalEventMessage == ePaste) {
|
||||||
// Clear and mark the clipboardData as readonly. This prevents someone
|
|
||||||
// from reading the clipboard contents after the paste event has fired.
|
|
||||||
if (clipboardData) {
|
|
||||||
clipboardData->ClearAll();
|
|
||||||
clipboardData->SetMode(DataTransfer::Mode::Protected);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aActionTaken) {
|
if (aActionTaken) {
|
||||||
*aActionTaken = true;
|
*aActionTaken = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1772,6 +1772,12 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||||
|
|
||||||
RefPtr<DataTransfer> dataTransfer =
|
RefPtr<DataTransfer> dataTransfer =
|
||||||
new DataTransfer(window, eDragStart, false, -1);
|
new DataTransfer(window, eDragStart, false, -1);
|
||||||
|
auto protectDataTransfer = MakeScopeExit([&] {
|
||||||
|
if (dataTransfer) {
|
||||||
|
dataTransfer->SetMode(DataTransfer::Mode::Protected);
|
||||||
|
dataTransfer->ClearAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsCOMPtr<nsISelection> selection;
|
||||||
nsCOMPtr<nsIContent> eventContent, targetContent;
|
nsCOMPtr<nsIContent> eventContent, targetContent;
|
||||||
|
@ -1839,11 +1845,6 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now that the dataTransfer has been updated in the dragstart and
|
|
||||||
// draggesture events, make it read only so that the data doesn't
|
|
||||||
// change during the drag.
|
|
||||||
dataTransfer->SetMode(DataTransfer::Mode::ReadOnly);
|
|
||||||
|
|
||||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||||
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||||
targetContent, selection);
|
targetContent, selection);
|
||||||
|
@ -2006,6 +2007,18 @@ EventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
if (!transArray)
|
if (!transArray)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// After this function returns, the DataTransfer will be cleared so it appears
|
||||||
|
// empty to content. We need to pass a DataTransfer into the Drag Session, so
|
||||||
|
// we need to make a copy.
|
||||||
|
RefPtr<DataTransfer> dataTransfer;
|
||||||
|
aDataTransfer->Clone(aDragTarget, eDrop, aDataTransfer->MozUserCancelled(),
|
||||||
|
false, getter_AddRefs(dataTransfer));
|
||||||
|
|
||||||
|
// Copy over the drop effect, as Clone doesn't copy it for us.
|
||||||
|
uint32_t dropEffect;
|
||||||
|
aDataTransfer->GetDropEffectInt(&dropEffect);
|
||||||
|
dataTransfer->SetDropEffectInt(dropEffect);
|
||||||
|
|
||||||
// XXXndeakin don't really want to create a new drag DOM event
|
// XXXndeakin don't really want to create a new drag DOM event
|
||||||
// here, but we need something to pass to the InvokeDragSession
|
// here, but we need something to pass to the InvokeDragSession
|
||||||
// methods.
|
// methods.
|
||||||
|
@ -2018,7 +2031,7 @@ EventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
// other than a selection is being dragged.
|
// other than a selection is being dragged.
|
||||||
if (!dragImage && aSelection) {
|
if (!dragImage && aSelection) {
|
||||||
dragService->InvokeDragSessionWithSelection(aSelection, transArray,
|
dragService->InvokeDragSessionWithSelection(aSelection, transArray,
|
||||||
action, event, aDataTransfer);
|
action, event, dataTransfer);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if dragging within a XUL tree and no custom drag image was
|
// if dragging within a XUL tree and no custom drag image was
|
||||||
|
@ -2045,7 +2058,7 @@ EventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||||
dragImage ? dragImage->AsDOMNode() :
|
dragImage ? dragImage->AsDOMNode() :
|
||||||
nullptr,
|
nullptr,
|
||||||
imageX, imageY, event,
|
imageX, imageY, event,
|
||||||
aDataTransfer);
|
dataTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -8242,6 +8242,23 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent,
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
nsIPresShell::AllowMouseCapture(false);
|
nsIPresShell::AllowMouseCapture(false);
|
||||||
break;
|
break;
|
||||||
|
case eDrag:
|
||||||
|
case eDragEnd:
|
||||||
|
case eDragEnter:
|
||||||
|
case eDragExit:
|
||||||
|
case eDragLeave:
|
||||||
|
case eDragOver:
|
||||||
|
case eDrop: {
|
||||||
|
// After any drag event other than dragstart (which is handled separately,
|
||||||
|
// as we need to collect the data first), the DataTransfer needs to be
|
||||||
|
// made protected, and then disconnected.
|
||||||
|
DataTransfer* dataTransfer = aEvent->AsDragEvent()->mDataTransfer;
|
||||||
|
if (dataTransfer) {
|
||||||
|
dataTransfer->SetMode(DataTransfer::Mode::Protected);
|
||||||
|
dataTransfer->ClearAll();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче