зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1809122 - Track top-level window context in DragSession; r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D169121
This commit is contained in:
Родитель
e39c51f7fd
Коммит
60b2a99aab
|
@ -248,15 +248,15 @@ ContentAreaDropListener.prototype = {
|
|||
}
|
||||
|
||||
// If this is an external drag, allow drop.
|
||||
let sourceWC = dataTransfer.sourceWindowContext;
|
||||
if (!sourceWC) {
|
||||
let sourceTopWC = dataTransfer.sourceTopWindowContext;
|
||||
if (!sourceTopWC) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If drag source and drop target are in the same top window, don't allow.
|
||||
let eventWC =
|
||||
aEvent.originalTarget.ownerGlobal.browsingContext.currentWindowContext;
|
||||
if (eventWC && sourceWC.topWindowContext == eventWC.topWindowContext) {
|
||||
if (eventWC && sourceTopWC == eventWC.topWindowContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -440,15 +440,16 @@ already_AddRefed<nsINode> DataTransfer::GetMozSourceNode() {
|
|||
return sourceNode.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WindowContext> DataTransfer::GetSourceWindowContext() {
|
||||
already_AddRefed<WindowContext> DataTransfer::GetSourceTopWindowContext() {
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
if (!dragSession) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<WindowContext> sourceWindowContext;
|
||||
dragSession->GetSourceWindowContext(getter_AddRefs(sourceWindowContext));
|
||||
return sourceWindowContext.forget();
|
||||
RefPtr<WindowContext> sourceTopWindowContext;
|
||||
dragSession->GetSourceTopWindowContext(
|
||||
getter_AddRefs(sourceTopWindowContext));
|
||||
return sourceTopWindowContext.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMStringList> DataTransfer::MozTypesAt(
|
||||
|
|
|
@ -255,7 +255,7 @@ class DataTransfer final : public nsISupports, public nsWrapperCache {
|
|||
|
||||
already_AddRefed<nsINode> GetMozSourceNode();
|
||||
|
||||
already_AddRefed<WindowContext> GetSourceWindowContext();
|
||||
already_AddRefed<WindowContext> GetSourceTopWindowContext();
|
||||
|
||||
/*
|
||||
* Integer version of dropEffect, set to one of the constants in
|
||||
|
|
|
@ -23,14 +23,15 @@ RemoteDragStartData::RemoteDragStartData(
|
|||
BrowserParent* aBrowserParent, nsTArray<IPCDataTransfer>&& aDataTransfer,
|
||||
const LayoutDeviceIntRect& aRect, nsIPrincipal* aPrincipal,
|
||||
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||
WindowContext* aSourceWindowContext)
|
||||
WindowContext* aSourceWindowContext, WindowContext* aSourceTopWindowContext)
|
||||
: mBrowserParent(aBrowserParent),
|
||||
mDataTransfer(std::move(aDataTransfer)),
|
||||
mRect(aRect),
|
||||
mPrincipal(aPrincipal),
|
||||
mCsp(aCsp),
|
||||
mCookieJarSettings(aCookieJarSettings),
|
||||
mSourceWindowContext(aSourceWindowContext) {}
|
||||
mSourceWindowContext(aSourceWindowContext),
|
||||
mSourceTopWindowContext(aSourceTopWindowContext) {}
|
||||
|
||||
void RemoteDragStartData::AddInitialDnDDataTo(
|
||||
DataTransfer* aDataTransfer, nsIPrincipal** aPrincipal,
|
||||
|
|
|
@ -31,7 +31,8 @@ class RemoteDragStartData {
|
|||
const LayoutDeviceIntRect& aRect,
|
||||
nsIPrincipal* aPrincipal, nsIContentSecurityPolicy* aCsp,
|
||||
nsICookieJarSettings* aCookieJarSettings,
|
||||
WindowContext* aSourceWindowContext);
|
||||
WindowContext* aSourceWindowContext,
|
||||
WindowContext* aSourceTopWindowContext);
|
||||
|
||||
void SetVisualization(
|
||||
already_AddRefed<gfx::DataSourceSurface> aVisualization) {
|
||||
|
@ -52,6 +53,7 @@ class RemoteDragStartData {
|
|||
nsICookieJarSettings** aCookieJarSettings);
|
||||
|
||||
WindowContext* GetSourceWindowContext() { return mSourceWindowContext; }
|
||||
WindowContext* GetSourceTopWindowContext() { return mSourceTopWindowContext; }
|
||||
|
||||
private:
|
||||
virtual ~RemoteDragStartData();
|
||||
|
@ -63,6 +65,7 @@ class RemoteDragStartData {
|
|||
nsCOMPtr<nsIContentSecurityPolicy> mCsp;
|
||||
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
|
||||
RefPtr<WindowContext> mSourceWindowContext;
|
||||
RefPtr<WindowContext> mSourceTopWindowContext;
|
||||
RefPtr<mozilla::gfx::SourceSurface> mVisualization;
|
||||
};
|
||||
|
||||
|
|
|
@ -3746,7 +3746,8 @@ mozilla::ipc::IPCResult BrowserParent::RecvInvokeDragSession(
|
|||
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
|
||||
nsIPrincipal* aPrincipal, nsIContentSecurityPolicy* aCsp,
|
||||
const CookieJarSettingsArgs& aCookieJarSettingsArgs,
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext) {
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
||||
const MaybeDiscarded<WindowContext>& aSourceTopWindowContext) {
|
||||
PresShell* presShell = mFrameElement->OwnerDoc()->GetPresShell();
|
||||
if (!presShell) {
|
||||
Unused << Manager()->SendEndDragSession(
|
||||
|
@ -3764,7 +3765,8 @@ mozilla::ipc::IPCResult BrowserParent::RecvInvokeDragSession(
|
|||
|
||||
RefPtr<RemoteDragStartData> dragStartData = new RemoteDragStartData(
|
||||
this, std::move(aTransfers), aDragRect, aPrincipal, aCsp,
|
||||
cookieJarSettings, aSourceWindowContext.GetMaybeDiscarded());
|
||||
cookieJarSettings, aSourceWindowContext.GetMaybeDiscarded(),
|
||||
aSourceTopWindowContext.GetMaybeDiscarded());
|
||||
|
||||
if (aVisualDnDData && aVisualDnDData->Size() >= aDragRect.height * aStride) {
|
||||
dragStartData->SetVisualization(gfx::CreateDataSourceSurfaceFromData(
|
||||
|
|
|
@ -674,7 +674,8 @@ class BrowserParent final : public PBrowserParent,
|
|||
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
|
||||
nsIPrincipal* aPrincipal, nsIContentSecurityPolicy* aCsp,
|
||||
const CookieJarSettingsArgs& aCookieJarSettingsArgs,
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext);
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
||||
const MaybeDiscarded<WindowContext>& aSourceTopWindowContext);
|
||||
|
||||
void AddInitialDnDDataTo(DataTransfer* aDataTransfer,
|
||||
nsIPrincipal** aPrincipal);
|
||||
|
|
|
@ -3184,6 +3184,7 @@ bool ContentChild::DeallocPWebBrowserPersistDocumentChild(
|
|||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvInvokeDragSession(
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
||||
const MaybeDiscarded<WindowContext>& aSourceTopWindowContext,
|
||||
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction) {
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
|
@ -3193,6 +3194,8 @@ mozilla::ipc::IPCResult ContentChild::RecvInvokeDragSession(
|
|||
dragService->GetCurrentSession(getter_AddRefs(session));
|
||||
if (session) {
|
||||
session->SetSourceWindowContext(aSourceWindowContext.GetMaybeDiscarded());
|
||||
session->SetSourceTopWindowContext(
|
||||
aSourceTopWindowContext.GetMaybeDiscarded());
|
||||
session->SetDragAction(aAction);
|
||||
// Check if we are receiving any file objects. If we are we will want
|
||||
// to hide any of the other objects coming in from content.
|
||||
|
|
|
@ -413,6 +413,7 @@ class ContentChild final : public PContentChild,
|
|||
|
||||
mozilla::ipc::IPCResult RecvInvokeDragSession(
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
||||
const MaybeDiscarded<WindowContext>& aSourceTopWindowContext,
|
||||
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
|
|
|
@ -5444,8 +5444,10 @@ void ContentParent::MaybeInvokeDragSession(BrowserParent* aParent) {
|
|||
|
||||
RefPtr<WindowContext> sourceWC;
|
||||
session->GetSourceWindowContext(getter_AddRefs(sourceWC));
|
||||
RefPtr<WindowContext> sourceTopWC;
|
||||
session->GetSourceTopWindowContext(getter_AddRefs(sourceTopWC));
|
||||
mozilla::Unused << SendInvokeDragSession(
|
||||
sourceWC, std::move(dataTransfers), action);
|
||||
sourceWC, sourceTopWC, std::move(dataTransfers), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -628,7 +628,8 @@ parent:
|
|||
LayoutDeviceIntRect dragRect,
|
||||
nsIPrincipal principal, nsIContentSecurityPolicy csp,
|
||||
CookieJarSettingsArgs cookieJarSettings,
|
||||
MaybeDiscardedWindowContext sourceWindowContext);
|
||||
MaybeDiscardedWindowContext sourceWindowContext,
|
||||
MaybeDiscardedWindowContext sourceTopWindowContext);
|
||||
|
||||
// After a compositor reset, it is necessary to reconnect each layers ID to
|
||||
// the compositor of the widget that will render those layers. Note that
|
||||
|
|
|
@ -815,7 +815,8 @@ child:
|
|||
*/
|
||||
async NotifyIdleObserver(uint64_t observerId, nsCString topic, nsString str);
|
||||
|
||||
async InvokeDragSession(MaybeDiscardedWindowContext aContext,
|
||||
async InvokeDragSession(MaybeDiscardedWindowContext aSourceWindowContext,
|
||||
MaybeDiscardedWindowContext aSourceTopWindowContext,
|
||||
IPCDataTransfer[] transfers, uint32_t action);
|
||||
|
||||
async EndDragSession(bool aDoneDrag, bool aUserCancelled,
|
||||
|
|
|
@ -152,11 +152,11 @@ partial interface DataTransfer {
|
|||
readonly attribute Node? mozSourceNode;
|
||||
|
||||
/**
|
||||
* The window context that mouse was pressed over to begin the drag. For
|
||||
* external drags, this will be null.
|
||||
* The top-level window context that mouse was pressed over to begin the drag.
|
||||
* For external drags, this will be null.
|
||||
*/
|
||||
[ChromeOnly]
|
||||
readonly attribute WindowContext? sourceWindowContext;
|
||||
readonly attribute WindowContext? sourceTopWindowContext;
|
||||
|
||||
/**
|
||||
* The URI spec of the triggering principal. This may be different than
|
||||
|
|
|
@ -150,6 +150,29 @@ nsBaseDragService::SetSourceWindowContext(WindowContext* aSourceWindowContext) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GetSourceTopWindowContext
|
||||
//
|
||||
// Returns the top-level window context where the drag was initiated. This will
|
||||
// be nullptr if the drag began outside of our application.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsBaseDragService::GetSourceTopWindowContext(
|
||||
WindowContext** aSourceTopWindowContext) {
|
||||
*aSourceTopWindowContext = mSourceTopWindowContext.get();
|
||||
NS_IF_ADDREF(*aSourceTopWindowContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseDragService::SetSourceTopWindowContext(
|
||||
WindowContext* aSourceTopWindowContext) {
|
||||
// This should only be called in a child process.
|
||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||
mSourceTopWindowContext = aSourceTopWindowContext;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GetSourceNode
|
||||
//
|
||||
|
@ -393,6 +416,8 @@ nsBaseDragService::InvokeDragSessionWithImage(
|
|||
mDragStartData = nullptr;
|
||||
mSourceWindowContext =
|
||||
aDOMNode ? aDOMNode->OwnerDoc()->GetWindowContext() : nullptr;
|
||||
mSourceTopWindowContext =
|
||||
mSourceWindowContext ? mSourceWindowContext->TopWindowContext() : nullptr;
|
||||
|
||||
mScreenPosition = aDragEvent->ScreenPoint(CallerType::System);
|
||||
mInputSource = aDragEvent->MozInputSource();
|
||||
|
@ -441,6 +466,7 @@ nsBaseDragService::InvokeDragSessionWithRemoteImage(
|
|||
mDragStartData = aDragStartData;
|
||||
mImageOffset = CSSIntPoint(0, 0);
|
||||
mSourceWindowContext = mDragStartData->GetSourceWindowContext();
|
||||
mSourceTopWindowContext = mDragStartData->GetSourceTopWindowContext();
|
||||
|
||||
mScreenPosition = aDragEvent->ScreenPoint(CallerType::System);
|
||||
mInputSource = aDragEvent->MozInputSource();
|
||||
|
@ -482,6 +508,8 @@ nsBaseDragService::InvokeDragSessionWithSelection(
|
|||
// endpoints of the selection
|
||||
nsCOMPtr<nsINode> node = aSelection->GetFocusNode();
|
||||
mSourceWindowContext = node ? node->OwnerDoc()->GetWindowContext() : nullptr;
|
||||
mSourceTopWindowContext =
|
||||
mSourceWindowContext ? mSourceWindowContext->TopWindowContext() : nullptr;
|
||||
|
||||
return InvokeDragSession(node, aPrincipal, aCsp, aCookieJarSettings,
|
||||
aTransferableArray, aActionType,
|
||||
|
|
|
@ -170,6 +170,7 @@ class nsBaseDragService : public nsIDragService, public nsIDragSession {
|
|||
RefPtr<mozilla::dom::Document> mSourceDocument;
|
||||
|
||||
RefPtr<mozilla::dom::WindowContext> mSourceWindowContext;
|
||||
RefPtr<mozilla::dom::WindowContext> mSourceTopWindowContext;
|
||||
|
||||
// the contentpolicy type passed to the channel when initiating the drag
|
||||
// session
|
||||
|
|
|
@ -46,7 +46,12 @@ nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
|||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
if (mSourceDocument) {
|
||||
csp = mSourceDocument->GetCsp();
|
||||
// XXX why do we need this here? Shouldn't they be set properly in
|
||||
// nsBaseDragService already?
|
||||
mSourceWindowContext = mSourceDocument->GetWindowContext();
|
||||
mSourceTopWindowContext = mSourceWindowContext
|
||||
? mSourceWindowContext->TopWindowContext()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
|
@ -75,7 +80,7 @@ nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
|||
mozilla::Unused << child->SendInvokeDragSession(
|
||||
std::move(dataTransfers), aActionType, std::move(surfaceData),
|
||||
stride, dataSurface->GetFormat(), dragRect, principal, csp, csArgs,
|
||||
mSourceWindowContext);
|
||||
mSourceWindowContext, mSourceTopWindowContext);
|
||||
StartDragSession();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -85,7 +90,7 @@ nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
|||
mozilla::Unused << child->SendInvokeDragSession(
|
||||
std::move(dataTransfers), aActionType, Nothing(), 0,
|
||||
static_cast<SurfaceFormat>(0), dragRect, principal, csp, csArgs,
|
||||
mSourceWindowContext);
|
||||
mSourceWindowContext, mSourceTopWindowContext);
|
||||
StartDragSession();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,14 @@ interface nsIDragSession : nsISupports
|
|||
[infallible]
|
||||
attribute WindowContext sourceWindowContext;
|
||||
|
||||
/**
|
||||
* The top-level window context where the drag was started, which will be
|
||||
* null if the drag originated outside the application. Useful for
|
||||
* determining if a drop originated in the same top-level window context.
|
||||
*/
|
||||
[infallible]
|
||||
attribute WindowContext sourceTopWindowContext;
|
||||
|
||||
/**
|
||||
* The dom node that was originally dragged to start the session, which will be null if the
|
||||
* drag originated outside the application.
|
||||
|
|
Загрузка…
Ссылка в новой задаче