зеркало из 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);
|
||||
}
|
||||
|
||||
// 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
|
||||
// took care of it and cancelled the event, or the caller will handle it.
|
||||
// Return true to indicate that the event wasn't cancelled.
|
||||
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) {
|
||||
*aActionTaken = true;
|
||||
}
|
||||
|
|
|
@ -1772,6 +1772,12 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||
|
||||
RefPtr<DataTransfer> dataTransfer =
|
||||
new DataTransfer(window, eDragStart, false, -1);
|
||||
auto protectDataTransfer = MakeScopeExit([&] {
|
||||
if (dataTransfer) {
|
||||
dataTransfer->SetMode(DataTransfer::Mode::Protected);
|
||||
dataTransfer->ClearAll();
|
||||
}
|
||||
});
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsCOMPtr<nsIContent> eventContent, targetContent;
|
||||
|
@ -1839,11 +1845,6 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||
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) {
|
||||
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||
targetContent, selection);
|
||||
|
@ -2006,6 +2007,18 @@ EventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
|||
if (!transArray)
|
||||
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
|
||||
// here, but we need something to pass to the InvokeDragSession
|
||||
// methods.
|
||||
|
@ -2018,7 +2031,7 @@ EventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
|||
// other than a selection is being dragged.
|
||||
if (!dragImage && aSelection) {
|
||||
dragService->InvokeDragSessionWithSelection(aSelection, transArray,
|
||||
action, event, aDataTransfer);
|
||||
action, event, dataTransfer);
|
||||
}
|
||||
else {
|
||||
// if dragging within a XUL tree and no custom drag image was
|
||||
|
@ -2045,7 +2058,7 @@ EventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
|||
dragImage ? dragImage->AsDOMNode() :
|
||||
nullptr,
|
||||
imageX, imageY, event,
|
||||
aDataTransfer);
|
||||
dataTransfer);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -8242,6 +8242,23 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent,
|
|||
case eMouseMove:
|
||||
nsIPresShell::AllowMouseCapture(false);
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче