Skip to content

Commit

Permalink
Bug 936092, initial DnD support for e10s, r=enndeakin,karlt
Browse files Browse the repository at this point in the history
--HG--
extra : rebase_source : 070a9902f23d8b47e48ac0f972213815f8e4302c
  • Loading branch information
Olli Pettay authored and Olli Pettay committed Apr 8, 2015
1 parent 640f5a1 commit aad5b35
Show file tree
Hide file tree
Showing 36 changed files with 879 additions and 43 deletions.
17 changes: 16 additions & 1 deletion dom/base/nsContentAreaDragDrop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "nsServiceManagerUtils.h"
#include "nsNetUtil.h"
#include "nsIFile.h"
#include "nsFrameLoader.h"
#include "nsIWebNavigation.h"
#include "nsIDocShell.h"
#include "nsIContent.h"
Expand All @@ -52,6 +53,7 @@
#include "mozilla/dom/DataTransfer.h"
#include "nsIMIMEInfo.h"
#include "nsRange.h"
#include "TabParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLAreaElement.h"

Expand Down Expand Up @@ -414,8 +416,21 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
dsti && dsti->ItemType() == nsIDocShellTreeItem::typeChrome;

// In chrome shells, only allow dragging inside editable areas.
if (isChromeShell && !editingElement)
if (isChromeShell && !editingElement) {
nsCOMPtr<nsIFrameLoaderOwner> flo = do_QueryInterface(mTarget);
if (flo) {
nsRefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
if (fl) {
TabParent* tp = static_cast<TabParent*>(fl->GetRemoteBrowser());
if (tp) {
// We have a TabParent, so it may have data for dnd in case the child
// process started a dnd session.
tp->AddInitialDnDDataTo(aDataTransfer);
}
}
}
return NS_OK;
}

if (isChromeShell && textControl) {
// Only use the selection if the target node is in the selection.
Expand Down
94 changes: 94 additions & 0 deletions dom/base/nsContentUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLTemplateElement.h"
#include "mozilla/dom/HTMLContentElement.h"
#include "mozilla/dom/HTMLShadowElement.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/TabParent.h"
Expand Down Expand Up @@ -7197,3 +7200,94 @@ nsContentUtils::CallOnAllRemoteChildren(nsIDOMWindow* aWindow,
}
}

void
nsContentUtils::TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
nsTArray<IPCDataTransfer>& aIPC,
mozilla::dom::nsIContentChild* aChild,
mozilla::dom::nsIContentParent* aParent)
{
aIPC.Clear();
MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
if (aTransferables) {
uint32_t transferableCount = 0;
aTransferables->Count(&transferableCount);
for (uint32_t i = 0; i < transferableCount; ++i) {
IPCDataTransfer* dt = aIPC.AppendElement();
nsCOMPtr<nsISupports> genericItem;
aTransferables->GetElementAt(i, getter_AddRefs(genericItem));
nsCOMPtr<nsITransferable> item(do_QueryInterface(genericItem));
if (item) {
nsCOMPtr<nsISupportsArray> flavorList;
item->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
if (flavorList) {
uint32_t flavorCount = 0;
flavorList->Count(&flavorCount);
for (uint32_t j = 0; j < flavorCount; ++j) {
nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
if (!flavor) {
continue;
}

nsAutoCString flavorStr;
flavor->GetData(flavorStr);
if (!flavorStr.Length()) {
continue;
}

nsCOMPtr<nsISupports> data;
uint32_t dataLen = 0;
item->GetTransferData(flavorStr.get(), getter_AddRefs(data), &dataLen);

nsCOMPtr<nsISupportsString> text = do_QueryInterface(data);
if (text) {
nsAutoString dataAsString;
text->GetData(dataAsString);
IPCDataTransferItem* item = dt->items().AppendElement();
item->flavor() = nsCString(flavorStr);
item->data() = nsString(dataAsString);
} else {
nsCOMPtr<nsISupportsInterfacePointer> sip =
do_QueryInterface(data);
if (sip) {
sip->GetData(getter_AddRefs(data));
}
nsCOMPtr<FileImpl> fileImpl;
nsCOMPtr<nsIFile> file = do_QueryInterface(data);
if (file) {
fileImpl = new FileImplFile(file, false);
ErrorResult rv;
fileImpl->GetSize(rv);
fileImpl->GetLastModified(rv);
} else {
fileImpl = do_QueryInterface(data);
}
if (fileImpl) {
IPCDataTransferItem* item = dt->items().AppendElement();
item->flavor() = nsCString(flavorStr);
if (aChild) {
item->data() =
mozilla::dom::BlobChild::GetOrCreate(aChild,
static_cast<FileImpl*>(fileImpl.get()));
} else if (aParent) {
item->data() =
mozilla::dom::BlobParent::GetOrCreate(aParent,
static_cast<FileImpl*>(fileImpl.get()));
}
} else {
// This is a hack to support kFilePromiseMime.
// On Windows there just needs to be an entry for it,
// and for OSX we need to create
// nsContentAreaDragDropDataProvider as nsIFlavorDataProvider.
if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
IPCDataTransferItem* item = dt->items().AppendElement();
item->flavor() = nsCString(flavorStr);
item->data() = NS_ConvertUTF8toUTF16(flavorStr);
}
}
}
}
}
}
}
}
}
8 changes: 8 additions & 0 deletions dom/base/nsContentUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class nsIScriptGlobalObject;
class nsIScriptSecurityManager;
class nsIStringBundle;
class nsIStringBundleService;
class nsISupportsArray;
class nsISupportsHashKey;
class nsIURI;
class nsIWidget;
Expand Down Expand Up @@ -120,7 +121,10 @@ namespace dom {
class DocumentFragment;
class Element;
class EventTarget;
class IPCDataTransfer;
class NodeInfo;
class nsIContentChild;
class nsIContentParent;
class Selection;
class TabParent;
} // namespace dom
Expand Down Expand Up @@ -2287,6 +2291,10 @@ class nsContentUtils
CallOnRemoteChildFunction aCallback,
void* aArg);

