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: #ifndef mozilla_AsyncEventDispatcher_h_ michael@0: #define mozilla_AsyncEventDispatcher_h_ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsIDOMEvent.h" michael@0: #include "nsINode.h" michael@0: #include "nsString.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: /** michael@0: * Use nsAsyncDOMEvent to fire a DOM event that requires safe a stable DOM. michael@0: * For example, you may need to fire an event from within layout, but michael@0: * want to ensure that the event handler doesn't mutate the DOM at michael@0: * the wrong time, in order to avoid resulting instability. michael@0: */ michael@0: michael@0: class AsyncEventDispatcher : public nsRunnable michael@0: { michael@0: public: michael@0: AsyncEventDispatcher(nsINode* aEventNode, const nsAString& aEventType, michael@0: bool aBubbles, bool aDispatchChromeOnly) michael@0: : mEventNode(aEventNode) michael@0: , mEventType(aEventType) michael@0: , mBubbles(aBubbles) michael@0: , mDispatchChromeOnly(aDispatchChromeOnly) michael@0: { michael@0: } michael@0: michael@0: AsyncEventDispatcher(nsINode* aEventNode, nsIDOMEvent* aEvent) michael@0: : mEventNode(aEventNode) michael@0: , mEvent(aEvent) michael@0: , mDispatchChromeOnly(false) michael@0: { michael@0: } michael@0: michael@0: AsyncEventDispatcher(nsINode* aEventNode, WidgetEvent& aEvent); michael@0: michael@0: NS_IMETHOD Run() MOZ_OVERRIDE; michael@0: nsresult PostDOMEvent(); michael@0: void RunDOMEventWhenSafe(); michael@0: michael@0: nsCOMPtr mEventNode; michael@0: nsCOMPtr mEvent; michael@0: nsString mEventType; michael@0: bool mBubbles; michael@0: bool mDispatchChromeOnly; michael@0: }; michael@0: michael@0: class LoadBlockingAsyncEventDispatcher MOZ_FINAL : public AsyncEventDispatcher michael@0: { michael@0: public: michael@0: LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, michael@0: const nsAString& aEventType, michael@0: bool aBubbles, bool aDispatchChromeOnly) michael@0: : AsyncEventDispatcher(aEventNode, aEventType, michael@0: aBubbles, aDispatchChromeOnly) michael@0: , mBlockedDoc(aEventNode->OwnerDoc()) michael@0: { michael@0: if (mBlockedDoc) { michael@0: mBlockedDoc->BlockOnload(); michael@0: } michael@0: } michael@0: michael@0: LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, nsIDOMEvent* aEvent) michael@0: : AsyncEventDispatcher(aEventNode, aEvent) michael@0: , mBlockedDoc(aEventNode->OwnerDoc()) michael@0: { michael@0: if (mBlockedDoc) { michael@0: mBlockedDoc->BlockOnload(); michael@0: } michael@0: } michael@0: michael@0: ~LoadBlockingAsyncEventDispatcher(); michael@0: michael@0: private: michael@0: nsCOMPtr mBlockedDoc; michael@0: }; michael@0: michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_AsyncEventDispatcher_h_