Bug 923054 part 2 - Convert DataTransfer to WebIDL bindings, add WebIDL API and switch to the WebIDL binding. r=smaug

This commit is contained in:
Peter Van der Beken 2014-02-26 22:23:31 -05:00
parent 5aeb243ad3
commit 6f93fad4e2
24 changed files with 683 additions and 243 deletions

View File

@ -492,24 +492,8 @@ function sendDragEvent(aEventType, aTarget, aData) {
* @return The drag event.
*/
function createDragEvent(aEventType, aData) {
let dataTransfer = {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () aData,
types: {
contains: function (aType) aType == "text/x-moz-url"
},
mozGetDataAt: function (aType, aIndex) {
if (aIndex || aType != "text/x-moz-url")
return null;
return aData;
}
};
let dataTransfer = new getContentWindow().DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", aData, 0);
let event = getContentDocument().createEvent("DragEvents");
event.initDragEvent(aEventType, true, true, getContentWindow(), 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);

View File

@ -4974,16 +4974,20 @@ nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent)
nsCOMPtr<nsIDragSession> dragSession = GetDragSession();
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
if (!initialDataTransfer) {
nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
nsCOMPtr<DataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
if (dataTransfer) {
initialDataTransfer = do_QueryInterface(dataTransfer);
if (!initialDataTransfer) {
return NS_ERROR_FAILURE;
}
} else {
// A dataTransfer won't exist when a drag was started by some other
// means, for instance calling the drag service directly, or a drag
// from another application. In either case, a new dataTransfer should
// be created that reflects the data.
initialDataTransfer = new DataTransfer(aDragEvent->message, true, -1);
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
initialDataTransfer = new DataTransfer(aDragEvent->target, aDragEvent->message, true, -1);
// now set it in the drag session so we don't need to create it again
dragSession->SetDataTransfer(initialDataTransfer);
@ -4996,7 +5000,7 @@ nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent)
}
// each event should use a clone of the original dataTransfer.
initialDataTransfer->Clone(aDragEvent->message, aDragEvent->userCancelled,
initialDataTransfer->Clone(aDragEvent->target, aDragEvent->message, aDragEvent->userCancelled,
isCrossDomainSubFrameDrop,
getter_AddRefs(aDragEvent->dataTransfer));
NS_ENSURE_TRUE(aDragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);

View File

@ -646,7 +646,8 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
bool doDefault = true;
nsRefPtr<DataTransfer> clipboardData;
if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
clipboardData = new DataTransfer(aType, aType == NS_PASTE, aClipboardType);
clipboardData =
new DataTransfer(piWindow, aType, aType == NS_PASTE, aClipboardType);
nsEventStatus status = nsEventStatus_eIgnore;
InternalClipboardEvent evt(true, aType);

View File

@ -131,8 +131,6 @@
#include "nsPIDOMStorage.h"
// Drag and drop
#include "nsIDOMDataTransfer.h"
#include "nsIDOMFile.h"
#include "nsDOMBlobBuilder.h" // nsDOMMultipartFile
@ -441,10 +439,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
// data transfer for drag and drop
NS_DEFINE_CLASSINFO_DATA(DataTransfer, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(EventListenerInfo, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager, nsEventTargetSH,
@ -1123,10 +1117,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(DataTransfer, nsIDOMDataTransfer)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataTransfer)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(EventListenerInfo, nsIEventListenerInfo)
DOM_CLASSINFO_MAP_ENTRY(nsIEventListenerInfo)
DOM_CLASSINFO_MAP_END

View File

@ -86,8 +86,6 @@ DOMCI_CLASS(MozMobileConnection)
// @font-face in CSS
DOMCI_CLASS(CSSFontFaceRule)
DOMCI_CLASS(DataTransfer)
DOMCI_CLASS(EventListenerInfo)
DOMCI_CLASS(ContentFrameMessageManager)

View File

@ -1969,4 +1969,3 @@ addExternalIface('XPathResult', nativeType='nsISupports')
addExternalIface('XPathExpression')
addExternalIface('XPathNSResolver')
addExternalIface('XULCommandDispatcher')
addExternalIface('DataTransfer', notflattened=True)

View File

@ -38,12 +38,27 @@ ClipboardEvent::InitClipboardEvent(const nsAString& aType,
bool aCancelable,
nsIDOMDataTransfer* aClipboardData)
{
nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<DataTransfer> clipboardData = do_QueryInterface(aClipboardData);
// Null clipboardData is OK
ErrorResult rv;
InitClipboardEvent(aType, aCanBubble, aCancelable, clipboardData, rv);
return rv.ErrorCode();
}
void
ClipboardEvent::InitClipboardEvent(const nsAString& aType, bool aCanBubble,
bool aCancelable,
DataTransfer* aClipboardData,
ErrorResult& aError)
{
aError = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
if (aError.Failed()) {
return;
}
mEvent->AsClipboardEvent()->clipboardData = aClipboardData;
return NS_OK;
}
already_AddRefed<ClipboardEvent>
@ -63,13 +78,13 @@ ClipboardEvent::Constructor(const GlobalObject& aGlobal,
// Always create a clipboardData for the copy event. If this is changed to
// support other types of events, make sure that read/write privileges are
// checked properly within DataTransfer.
clipboardData = new DataTransfer(NS_COPY, false, -1);
clipboardData = new DataTransfer(ToSupports(e), NS_COPY, false, -1);
clipboardData->SetData(aParam.mDataType, aParam.mData);
}
}
aRv = e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable,
clipboardData);
e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable,
clipboardData, aRv);
e->SetTrusted(trusted);
return e.forget();
}
@ -81,17 +96,20 @@ ClipboardEvent::GetClipboardData(nsIDOMDataTransfer** aClipboardData)
return NS_OK;
}
nsIDOMDataTransfer*
DataTransfer*
ClipboardEvent::GetClipboardData()
{
InternalClipboardEvent* event = mEvent->AsClipboardEvent();
if (!event->clipboardData) {
if (mEventIsInternal) {
event->clipboardData = new DataTransfer(NS_COPY, false, -1);
event->clipboardData =
new DataTransfer(ToSupports(this), NS_COPY, false, -1);
} else {
event->clipboardData =
new DataTransfer(event->message, event->message == NS_PASTE, nsIClipboard::kGlobalClipboard);
new DataTransfer(ToSupports(this), event->message,
event->message == NS_PASTE,
nsIClipboard::kGlobalClipboard);
}
}

View File

@ -13,6 +13,7 @@
namespace mozilla {
namespace dom {
class DataTransfer;
class ClipboardEvent : public nsDOMEvent,
public nsIDOMClipboardEvent
@ -41,7 +42,12 @@ public:
const ClipboardEventInit& aParam,
ErrorResult& aRv);
nsIDOMDataTransfer* GetClipboardData();
DataTransfer* GetClipboardData();
void InitClipboardEvent(const nsAString& aType, bool aCanBubble,
bool aCancelable,
DataTransfer* aClipboardData,
ErrorResult& aError);
};
} // namespace dom