static void TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
nsTArray<mozilla::dom::IPCDataTransfer>& aIPC,
mozilla::dom::nsIContentChild* aChild,
mozilla::dom::nsIContentParent* aParent);
private:
static bool InitializeEventTable();

Expand Down
55 changes: 40 additions & 15 deletions dom/events/DataTransfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "nsIScriptContext.h"
#include "nsIDocument.h"
#include "nsIScriptGlobalObject.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/DataTransferBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/BindingUtils.h"
Expand Down Expand Up @@ -82,7 +83,6 @@ DataTransfer::DataTransfer(nsISupports* aParent, uint32_t aEventType,
mDragImageX(0),
mDragImageY(0)
{
MOZ_ASSERT(mParent);
// For these events, we want to be able to add data to the data transfer, so
// clear the readonly state. Otherwise, the data is already present. For
// external usage, cache the data from the native clipboard or drag.
Expand Down Expand Up @@ -300,10 +300,16 @@ DataTransfer::GetFiles(ErrorResult& aRv)

nsCOMPtr<nsIFile> file = do_QueryInterface(supports);

if (!file)
continue;

nsRefPtr<File> domFile = File::CreateFromFile(GetParentObject(), file);
nsRefPtr<File> domFile;
if (file) {
domFile = File::CreateFromFile(GetParentObject(), file);
} else {
nsCOMPtr<FileImpl> fileImpl = do_QueryInterface(supports);
if (!fileImpl) {
continue;
}
domFile = new File(GetParentObject(), static_cast<FileImpl*>(fileImpl.get()));
}

if (!mFiles->Append(domFile)) {
aRv.Throw(NS_ERROR_FAILURE);
Expand Down Expand Up @@ -855,13 +861,6 @@ DataTransfer::GetTransferables(nsIDOMNode* aDragTarget)
{
MOZ_ASSERT(aDragTarget);

nsCOMPtr<nsISupportsArray> transArray =
do_CreateInstance("@mozilla.org/supports-array;1");
if (!transArray) {
return nullptr;
}


nsCOMPtr<nsINode> dragNode = do_QueryInterface(aDragTarget);
if (!dragNode) {
return nullptr;
Expand All @@ -871,12 +870,23 @@ DataTransfer::GetTransferables(nsIDOMNode* aDragTarget)
if (!doc) {
return nullptr;
}

nsILoadContext* loadContext = doc->GetLoadContext();

return GetTransferables(doc->GetLoadContext());
}

already_AddRefed<nsISupportsArray>
DataTransfer::GetTransferables(nsILoadContext* aLoadContext)
{

nsCOMPtr<nsISupportsArray> transArray =
do_CreateInstance("@mozilla.org/supports-array;1");
if (!transArray) {
return nullptr;
}

uint32_t count = mItems.Length();
for (uint32_t i = 0; i < count; i++) {
nsCOMPtr<nsITransferable> transferable = GetTransferable(i, loadContext);
nsCOMPtr<nsITransferable> transferable = GetTransferable(i, aLoadContext);
if (transferable) {
transArray->AppendElement(transferable);
}
Expand Down Expand Up @@ -1253,5 +1263,20 @@ DataTransfer::FillInExternalData(TransferItem& aItem, uint32_t aIndex)
aItem.mData = variant;
}

void
DataTransfer::FillAllExternalData()
{
if (mIsExternal) {
for (uint32_t i = 0; i < mItems.Length(); ++i) {
nsTArray<TransferItem>& itemArray = mItems[i];
for (uint32_t j = 0; j < itemArray.Length(); ++j) {
if (!itemArray[j].mData) {
FillInExternalData(itemArray[j], i);
}
}
}
}
}

} // namespace dom
} // namespace mozilla
4 changes: 4 additions & 0 deletions dom/events/DataTransfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class DataTransfer final : public nsIDOMDataTransfer,
// converts the data into an array of nsITransferable objects to be used for
// drag and drop or clipboard operations.
already_AddRefed<nsISupportsArray> GetTransferables(nsIDOMNode* aDragTarget);
already_AddRefed<nsISupportsArray> GetTransferables(nsILoadContext* aLoadContext);

// converts the data for a single item at aIndex into an nsITransferable object.
already_AddRefed<nsITransferable> GetTransferable(uint32_t aIndex,
Expand Down Expand Up @@ -239,6 +240,9 @@ class DataTransfer final : public nsIDOMDataTransfer,
// clipboard for a given index.
void FillInExternalData(TransferItem& aItem, uint32_t aIndex);

friend class ContentParent;
void FillAllExternalData();

void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
mozilla::ErrorResult& aRv);

Expand Down
Loading

0 comments on commit aad5b35

Please sign in to comment.