/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */ #include "mozilla/dom/DragEvent.h" #include "mozilla/MouseEvents.h" #include "nsContentUtils.h" #include "prtime.h" namespace mozilla { namespace dom { DragEvent::DragEvent(EventTarget* aOwner, nsPresContext* aPresContext, WidgetDragEvent* aEvent) : MouseEvent(aOwner, aPresContext, aEvent ? aEvent : new WidgetDragEvent(false, 0, nullptr)) { if (aEvent) { mEventIsInternal = false; } else { mEventIsInternal = true; mEvent->time = PR_Now(); mEvent->refPoint.x = mEvent->refPoint.y = 0; mEvent->AsMouseEvent()->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN; } } NS_IMPL_ADDREF_INHERITED(DragEvent, MouseEvent) NS_IMPL_RELEASE_INHERITED(DragEvent, MouseEvent) NS_INTERFACE_MAP_BEGIN(DragEvent) NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent) NS_INTERFACE_MAP_END_INHERITING(MouseEvent) void DragEvent::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 = MouseEvent::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 DragEvent::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, nsIDOMEventTarget* aRelatedTarget, nsIDOMDataTransfer* aDataTransfer) { nsCOMPtr dataTransfer = do_QueryInterface(aDataTransfer); nsresult rv = MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail, aScreenX, aScreenY, aClientX, aClientY, aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton, aRelatedTarget); NS_ENSURE_SUCCESS(rv, rv); if (mEventIsInternal && mEvent) { mEvent->AsDragEvent()->dataTransfer = dataTransfer; } return NS_OK; } NS_IMETHODIMP DragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer) { NS_IF_ADDREF(*aDataTransfer = GetDataTransfer()); return NS_OK; } DataTransfer* DragEvent::GetDataTransfer() { // the dataTransfer field of the event caches the DataTransfer associated // with the drag. It is initialized when an attempt is made to retrieve it // rather that when the event is created to avoid duplicating the data when // no listener ever uses it. if (!mEvent || mEvent->mClass != eDragEventClass) { NS_WARNING("Tried to get dataTransfer from non-drag event!"); return nullptr; } WidgetDragEvent* dragEvent = mEvent->AsDragEvent(); // for synthetic events, just use the supplied data transfer object even if null if (!mEventIsInternal) { nsresult rv = nsContentUtils::SetDataTransferInEvent(dragEvent); NS_ENSURE_SUCCESS(rv, nullptr); } return dragEvent->dataTransfer; } // static already_AddRefed DragEvent::Constructor(const GlobalObject& aGlobal, const nsAString& aType, const DragEventInit& aParam, ErrorResult& aRv) { nsCOMPtr t = do_QueryInterface(aGlobal.GetAsSupports()); nsRefPtr e = new DragEvent(t, nullptr, nullptr); bool trusted = e->Init(t); aRv = e->InitDragEvent(aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail, aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY, aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey, aParam.mMetaKey, aParam.mButton, aParam.mRelatedTarget, aParam.mDataTransfer); e->InitializeExtraMouseEventDictionaryMembers(aParam); e->SetTrusted(trusted); return e.forget(); } } // namespace dom } // namespace mozilla using namespace mozilla; using namespace mozilla::dom; nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult, EventTarget* aOwner, nsPresContext* aPresContext, WidgetDragEvent* aEvent) { DragEvent* event = new DragEvent(aOwner, aPresContext, aEvent); return CallQueryInterface(event, aInstancePtrResult); }