Bug 1199729 - Part 3: Clear the DataTransfer after handling Drag and Clipboard events, r=baku

This commit is contained in:
Michael Layzell 2017-09-06 11:26:50 -04:00
Родитель f116f4037e
Коммит 18e36b497a
3 изменённых файлов: 47 добавлений и 14 удалений

Просмотреть файл

@ -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;
}