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/AsyncEventDispatcher.h" michael@0: #include "mozilla/BasicEvents.h" michael@0: #include "mozilla/EventDispatcher.h" michael@0: #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent() michael@0: #include "mozilla/dom/EventTarget.h" michael@0: #include "nsContentUtils.h" michael@0: #include "nsIDOMEvent.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: using namespace dom; michael@0: michael@0: /****************************************************************************** michael@0: * mozilla::AsyncEventDispatcher michael@0: ******************************************************************************/ michael@0: michael@0: AsyncEventDispatcher::AsyncEventDispatcher(nsINode* aEventNode, michael@0: WidgetEvent& aEvent) michael@0: : mEventNode(aEventNode) michael@0: , mDispatchChromeOnly(false) michael@0: { michael@0: MOZ_ASSERT(mEventNode); michael@0: EventDispatcher::CreateEvent(aEventNode, nullptr, &aEvent, EmptyString(), michael@0: getter_AddRefs(mEvent)); michael@0: NS_ASSERTION(mEvent, "Should never fail to create an event"); michael@0: mEvent->DuplicatePrivateData(); michael@0: mEvent->SetTrusted(aEvent.mFlags.mIsTrusted); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: AsyncEventDispatcher::Run() michael@0: { michael@0: if (mEvent) { michael@0: if (mDispatchChromeOnly) { michael@0: MOZ_ASSERT(mEvent->InternalDOMEvent()->IsTrusted()); michael@0: michael@0: nsCOMPtr ownerDoc = mEventNode->OwnerDoc(); michael@0: nsPIDOMWindow* window = ownerDoc->GetWindow(); michael@0: if (!window) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsCOMPtr target = window->GetParentTarget(); michael@0: if (!target) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: EventDispatcher::DispatchDOMEvent(target, nullptr, mEvent, michael@0: nullptr, nullptr); michael@0: } else { michael@0: nsCOMPtr target = mEventNode.get(); michael@0: bool defaultActionEnabled; // This is not used because the caller is async michael@0: target->DispatchEvent(mEvent, &defaultActionEnabled); michael@0: } michael@0: } else { michael@0: nsIDocument* doc = mEventNode->OwnerDoc(); michael@0: if (mDispatchChromeOnly) { michael@0: nsContentUtils::DispatchChromeEvent(doc, mEventNode, mEventType, michael@0: mBubbles, false); michael@0: } else { michael@0: nsContentUtils::DispatchTrustedEvent(doc, mEventNode, mEventType, michael@0: mBubbles, false); michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: AsyncEventDispatcher::PostDOMEvent() michael@0: { michael@0: return NS_DispatchToCurrentThread(this); michael@0: } michael@0: michael@0: void michael@0: AsyncEventDispatcher::RunDOMEventWhenSafe() michael@0: { michael@0: nsContentUtils::AddScriptRunner(this); michael@0: } michael@0: michael@0: /****************************************************************************** michael@0: * mozilla::LoadBlockingAsyncEventDispatcher michael@0: ******************************************************************************/ michael@0: michael@0: LoadBlockingAsyncEventDispatcher::~LoadBlockingAsyncEventDispatcher() michael@0: { michael@0: if (mBlockedDoc) { michael@0: mBlockedDoc->UnblockOnload(true); michael@0: } michael@0: } michael@0: michael@0: } // namespace mozilla