View File

@ -12,7 +12,6 @@
#include "nsIDOMDocument.h"
#include "nsIVariant.h"
#include "nsISupportsPrimitives.h"
#include "nsDOMClassInfoID.h"
#include "nsIScriptSecurityManager.h"
#include "nsDOMLists.h"
#include "nsError.h"
@ -25,8 +24,9 @@
#include "nsIScriptContext.h"
#include "nsIDocument.h"
#include "nsIScriptGlobalObject.h"
DOMCI_DATA(DataTransfer, mozilla::dom::DataTransfer)
#include "mozilla/dom/DataTransferBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/BindingUtils.h"
namespace mozilla {
namespace dom {
@ -34,26 +34,31 @@ namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(DataTransfer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DataTransfer)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
if (tmp->mFiles) {
tmp->mFiles->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFiles)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDragTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDragImage)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DataTransfer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFiles)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDragTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDragImage)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(DataTransfer)
NS_IMPL_CYCLE_COLLECTING_ADDREF(DataTransfer)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DataTransfer)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DataTransfer)
NS_INTERFACE_MAP_ENTRY(mozilla::dom::DataTransfer)
NS_INTERFACE_MAP_ENTRY(nsIDOMDataTransfer)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDataTransfer)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DataTransfer)
NS_INTERFACE_MAP_END
// the size of the array
@ -61,8 +66,10 @@ const char DataTransfer::sEffects[8][9] = {
"none", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"
};
DataTransfer::DataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipboardType)
: mEventType(aEventType),
DataTransfer::DataTransfer(nsISupports* aParent, uint32_t aEventType,
bool aIsExternal, int32_t aClipboardType)
: mParent(aParent),
mEventType(aEventType),
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
mEffectAllowed(nsIDragService::DRAGDROP_ACTION_UNINITIALIZED),
mCursorState(false),
@ -74,6 +81,8 @@ DataTransfer::DataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipb
mDragImageX(0),
mDragImageY(0)
{
MOZ_ASSERT(mParent);
SetIsDOMBinding();
// 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.
@ -82,7 +91,7 @@ DataTransfer::DataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipb
aEventType == NS_DRAGDROP_START ||
aEventType == NS_DRAGDROP_GESTURE) {
mReadOnly = false;
} else if (mIsExternal) {
} else if (mIsExternal) {
if (aEventType == NS_PASTE) {
CacheExternalClipboardFormats();
} else if (aEventType >= NS_DRAGDROP_EVENT_START && aEventType <= NS_DRAGDROP_LEAVE_SYNTH) {
@ -91,7 +100,8 @@ DataTransfer::DataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipb
}
}
DataTransfer::DataTransfer(uint32_t aEventType,
DataTransfer::DataTransfer(nsISupports* aParent,
uint32_t aEventType,
const uint32_t aEffectAllowed,
bool aCursorState,
bool aIsExternal,
@ -99,10 +109,11 @@ DataTransfer::DataTransfer(uint32_t aEventType,
bool aIsCrossDomainSubFrameDrop,
int32_t aClipboardType,
nsTArray<nsTArray<TransferItem> >& aItems,
nsIDOMElement* aDragImage,
Element* aDragImage,
uint32_t aDragImageX,
uint32_t aDragImageY)
: mEventType(aEventType),
: mParent(aParent),
mEventType(aEventType),
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
mEffectAllowed(aEffectAllowed),
mCursorState(aCursorState),
@ -116,6 +127,8 @@ DataTransfer::DataTransfer(uint32_t aEventType,
mDragImageX(aDragImageX),
mDragImageY(aDragImageY)
{
MOZ_ASSERT(mParent);
SetIsDOMBinding();
// The items are copied from aItems into mItems. There is no need to copy
// the actual data in the items as the data transfer will be read only. The
// draggesture and dragstart events are the only times when items are
@ -126,10 +139,46 @@ DataTransfer::DataTransfer(uint32_t aEventType,
"invalid event type for DataTransfer constructor");
}
DataTransfer::~DataTransfer()
{
if (mFiles) {
mFiles->Disconnect();
}
}
// static
already_AddRefed<DataTransfer>
DataTransfer::Constructor(const GlobalObject& aGlobal,
const nsAString& aEventType, bool aIsExternal,
ErrorResult& aRv)
{
nsAutoCString onEventType("on");
AppendUTF16toUTF8(aEventType, onEventType);
nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(onEventType);
if (!eventTypeAtom) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
uint32_t eventType = nsContentUtils::GetEventId(eventTypeAtom);
nsRefPtr<DataTransfer> transfer = new DataTransfer(aGlobal.GetAsSupports(),
eventType, aIsExternal,
-1);
return transfer.forget();
}
JSObject*
DataTransfer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return DataTransferBinding::Wrap(aCx, aScope, this);
}
NS_IMETHODIMP
DataTransfer::GetDropEffect(nsAString& aDropEffect)
{
aDropEffect.AssignASCII(sEffects[mDropEffect]);
nsString dropEffect;
GetDropEffect(dropEffect);
aDropEffect = dropEffect;
return NS_OK;
}
@ -153,10 +202,9 @@ DataTransfer::SetDropEffect(const nsAString& aDropEffect)
NS_IMETHODIMP
DataTransfer::GetEffectAllowed(nsAString& aEffectAllowed)
{
if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
aEffectAllowed.AssignLiteral("uninitialized");
else
aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
nsString effectAllowed;
GetEffectAllowed(effectAllowed);
aEffectAllowed = effectAllowed;
return NS_OK;
}
@ -218,18 +266,16 @@ DataTransfer::SetEffectAllowedInt(uint32_t aEffectAllowed)
NS_IMETHODIMP
DataTransfer::GetMozUserCancelled(bool* aUserCancelled)
{
*aUserCancelled = mUserCancelled;
*aUserCancelled = MozUserCancelled();
return NS_OK;
}
NS_IMETHODIMP
DataTransfer::GetFiles(nsIDOMFileList** aFileList)
nsDOMFileList*
DataTransfer::GetFiles(ErrorResult& aRv)
{
*aFileList = nullptr;
if (mEventType != NS_DRAGDROP_DROP && mEventType != NS_DRAGDROP_DRAGDROP &&
mEventType != NS_PASTE) {
return NS_OK;
return nullptr;
}
if (!mFiles) {
@ -239,14 +285,16 @@ DataTransfer::GetFiles(nsIDOMFileList** aFileList)
for (uint32_t i = 0; i < count; i++) {
nsCOMPtr<nsIVariant> variant;
nsresult rv = MozGetDataAt(NS_ConvertUTF8toUTF16(kFileMime), i, getter_AddRefs(variant));
NS_ENSURE_SUCCESS(rv, rv);
aRv = MozGetDataAt(NS_ConvertUTF8toUTF16(kFileMime), i, getter_AddRefs(variant));
if (aRv.Failed()) {
return nullptr;
}
if (!variant)
continue;
nsCOMPtr<nsISupports> supports;
rv = variant->GetAsISupports(getter_AddRefs(supports));
nsresult rv = variant->GetAsISupports(getter_AddRefs(supports));
if (NS_FAILED(rv))
continue;
@ -258,23 +306,28 @@ DataTransfer::GetFiles(nsIDOMFileList** aFileList)
nsRefPtr<nsDOMFileFile> domFile = new nsDOMFileFile(file);
if (!mFiles->Append(domFile))
return NS_ERROR_FAILURE;
if (!mFiles->Append(domFile)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
}
}
*aFileList = mFiles;
NS_ADDREF(*aFileList);
return NS_OK;
return mFiles;
}
NS_IMETHODIMP
DataTransfer::GetTypes(nsIDOMDOMStringList** aTypes)
DataTransfer::GetFiles(nsIDOMFileList** aFileList)
{
*aTypes = nullptr;
ErrorResult rv;
*aFileList = GetFiles(rv);
return rv.ErrorCode();
}
already_AddRefed<nsIDOMDOMStringList>
DataTransfer::Types()
{
nsRefPtr<nsDOMStringList> types = new nsDOMStringList();
if (mItems.Length()) {
const nsTArray<TransferItem>& item = mItems[0];
for (uint32_t i = 0; i < item.Length(); i++)
@ -287,26 +340,33 @@ DataTransfer::GetTypes(nsIDOMDOMStringList** aTypes)
types->Add(NS_LITERAL_STRING("Files"));
}
*aTypes = types;
NS_ADDREF(*aTypes);
return types.forget();
}
NS_IMETHODIMP
DataTransfer::GetTypes(nsIDOMDOMStringList** aTypes)
{
*aTypes = Types().get();
return NS_OK;
}
NS_IMETHODIMP
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
void
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData,
ErrorResult& aRv)
{
// return an empty string if data for the format was not found
aData.Truncate();
nsCOMPtr<nsIVariant> data;
nsresult rv = MozGetDataAt(aFormat, 0, getter_AddRefs(data));
if (rv == NS_ERROR_DOM_INDEX_SIZE_ERR) {
return NS_OK;
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_DOM_INDEX_SIZE_ERR) {
aRv.Throw(rv);
}
return;
}
NS_ENSURE_SUCCESS(rv, rv);
if (data) {
nsAutoString stringdata;
data->GetAsAString(stringdata);
@ -314,9 +374,9 @@ DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
// for the URL type, parse out the first URI from the list. The URIs are
// separated by newlines
nsAutoString lowercaseFormat;
rv = nsContentUtils::ASCIIToLower(aFormat, lowercaseFormat);
if (NS_FAILED(rv)) {
return rv;
aRv = nsContentUtils::ASCIIToLower(aFormat, lowercaseFormat);
if (aRv.Failed()) {
return;
}
if (lowercaseFormat.EqualsLiteral("url")) {
@ -335,7 +395,7 @@ DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
else
aData.Assign(Substring(stringdata, lastidx, idx - lastidx));
aData = nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(aData, true);
return NS_OK;
return;
}
lastidx = idx + 1;
}
@ -344,43 +404,81 @@ DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
aData = stringdata;
}
}
}
return NS_OK;
NS_IMETHODIMP
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
{
ErrorResult rv;
GetData(aFormat, aData, rv);
return rv.ErrorCode();
}
void
DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData,
ErrorResult& aRv)
{
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID);
if (!variant) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
variant->SetAsAString(aData);
aRv = MozSetDataAt(aFormat, variant, 0);
}
NS_IMETHODIMP
DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData)
{
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID);
NS_ENSURE_TRUE(variant, NS_ERROR_OUT_OF_MEMORY);
ErrorResult rv;
SetData(aFormat, aData, rv);
return rv.ErrorCode();
}
variant->SetAsAString(aData);
void
DataTransfer::ClearData(const Optional<nsAString>& aFormat, ErrorResult& aRv)
{
if (mReadOnly) {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
}
return MozSetDataAt(aFormat, variant, 0);
if (mItems.Length() == 0) {
return;
}
if (aFormat.WasPassed()) {
MozClearDataAtHelper(aFormat.Value(), 0, aRv);
} else {
MozClearDataAtHelper(EmptyString(), 0, aRv);
}
}
NS_IMETHODIMP
DataTransfer::ClearData(const nsAString& aFormat)
{
nsresult rv = MozClearDataAt(aFormat, 0);
return (rv == NS_ERROR_DOM_INDEX_SIZE_ERR) ? NS_OK : rv;
Optional<nsAString> format;
format = &aFormat;
ErrorResult rv;
ClearData(format, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
DataTransfer::GetMozItemCount(uint32_t* aCount)
{
*aCount = mItems.Length();
*aCount = MozItemCount();
return NS_OK;
}
NS_IMETHODIMP
DataTransfer::GetMozCursor(nsAString& aCursorState)
{
if (mCursorState) {
aCursorState.AssignLiteral("default");
} else {
aCursorState.AssignLiteral("auto");
}
nsString cursor;
GetMozCursor(cursor);
aCursorState = cursor;
return NS_OK;
}
@ -393,37 +491,47 @@ DataTransfer::SetMozCursor(const nsAString& aCursorState)
return NS_OK;
}
NS_IMETHODIMP
DataTransfer::GetMozSourceNode(nsIDOMNode** aSourceNode)
already_AddRefed<nsINode>
DataTransfer::GetMozSourceNode()
{
*aSourceNode = nullptr;
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
if (!dragSession)
return NS_OK;
if (!dragSession) {
return nullptr;
}
nsCOMPtr<nsIDOMNode> sourceNode;
dragSession->GetSourceNode(getter_AddRefs(sourceNode));
if (sourceNode && !nsContentUtils::CanCallerAccess(sourceNode))
return NS_OK;
nsCOMPtr<nsINode> node = do_QueryInterface(sourceNode);
if (node && !nsContentUtils::CanCallerAccess(node)) {
return nullptr;
}
sourceNode.swap(*aSourceNode);
return NS_OK;
return node.forget();
}
NS_IMETHODIMP
DataTransfer::MozTypesAt(uint32_t aIndex, nsIDOMDOMStringList** aTypes)
DataTransfer::GetMozSourceNode(nsIDOMNode** aSourceNode)
{
*aTypes = nullptr;
nsCOMPtr<nsINode> sourceNode = GetMozSourceNode();
if (!sourceNode) {
*aSourceNode = nullptr;
return NS_OK;
}
return CallQueryInterface(sourceNode, aSourceNode);
}
already_AddRefed<nsIDOMDOMStringList>
DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv)
{
// Only the first item is valid for clipboard events
if (aIndex > 0 &&
(mEventType == NS_CUT || mEventType == NS_COPY || mEventType == NS_PASTE)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
nsRefPtr<nsDOMStringList> types = new nsDOMStringList();
if (aIndex < mItems.Length()) {
// note that you can retrieve the types regardless of their principal
nsTArray<TransferItem>& item = mItems[aIndex];
@ -431,10 +539,15 @@ DataTransfer::MozTypesAt(uint32_t aIndex, nsIDOMDOMStringList** aTypes)
types->Add(item[i].mFormat);
}
*aTypes = types;
NS_ADDREF(*aTypes);
return types.forget();
}
return NS_OK;
NS_IMETHODIMP
DataTransfer::MozTypesAt(uint32_t aIndex, nsIDOMDOMStringList** aTypes)
{
ErrorResult rv;
*aTypes = MozTypesAt(aIndex, rv).get();
return rv.ErrorCode();
}
NS_IMETHODIMP
@ -521,17 +634,41 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
return NS_OK;
}
JS::Value
DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, mozilla::ErrorResult& aRv)
{
nsCOMPtr<nsIVariant> data;
aRv = MozGetDataAt(aFormat, aIndex, getter_AddRefs(data));
if (aRv.Failed()) {
return JS::UndefinedValue();
}
if (!data) {
return JS::NullValue();
}
JS::Rooted<JS::Value> result(aCx);
JS::Rooted<JSObject*> scope(aCx, GetWrapper());
if (!VariantToJsval(aCx, scope, data, &result)) {
aRv = NS_ERROR_FAILURE;
return JS::UndefinedValue();
}
return result;
}
NS_IMETHODIMP
DataTransfer::MozSetDataAt(const nsAString& aFormat, nsIVariant* aData,
uint32_t aIndex)
{
NS_ENSURE_TRUE(aData, NS_ERROR_NULL_POINTER);
if (aFormat.IsEmpty())
if (aFormat.IsEmpty()) {
return NS_OK;
}
if (mReadOnly)
if (mReadOnly) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
// Specifying an index less than the current length will replace an existing
// item. Specifying an index equal to the current length will add a new item.
@ -556,31 +693,66 @@ DataTransfer::MozSetDataAt(const nsAString& aFormat, nsIVariant* aData,
nsresult rv = NS_OK;
nsIPrincipal* principal = GetCurrentPrincipal(&rv);
NS_ENSURE_SUCCESS(rv, rv);
return SetDataWithPrincipal(aFormat, aData, aIndex, principal);
}
NS_IMETHODIMP
DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex)
void
DataTransfer::MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
JS::Handle<JS::Value> aData,
uint32_t aIndex, ErrorResult& aRv)
{
if (mReadOnly)
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
nsCOMPtr<nsIVariant> data;
aRv = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData,
getter_AddRefs(data));
if (!aRv.Failed()) {
aRv = MozSetDataAt(aFormat, data, aIndex);
}
}
void
DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
ErrorResult& aRv)
{
if (mReadOnly) {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
}
if (aIndex >= mItems.Length()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
// Only the first item is valid for clipboard events
if (aIndex > 0 &&
(mEventType == NS_CUT || mEventType == NS_COPY || mEventType == NS_PASTE)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
MozClearDataAtHelper(aFormat, aIndex, aRv);
}
void
DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
ErrorResult& aRv)
{
MOZ_ASSERT(!mReadOnly);
MOZ_ASSERT(aIndex < mItems.Length());
MOZ_ASSERT(aIndex == 0 ||
(mEventType != NS_CUT && mEventType != NS_COPY &&
mEventType != NS_PASTE));
nsAutoString format;
GetRealFormat(aFormat, format);
nsresult rv = NS_OK;
nsIPrincipal* principal = GetCurrentPrincipal(&rv);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
aRv = rv;
return;
}
// if the format is empty, clear all formats
bool clearall = format.IsEmpty();
@ -594,8 +766,10 @@ DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex)
// don't allow removing data that has a stronger principal
bool subsumes;
if (formatitem.mPrincipal && principal &&
(NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes))
return NS_ERROR_DOM_SECURITY_ERR;
(NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
item.RemoveElementAt(i);
@ -609,24 +783,50 @@ DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex)
// if the last format for an item is removed, remove the entire item
if (!item.Length())
mItems.RemoveElementAt(aIndex);
}
return NS_OK;
NS_IMETHODIMP
DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex)
{
ErrorResult rv;
MozClearDataAt(aFormat, aIndex, rv);
return rv.ErrorCode();
}
void
DataTransfer::SetDragImage(Element& aImage, int32_t aX, int32_t aY,
ErrorResult& aRv)
{
if (mReadOnly) {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
}
mDragImage = &aImage;
mDragImageX = aX;
mDragImageY = aY;
}
NS_IMETHODIMP
DataTransfer::SetDragImage(nsIDOMElement* aImage, int32_t aX, int32_t aY)
{
if (mReadOnly)
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
if (aImage) {
nsCOMPtr<nsIContent> content = do_QueryInterface(aImage);
NS_ENSURE_TRUE(content, NS_ERROR_INVALID_ARG);
ErrorResult rv;
nsCOMPtr<Element> image = do_QueryInterface(aImage);
if (image) {
SetDragImage(*image, aX, aY, rv);
}
mDragImage = aImage;
mDragImageX = aX;
mDragImageY = aY;
return NS_OK;
return rv.ErrorCode();
}
void
DataTransfer::AddElement(Element& aElement, ErrorResult& aRv)
{
if (mReadOnly) {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
}
mDragTarget = &aElement;
}
NS_IMETHODIMP
@ -634,28 +834,24 @@ DataTransfer::AddElement(nsIDOMElement* aElement)
{
NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER);
if (aElement) {
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
NS_ENSURE_TRUE(content, NS_ERROR_INVALID_ARG);
}
nsCOMPtr<Element> element = do_QueryInterface(aElement);
NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG);
if (mReadOnly)
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
mDragTarget = do_QueryInterface(aElement);
return NS_OK;
ErrorResult rv;
AddElement(*element, rv);
return rv.ErrorCode();
}
nsresult
DataTransfer::Clone(uint32_t aEventType, bool aUserCancelled,
bool aIsCrossDomainSubFrameDrop,
nsIDOMDataTransfer** aNewDataTransfer)
DataTransfer::Clone(nsISupports* aParent, uint32_t aEventType,
bool aUserCancelled, bool aIsCrossDomainSubFrameDrop,
DataTransfer** aNewDataTransfer)
{
DataTransfer* newDataTransfer =
new DataTransfer(aEventType, mEffectAllowed, mCursorState, mIsExternal,
aUserCancelled, aIsCrossDomainSubFrameDrop, mClipboardType,
mItems, mDragImage, mDragImageX, mDragImageY);
new DataTransfer(aParent, aEventType, mEffectAllowed, mCursorState,
mIsExternal, aUserCancelled, aIsCrossDomainSubFrameDrop,
mClipboardType, mItems, mDragImage, mDragImageX,
mDragImageY);
*aNewDataTransfer = newDataTransfer;
NS_ADDREF(*aNewDataTransfer);

View File

@ -12,6 +12,7 @@
#include "nsIPrincipal.h"
#include "nsIDOMDataTransfer.h"
#include "nsIDOMElement.h"
#include "nsIDragService.h"
#include "nsCycleCollectionParticipant.h"
#include "nsAutoPtr.h"
@ -19,6 +20,7 @@
#include "mozilla/Attributes.h"
class nsEventStateManager;
class nsINode;
class nsITransferable;
class nsISupportsArray;
class nsILoadContext;
@ -26,6 +28,9 @@ class nsILoadContext;
namespace mozilla {
namespace dom {
class Element;
template<typename T> class Optional;
/**
* TransferItem is used to hold data for a particular format. Each piece of
* data has a principal set from the caller which added it. This allows a
@ -39,13 +44,20 @@ struct TransferItem {
nsCOMPtr<nsIVariant> mData;
};
class DataTransfer MOZ_FINAL : public nsIDOMDataTransfer
#define NS_DATATRANSFER_IID \
{ 0x43ee0327, 0xde5d, 0x463d, \
{ 0x9b, 0xd0, 0xf1, 0x79, 0x09, 0x69, 0xf2, 0xfb } }
class DataTransfer MOZ_FINAL : public nsIDOMDataTransfer,
public nsWrapperCache
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DATATRANSFER_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIDOMDATATRANSFER
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DataTransfer, nsIDOMDataTransfer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer)
friend class ::nsEventStateManager;
@ -56,7 +68,8 @@ protected:
// this constructor is used only by the Clone method to copy the fields as
// needed to a new data transfer.
DataTransfer(uint32_t aEventType,
DataTransfer(nsISupports* aParent,
uint32_t aEventType,
const uint32_t aEffectAllowed,
bool aCursorState,
bool aIsExternal,
@ -64,16 +77,11 @@ protected:
bool aIsCrossDomainSubFrameDrop,
int32_t aClipboardType,
nsTArray<nsTArray<TransferItem> >& aItems,
nsIDOMElement* aDragImage,
Element* aDragImage,
uint32_t aDragImageX,
uint32_t aDragImageY);
~DataTransfer()
{
if (mFiles) {
mFiles->Disconnect();
}
}
~DataTransfer();
static const char sEffects[8][9];
@ -90,12 +98,80 @@ public:
// service directly. For clipboard operations, aClipboardType indicates
// which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations,
// or if access to the system clipboard should not be allowed.
DataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipboardType);
DataTransfer(nsISupports* aParent, uint32_t aEventType, bool aIsExternal,
int32_t aClipboardType);
void GetDragTarget(nsIDOMElement** aDragTarget)
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope);
nsISupports* GetParentObject()
{
*aDragTarget = mDragTarget;
NS_IF_ADDREF(*aDragTarget);
return mParent;
}
void SetParentObject(nsISupports* aNewParent)
{
MOZ_ASSERT(aNewParent);
// Setting the parent after we've been wrapped is pointless, so
// make sure we aren't wrapped yet.
MOZ_ASSERT(!GetWrapperPreserveColor());
mParent = aNewParent;
}
static already_AddRefed<DataTransfer>
Constructor(const GlobalObject& aGlobal, const nsAString& aEventType,
bool aIsExternal, ErrorResult& aRv);
void GetDropEffect(nsString& aDropEffect)
{
aDropEffect.AssignASCII(sEffects[mDropEffect]);
}
void GetEffectAllowed(nsString& aEffectAllowed)
{
if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) {
aEffectAllowed.AssignLiteral("uninitialized");
} else {
aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
}
}
void SetDragImage(Element& aElement, int32_t aX, int32_t aY,
ErrorResult& aRv);
already_AddRefed<nsIDOMDOMStringList> Types();
void GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv);
void SetData(const nsAString& aFormat, const nsAString& aData,
ErrorResult& aRv);
void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
mozilla::ErrorResult& aRv);
nsDOMFileList* GetFiles(mozilla::ErrorResult& aRv);
void AddElement(Element& aElement, mozilla::ErrorResult& aRv);
uint32_t MozItemCount()
{
return mItems.Length();
}
void GetMozCursor(nsString& aCursor)
{
if (mCursorState) {
aCursor.AssignLiteral("default");
} else {
aCursor.AssignLiteral("auto");
}
}
already_AddRefed<nsIDOMDOMStringList> MozTypesAt(uint32_t aIndex,
mozilla::ErrorResult& aRv);
void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
mozilla::ErrorResult& aRv);
void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
JS::Handle<JS::Value> aData, uint32_t aIndex,
mozilla::ErrorResult& aRv);
JS::Value MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, mozilla::ErrorResult& aRv);
bool MozUserCancelled()
{
return mUserCancelled;
}
already_AddRefed<nsINode> GetMozSourceNode();
mozilla::dom::Element* GetDragTarget()
{
return mDragTarget;
}
// a readonly dataTransfer cannot have new data added or existing data removed.
@ -127,16 +203,19 @@ public:
uint32_t aIndex,
nsIPrincipal* aPrincipal);
protected:
// returns a weak reference to the drag image
nsIDOMElement* GetDragImage(int32_t* aX, int32_t* aY)
Element* GetDragImage(int32_t* aX, int32_t* aY)
{
*aX = mDragImageX;
*aY = mDragImageY;
return mDragImage;
}
nsresult Clone(nsISupports* aParent, uint32_t aEventType, bool aUserCancelled,
bool aIsCrossDomainSubFrameDrop, DataTransfer** aResult);
protected:
// returns a weak reference to the current principal
nsIPrincipal* GetCurrentPrincipal(nsresult* rv);
@ -159,6 +238,11 @@ protected:
// clipboard for a given index.
void FillInExternalData(TransferItem& aItem, uint32_t aIndex);
void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
mozilla::ErrorResult& aRv);
nsCOMPtr<nsISupports> mParent;
// the event type this data transfer is for. This will correspond to an
// event->message value.
uint32_t mEventType;
@ -196,15 +280,17 @@ protected:
nsRefPtr<nsDOMFileList> mFiles;
// the target of the drag. The drag and dragend events will fire at this.
nsCOMPtr<nsIDOMElement> mDragTarget;
nsCOMPtr<mozilla::dom::Element> mDragTarget;
// the custom drag image and coordinates within the image. If mDragImage is
// null, the default image is created from the drag target.
nsCOMPtr<nsIDOMElement> mDragImage;
nsCOMPtr<mozilla::dom::Element> mDragImage;
uint32_t mDragImageX;
uint32_t mDragImageY;
};
NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
} // namespace dom
} // namespace mozilla

View File

@ -9,8 +9,9 @@
#include "mozilla/MouseEvents.h"
using namespace mozilla;
using namespace mozilla::dom;
nsDOMDragEvent::nsDOMDragEvent(mozilla::dom::EventTarget* aOwner,
nsDOMDragEvent::nsDOMDragEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetDragEvent* aEvent)
: nsDOMMouseEvent(aOwner, aPresContext, aEvent ? aEvent :
@ -34,6 +35,31 @@ NS_INTERFACE_MAP_BEGIN(nsDOMDragEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMMouseEvent)
void
nsDOMDragEvent::InitDragEvent(const nsAString& aType, bool aCanBubble,
bool aCancelable, nsIDOMWindow* aView,
int32_t aDetail, int32_t aScreenX,
int32_t aScreenY, int32_t aClientX,
int32_t aClientY, bool aCtrlKey, bool aAltKey,
bool aShiftKey, bool aMetaKey, uint16_t aButton,
EventTarget* aRelatedTarget,
DataTransfer* aDataTransfer, ErrorResult& aError)
{
aError =
nsDOMMouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable,
aView, aDetail, aScreenX, aScreenY,
aClientX, aClientY, aCtrlKey, aAltKey,
aShiftKey, aMetaKey, aButton,
aRelatedTarget);
if (aError.Failed()) {
return;
}
if (mEventIsInternal && mEvent) {
mEvent->AsDragEvent()->dataTransfer = aDataTransfer;
}
}
NS_IMETHODIMP
nsDOMDragEvent::InitDragEvent(const nsAString & aType,
bool aCanBubble, bool aCancelable,
@ -45,6 +71,9 @@ nsDOMDragEvent::InitDragEvent(const nsAString & aType,
nsIDOMEventTarget *aRelatedTarget,
nsIDOMDataTransfer* aDataTransfer)
{
nsCOMPtr<DataTransfer> dataTransfer = do_QueryInterface(aDataTransfer);
NS_ENSURE_ARG(dataTransfer);
nsresult rv = nsDOMMouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable,
aView, aDetail, aScreenX, aScreenY, aClientX, aClientY,
aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton,
@ -52,7 +81,7 @@ nsDOMDragEvent::InitDragEvent(const nsAString & aType,
NS_ENSURE_SUCCESS(rv, rv);
if (mEventIsInternal && mEvent) {
mEvent->AsDragEvent()->dataTransfer = aDataTransfer;
mEvent->AsDragEvent()->dataTransfer = dataTransfer;
}
return NS_OK;
@ -65,7 +94,7 @@ nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
return NS_OK;
}
nsIDOMDataTransfer*
DataTransfer*
nsDOMDragEvent::GetDataTransfer()
{
// the dataTransfer field of the event caches the DataTransfer associated
@ -88,7 +117,7 @@ nsDOMDragEvent::GetDataTransfer()
}
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
mozilla::dom::EventTarget* aOwner,
EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetDragEvent* aEvent)
{

View File

@ -11,6 +11,12 @@
#include "mozilla/dom/DragEventBinding.h"
#include "mozilla/EventForwards.h"
namespace mozilla {
namespace dom {
class DataTransfer;
}
}
class nsDOMDragEvent : public nsDOMMouseEvent,
public nsIDOMDragEvent
{
@ -31,24 +37,18 @@ public:
return mozilla::dom::DragEventBinding::Wrap(aCx, aScope, this);
}
nsIDOMDataTransfer* GetDataTransfer();
mozilla::dom::DataTransfer* GetDataTransfer();
void InitDragEvent(const nsAString& aType,
bool aCanBubble, bool aCancelable,
nsIDOMWindow* aView, int32_t aDetail,
int32_t aScreenX, int32_t aScreenY,
int32_t aClientX, int32_t aClientY,
int32_t aClientX, int32_t aClientY,
bool aCtrlKey, bool aAltKey, bool aShiftKey,
bool aMetaKey, uint16_t aButton,
mozilla::dom::EventTarget* aRelatedTarget,
nsIDOMDataTransfer* aDataTransfer,
mozilla::ErrorResult& aRv)
{
aRv = InitDragEvent(aType, aCanBubble, aCancelable,
aView, aDetail, aScreenX, aScreenY, aClientX, aClientY,
aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton,
aRelatedTarget, aDataTransfer);
}
mozilla::dom::DataTransfer* aDataTransfer,
mozilla::ErrorResult& aError);
};
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,

View File

@ -2111,16 +2111,19 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
KillClickHoldTimer();
}
nsRefPtr<DataTransfer> dataTransfer =
new DataTransfer(NS_DRAGDROP_START, false, -1);
if (!dataTransfer)
nsCOMPtr<nsISupports> container = aPresContext->GetContainerWeak();
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(container);
if (!window)
return;
nsRefPtr<DataTransfer> dataTransfer =
new DataTransfer(window, NS_DRAGDROP_START, false, -1);
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsIContent> eventContent, targetContent;
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
if (eventContent)
DetermineDragTarget(aPresContext, eventContent, dataTransfer,
DetermineDragTarget(window, eventContent, dataTransfer,
getter_AddRefs(selection), getter_AddRefs(targetContent));
// Stop tracking the drag gesture now. This should stop us from
@ -2130,6 +2133,10 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
if (!targetContent)
return;
// Use our targetContent, now that we've determined it, as the
// parent object of the DataTransfer.
dataTransfer->SetParentObject(targetContent);
sLastDragOverFrame = nullptr;
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetNearestWidget();
@ -2213,7 +2220,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
} // GenerateDragGesture
void
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
nsEventStateManager::DetermineDragTarget(nsPIDOMWindow* aWindow,
nsIContent* aSelectionTarget,
DataTransfer* aDataTransfer,
nsISelection** aSelection,
@ -2221,11 +2228,6 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
{
*aTargetNode = nullptr;
nsCOMPtr<nsISupports> container = aPresContext->GetContainerWeak();
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(container);
if (!window)
return;
// GetDragData determines if a selection, link or image in the content
// should be dragged, and places the data associated with the drag in the
// data transfer.
@ -2234,7 +2236,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
bool canDrag;
nsCOMPtr<nsIContent> dragDataNode;
bool wasAlt = (mGestureModifiers & MODIFIER_ALT) != 0;
nsresult rv = nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
nsresult rv = nsContentAreaDragDrop::GetDragData(aWindow, mGestureDownContent,
aSelectionTarget, wasAlt,
aDataTransfer, &canDrag, aSelection,
getter_AddRefs(dragDataNode));
@ -2335,16 +2337,12 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
// target of the mouse event. If one wasn't set in the
// aDataTransfer during the event handler, just use the original
// target instead.
nsCOMPtr<nsIDOMNode> dragTarget;
nsCOMPtr<nsIDOMElement> dragTargetElement;
aDataTransfer->GetDragTarget(getter_AddRefs(dragTargetElement));
dragTarget = do_QueryInterface(dragTargetElement);
nsCOMPtr<Element> dragTarget = aDataTransfer->GetDragTarget();
if (!dragTarget) {
dragTarget = do_QueryInterface(aDragTarget);
if (!dragTarget)
return false;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(dragTarget);
// check which drag effect should initially be used. If the effect was not
// set, just use all actions, otherwise Windows won't allow a drop.
@ -2357,9 +2355,10 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
// get any custom drag image that was set
int32_t imageX, imageY;
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
Element* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
nsCOMPtr<nsISupportsArray> transArray = aDataTransfer->GetTransferables(dragTarget);
nsCOMPtr<nsISupportsArray> transArray =
aDataTransfer->GetTransferables(dragTarget->AsDOMNode());
if (!transArray)
return false;
@ -2367,7 +2366,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
// here, but we need something to pass to the InvokeDragSession
// methods.
nsCOMPtr<nsIDOMEvent> domEvent;
NS_NewDOMDragEvent(getter_AddRefs(domEvent), content,
NS_NewDOMDragEvent(getter_AddRefs(domEvent), dragTarget,
aPresContext, aDragEvent);
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
@ -2392,9 +2391,10 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
nsCOMPtr<nsIScriptableRegion> region;
#ifdef MOZ_XUL
if (dragTarget && !dragImage) {
if (content->NodeInfo()->Equals(nsGkAtoms::treechildren,
kNameSpaceID_XUL)) {
nsTreeBodyFrame* treeBody = do_QueryFrame(content->GetPrimaryFrame());
if (dragTarget->NodeInfo()->Equals(nsGkAtoms::treechildren,
kNameSpaceID_XUL)) {
nsTreeBodyFrame* treeBody =
do_QueryFrame(dragTarget->GetPrimaryFrame());
if (treeBody) {
treeBody->GetSelectionRegion(getter_AddRefs(region));
}
@ -2402,9 +2402,12 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
}
#endif
dragService->InvokeDragSessionWithImage(dragTarget, transArray,
region, action, dragImage,
imageX, imageY, domDragEvent,
dragService->InvokeDragSessionWithImage(dragTarget->AsDOMNode(), transArray,
region, action,
dragImage ? dragImage->AsDOMNode() :
nullptr,
imageX,
imageY, domDragEvent,
aDataTransfer);
}

View File

@ -737,7 +737,7 @@ protected:
* aSelection - [out] set to the selection to be dragged
* aTargetNode - [out] the draggable node, or null if there isn't one
*/
void DetermineDragTarget(nsPresContext* aPresContext,
void DetermineDragTarget(nsPIDOMWindow* aWindow,
nsIContent* aSelectionTarget,
mozilla::dom::DataTransfer* aDataTransfer,
nsISelection** aSelection,

View File

@ -8,7 +8,7 @@
interface nsIVariant;
interface nsIDOMFileList;
[scriptable, uuid(7D73CFBF-EC30-4F8E-B6A4-BB31EB943580)]
[scriptable, builtinclass, uuid(4ba241dd-a964-4077-bc30-515a657772e4)]
interface nsIDOMDataTransfer : nsISupports
{
/**
@ -229,14 +229,4 @@ interface nsIDOMDataTransfer : nsISupports
* constants in nsIDragService.
*/
[noscript] attribute unsigned long effectAllowedInt;
/**
* Creates a copy of the data transfer object, for the given event type and
* user cancelled flag. If isCrossDomainSubFrameDrop is set, then this is a
* cross-domain drop from a subframe where access to the data should be
* prevented.
*/
[noscript] nsIDOMDataTransfer clone(in uint32_t aEventType,
in boolean aUserCancelled,
in boolean isCrossDomainSubFrameDrop);
};

View File

@ -10,8 +10,6 @@
* liability, trademark and document use rules apply.
*/
interface DataTransfer;
[Constructor(DOMString type, optional ClipboardEventInit eventInitDict)]
interface ClipboardEvent : Event
{

View File

@ -0,0 +1,137 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is:
* http://www.whatwg.org/specs/web-apps/current-work/#the-datatransfer-interface
*/
[ChromeConstructor(DOMString eventType, boolean isExternal)]
interface DataTransfer {
attribute DOMString dropEffect;
attribute DOMString effectAllowed;
//readonly attribute DataTransferItemList items;
[Throws]
void setDragImage(Element image, long x, long y);
readonly attribute DOMStringList types;
[Throws]
DOMString getData(DOMString format);
[Throws]
void setData(DOMString format, DOMString data);
[Throws]
void clearData(optional DOMString format);
[Throws]
readonly attribute FileList files;
};
// Mozilla specific stuff
partial interface DataTransfer {
/*
* Set the drag source. Usually you would not change this, but it will
* affect which node the drag and dragend events are fired at. The
* default target is the node that was dragged.
*
* @param element drag source to use
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
*/
[Throws]
void addElement(Element element);
/**
* The number of items being dragged.
*/
readonly attribute unsigned long mozItemCount;
/**
* Sets the drag cursor state. Primarily used to control the cursor during
* tab drags, but could be expanded to other uses. XXX Currently implemented
* on Win32 only.
*
* Possible values:
* auto - use default system behavior.
* default - set the cursor to an arrow during the drag operation.
*
* Values other than 'default' are indentical to setting mozCursor to
* 'auto'.
*/
attribute DOMString mozCursor;
/**
* Holds a list of the format types of the data that is stored for an item
* at the specified index. If the index is not in the range from 0 to
* itemCount - 1, an empty string list is returned.
*/
[Throws]
DOMStringList mozTypesAt(unsigned long index);
/**
* Remove the data associated with the given format for an item at the
* specified index. The index is in the range from zero to itemCount - 1.
*
* If the last format for the item is removed, the entire item is removed,
* reducing the itemCount by one.
*
* If format is empty, then the data associated with all formats is removed.
* If the format is not found, then this method has no effect.
*
* @param format the format to remove
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
*/
[Throws]
void mozClearDataAt(DOMString format, unsigned long index);
/*
* A data transfer may store multiple items, each at a given zero-based
* index. setDataAt may only be called with an index argument less than
* itemCount in which case an existing item is modified, or equal to
* itemCount in which case a new item is added, and the itemCount is
* incremented by one.
*
* Data should be added in order of preference, with the most specific
* format added first and the least specific format added last. If data of
* the given format already exists, it is replaced in the same position as
* the old data.
*
* The data should be either a string, a primitive boolean or number type
* (which will be converted into a string) or an nsISupports.
*
* @param format the format to add
* @param data the data to add
* @throws NS_ERROR_NULL_POINTER if the data is null
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater than itemCount
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
*/
[Throws]
void mozSetDataAt(DOMString format, any data, unsigned long index);
/**
* Retrieve the data associated with the given format for an item at the
* specified index, or null if it does not exist. The index should be in the
* range from zero to itemCount - 1.
*
* @param format the format of the data to look up
* @returns the data of the given format, or null if it doesn't exist.
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
*/
[Throws]
any mozGetDataAt(DOMString format, unsigned long index);
/**
* Will be true when the user has cancelled the drag (typically by pressing
* Escape) and when the drag has been cancelled unexpectedly. This will be
* false otherwise, including when the drop has been rejected by its target.
* This property is only relevant for the dragend event.
*/
readonly attribute boolean mozUserCancelled;
/**
* The node that the mouse was pressed over to begin the drag. For external
* drags, or if the caller cannot access this node, this will be null.
*/
readonly attribute Node? mozSourceNode;
};

View File

@ -5,7 +5,6 @@
*/
interface WindowProxy;
interface DataTransfer;
interface DragEvent : MouseEvent
{

View File

@ -66,6 +66,7 @@ WEBIDL_FILES = [
'CSSValueList.webidl',
'DataContainerEvent.webidl',
'DataStore.webidl',
'DataTransfer.webidl',
'DedicatedWorkerGlobalScope.webidl',
'DelayNode.webidl',
'DesktopNotification.webidl',

View File

@ -21,7 +21,7 @@
#include "nsIController.h" // for nsIController
#include "nsID.h"
#include "nsIDOMDOMStringList.h" // for nsIDOMDOMStringList
#include "nsIDOMDataTransfer.h" // for nsIDOMDataTransfer
#include "mozilla/dom/DataTransfer.h"
#include "nsIDOMDocument.h" // for nsIDOMDocument
#include "nsIDOMDragEvent.h" // for nsIDOMDragEvent
#include "nsIDOMElement.h" // for nsIDOMElement

View File

@ -35,7 +35,7 @@
#include "nsIContentFilter.h"
#include "nsIDOMComment.h"
#include "nsIDOMDOMStringList.h"
#include "nsIDOMDataTransfer.h"
#include "mozilla/dom/DataTransfer.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMElement.h"

View File

@ -10,6 +10,7 @@
#include "nsIDocument.h"
#include "nsINodeInfo.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/HTMLButtonElement.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "nsNodeInfoManager.h"

View File

@ -9,9 +9,9 @@
#include <stdint.h>
#include "mozilla/BasicEvents.h"
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/EventTarget.h"
#include "nsCOMPtr.h"
#include "nsIDOMDataTransfer.h"
#include "nsRect.h"
#include "nsStringGlue.h"
@ -174,7 +174,7 @@ public:
return result;
}
nsCOMPtr<nsIDOMDataTransfer> clipboardData;
nsCOMPtr<dom::DataTransfer> clipboardData;
void AssignClipboardEventData(const InternalClipboardEvent& aEvent,
bool aCopyTargets)

View File

@ -10,8 +10,8 @@
#include "mozilla/BasicEvents.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/dom/DataTransfer.h"
#include "nsCOMPtr.h"
#include "nsIDOMDataTransfer.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMWheelEvent.h"
@ -310,7 +310,7 @@ public:
}
// The dragging data.
nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
nsCOMPtr<dom::DataTransfer> dataTransfer;
// If this is true, user has cancelled the drag operation.
bool userCancelled;