michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/dom/DragEvent.h" michael@0: #include "mozilla/MouseEvents.h" michael@0: #include "nsContentUtils.h" michael@0: #include "prtime.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: DragEvent::DragEvent(EventTarget* aOwner, michael@0: nsPresContext* aPresContext, michael@0: WidgetDragEvent* aEvent) michael@0: : MouseEvent(aOwner, aPresContext, michael@0: aEvent ? aEvent : new WidgetDragEvent(false, 0, nullptr)) michael@0: { michael@0: if (aEvent) { michael@0: mEventIsInternal = false; michael@0: } michael@0: else { michael@0: mEventIsInternal = true; michael@0: mEvent->time = PR_Now(); michael@0: mEvent->refPoint.x = mEvent->refPoint.y = 0; michael@0: mEvent->AsMouseEvent()->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN; michael@0: } michael@0: } michael@0: michael@0: NS_IMPL_ADDREF_INHERITED(DragEvent, MouseEvent) michael@0: NS_IMPL_RELEASE_INHERITED(DragEvent, MouseEvent) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(DragEvent) michael@0: NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent) michael@0: NS_INTERFACE_MAP_END_INHERITING(MouseEvent) michael@0: michael@0: void michael@0: DragEvent::InitDragEvent(const nsAString& aType, michael@0: bool aCanBubble, michael@0: bool aCancelable, michael@0: nsIDOMWindow* aView, michael@0: int32_t aDetail, michael@0: int32_t aScreenX, michael@0: int32_t aScreenY, michael@0: int32_t aClientX, michael@0: int32_t aClientY, michael@0: bool aCtrlKey, michael@0: bool aAltKey, michael@0: bool aShiftKey, michael@0: bool aMetaKey, michael@0: uint16_t aButton, michael@0: EventTarget* aRelatedTarget, michael@0: DataTransfer* aDataTransfer, michael@0: ErrorResult& aError) michael@0: { michael@0: aError = michael@0: MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, michael@0: aView, aDetail, aScreenX, aScreenY, michael@0: aClientX, aClientY, aCtrlKey, aAltKey, michael@0: aShiftKey, aMetaKey, aButton, aRelatedTarget); michael@0: if (aError.Failed()) { michael@0: return; michael@0: } michael@0: michael@0: if (mEventIsInternal && mEvent) { michael@0: mEvent->AsDragEvent()->dataTransfer = aDataTransfer; michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: DragEvent::InitDragEvent(const nsAString& aType, michael@0: bool aCanBubble, michael@0: bool aCancelable, michael@0: nsIDOMWindow* aView, michael@0: int32_t aDetail, michael@0: int32_t aScreenX, michael@0: int32_t aScreenY, michael@0: int32_t aClientX, michael@0: int32_t aClientY, michael@0: bool aCtrlKey, michael@0: bool aAltKey, michael@0: bool aShiftKey, michael@0: bool aMetaKey, michael@0: uint16_t aButton, michael@0: nsIDOMEventTarget* aRelatedTarget, michael@0: nsIDOMDataTransfer* aDataTransfer) michael@0: { michael@0: nsCOMPtr dataTransfer = do_QueryInterface(aDataTransfer); michael@0: michael@0: nsresult rv = michael@0: MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail, michael@0: aScreenX, aScreenY, aClientX, aClientY, michael@0: aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton, michael@0: aRelatedTarget); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (mEventIsInternal && mEvent) { michael@0: mEvent->AsDragEvent()->dataTransfer = dataTransfer; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: DragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer) michael@0: { michael@0: NS_IF_ADDREF(*aDataTransfer = GetDataTransfer()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: DataTransfer* michael@0: DragEvent::GetDataTransfer() michael@0: { michael@0: // the dataTransfer field of the event caches the DataTransfer associated michael@0: // with the drag. It is initialized when an attempt is made to retrieve it michael@0: // rather that when the event is created to avoid duplicating the data when michael@0: // no listener ever uses it. michael@0: if (!mEvent || mEvent->eventStructType != NS_DRAG_EVENT) { michael@0: NS_WARNING("Tried to get dataTransfer from non-drag event!"); michael@0: return nullptr; michael@0: } michael@0: michael@0: WidgetDragEvent* dragEvent = mEvent->AsDragEvent(); michael@0: // for synthetic events, just use the supplied data transfer object even if null michael@0: if (!mEventIsInternal) { michael@0: nsresult rv = nsContentUtils::SetDataTransferInEvent(dragEvent); michael@0: NS_ENSURE_SUCCESS(rv, nullptr); michael@0: } michael@0: michael@0: return dragEvent->dataTransfer; michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: nsresult michael@0: NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult, michael@0: EventTarget* aOwner, michael@0: nsPresContext* aPresContext, michael@0: WidgetDragEvent* aEvent) michael@0: { michael@0: DragEvent* event = new DragEvent(aOwner, aPresContext, aEvent); michael@0: return CallQueryInterface(event, aInstancePtrResult); michael@0: }