DragEvent.cpp (3741B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "DragEvent.h" 8 9 #include "mozilla/MouseEvents.h" 10 #include "mozilla/dom/MouseEventBinding.h" 11 #include "nsContentUtils.h" 12 13 namespace mozilla::dom { 14 15 DragEvent::DragEvent(EventTarget* aOwner, nsPresContext* aPresContext, 16 WidgetDragEvent* aEvent) 17 : MouseEvent( 18 aOwner, aPresContext, 19 aEvent ? aEvent : new WidgetDragEvent(false, eVoidEvent, nullptr)) { 20 if (aEvent) { 21 mEventIsInternal = false; 22 } else { 23 mEventIsInternal = true; 24 mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0); 25 mEvent->AsMouseEvent()->mInputSource = 26 MouseEvent_Binding::MOZ_SOURCE_UNKNOWN; 27 } 28 } 29 30 void DragEvent::InitDragEventInternal( 31 const nsAString& aType, bool aCanBubble, bool aCancelable, 32 nsGlobalWindowInner* aView, int32_t aDetail, double aScreenX, 33 double aScreenY, double aClientX, double aClientY, bool aCtrlKey, 34 bool aAltKey, bool aShiftKey, bool aMetaKey, uint16_t aButton, 35 EventTarget* aRelatedTarget, DataTransfer* aDataTransfer) { 36 NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched); 37 38 MouseEvent::InitMouseEventInternal(aType, aCanBubble, aCancelable, aView, 39 aDetail, aScreenX, aScreenY, aClientX, 40 aClientY, aCtrlKey, aAltKey, aShiftKey, 41 aMetaKey, aButton, aRelatedTarget); 42 if (mEventIsInternal) { 43 mEvent->AsDragEvent()->mDataTransfer = aDataTransfer; 44 } 45 } 46 47 DataTransfer* DragEvent::GetDataTransfer() { 48 // the dataTransfer field of the event caches the DataTransfer associated 49 // with the drag. It is initialized when an attempt is made to retrieve it 50 // rather that when the event is created to avoid duplicating the data when 51 // no listener ever uses it. 52 if (!mEvent || mEvent->mClass != eDragEventClass) { 53 NS_WARNING("Tried to get dataTransfer from non-drag event!"); 54 return nullptr; 55 } 56 57 WidgetDragEvent* dragEvent = mEvent->AsDragEvent(); 58 // for synthetic events, just use the supplied data transfer object even if 59 // null 60 if (!mEventIsInternal) { 61 nsresult rv = nsContentUtils::SetDataTransferInEvent(dragEvent); 62 NS_ENSURE_SUCCESS(rv, nullptr); 63 } 64 65 return dragEvent->mDataTransfer; 66 } 67 68 // static 69 already_AddRefed<DragEvent> DragEvent::Constructor( 70 const GlobalObject& aGlobal, const nsAString& aType, 71 const DragEventInit& aParam) { 72 nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports()); 73 RefPtr<DragEvent> e = new DragEvent(t, nullptr, nullptr); 74 bool trusted = e->Init(t); 75 e->InitDragEventInternal( 76 aType, aParam.mBubbles, aParam.mCancelable, aParam.mView, aParam.mDetail, 77 aParam.mScreenX, aParam.mScreenY, aParam.mClientX, aParam.mClientY, 78 aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey, aParam.mMetaKey, 79 aParam.mButton, aParam.mRelatedTarget, aParam.mDataTransfer); 80 e->InitializeExtraMouseEventDictionaryMembers(aParam); 81 e->SetTrusted(trusted); 82 e->SetComposed(aParam.mComposed); 83 return e.forget(); 84 } 85 86 } // namespace mozilla::dom 87 88 using namespace mozilla; 89 using namespace mozilla::dom; 90 91 already_AddRefed<DragEvent> NS_NewDOMDragEvent(EventTarget* aOwner, 92 nsPresContext* aPresContext, 93 WidgetDragEvent* aEvent) { 94 RefPtr<DragEvent> event = new DragEvent(aOwner, aPresContext, aEvent); 95 return event.forget(); 96 }