AsyncEventDispatcher.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_AsyncEventDispatcher_h_
  6. #define mozilla_AsyncEventDispatcher_h_
  7. #include "mozilla/Attributes.h"
  8. #include "nsCOMPtr.h"
  9. #include "nsIDocument.h"
  10. #include "nsIDOMEvent.h"
  11. #include "nsString.h"
  12. #include "nsThreadUtils.h"
  13. class nsINode;
  14. namespace mozilla {
  15. /**
  16. * Use AsyncEventDispatcher to fire a DOM event that requires safe a stable DOM.
  17. * For example, you may need to fire an event from within layout, but
  18. * want to ensure that the event handler doesn't mutate the DOM at
  19. * the wrong time, in order to avoid resulting instability.
  20. */
  21. class AsyncEventDispatcher : public CancelableRunnable
  22. {
  23. public:
  24. /**
  25. * If aOnlyChromeDispatch is true, the event is dispatched to only
  26. * chrome node. In that case, if aTarget is already a chrome node,
  27. * the event is dispatched to it, otherwise the dispatch path starts
  28. * at the first chrome ancestor of that target.
  29. */
  30. AsyncEventDispatcher(nsINode* aTarget, const nsAString& aEventType,
  31. bool aBubbles, bool aOnlyChromeDispatch)
  32. : mTarget(aTarget)
  33. , mEventType(aEventType)
  34. , mBubbles(aBubbles)
  35. , mOnlyChromeDispatch(aOnlyChromeDispatch)
  36. {
  37. }
  38. AsyncEventDispatcher(dom::EventTarget* aTarget, const nsAString& aEventType,
  39. bool aBubbles)
  40. : mTarget(aTarget)
  41. , mEventType(aEventType)
  42. , mBubbles(aBubbles)
  43. {
  44. }
  45. AsyncEventDispatcher(dom::EventTarget* aTarget, nsIDOMEvent* aEvent)
  46. : mTarget(aTarget)
  47. , mEvent(aEvent)
  48. {
  49. }
  50. AsyncEventDispatcher(dom::EventTarget* aTarget, WidgetEvent& aEvent);
  51. NS_IMETHOD Run() override;
  52. nsresult Cancel() override;
  53. nsresult PostDOMEvent();
  54. void RunDOMEventWhenSafe();
  55. nsCOMPtr<dom::EventTarget> mTarget;
  56. nsCOMPtr<nsIDOMEvent> mEvent;
  57. nsString mEventType;
  58. bool mBubbles = false;
  59. bool mOnlyChromeDispatch = false;
  60. bool mCanceled = false;
  61. };
  62. class LoadBlockingAsyncEventDispatcher final : public AsyncEventDispatcher
  63. {
  64. public:
  65. LoadBlockingAsyncEventDispatcher(nsINode* aEventNode,
  66. const nsAString& aEventType,
  67. bool aBubbles, bool aDispatchChromeOnly)
  68. : AsyncEventDispatcher(aEventNode, aEventType,
  69. aBubbles, aDispatchChromeOnly)
  70. , mBlockedDoc(aEventNode->OwnerDoc())
  71. {
  72. if (mBlockedDoc) {
  73. mBlockedDoc->BlockOnload();
  74. }
  75. }
  76. LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, nsIDOMEvent* aEvent)
  77. : AsyncEventDispatcher(aEventNode, aEvent)
  78. , mBlockedDoc(aEventNode->OwnerDoc())
  79. {
  80. if (mBlockedDoc) {
  81. mBlockedDoc->BlockOnload();
  82. }
  83. }
  84. ~LoadBlockingAsyncEventDispatcher();
  85. private:
  86. nsCOMPtr<nsIDocument> mBlockedDoc;
  87. };
  88. } // namespace mozilla
  89. #endif // mozilla_AsyncEventDispatcher_h_