CustomEvent.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. #include "CustomEvent.h"
  6. #include "mozilla/dom/CustomEventBinding.h"
  7. #include "mozilla/dom/BindingUtils.h"
  8. #include "nsContentUtils.h"
  9. #include "nsIXPConnect.h"
  10. using namespace mozilla;
  11. using namespace mozilla::dom;
  12. CustomEvent::CustomEvent(mozilla::dom::EventTarget* aOwner,
  13. nsPresContext* aPresContext,
  14. mozilla::WidgetEvent* aEvent)
  15. : Event(aOwner, aPresContext, aEvent)
  16. , mDetail(JS::NullValue())
  17. {
  18. mozilla::HoldJSObjects(this);
  19. }
  20. CustomEvent::~CustomEvent()
  21. {
  22. mozilla::DropJSObjects(this);
  23. }
  24. NS_IMPL_CYCLE_COLLECTION_CLASS(CustomEvent)
  25. NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CustomEvent, Event)
  26. tmp->mDetail.setUndefined();
  27. mozilla::DropJSObjects(this);
  28. NS_IMPL_CYCLE_COLLECTION_UNLINK_END
  29. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CustomEvent, Event)
  30. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  31. NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CustomEvent, Event)
  32. NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDetail)
  33. NS_IMPL_CYCLE_COLLECTION_TRACE_END
  34. NS_IMPL_ADDREF_INHERITED(CustomEvent, Event)
  35. NS_IMPL_RELEASE_INHERITED(CustomEvent, Event)
  36. NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CustomEvent)
  37. NS_INTERFACE_MAP_ENTRY(nsIDOMCustomEvent)
  38. NS_INTERFACE_MAP_END_INHERITING(Event)
  39. already_AddRefed<CustomEvent>
  40. CustomEvent::Constructor(const GlobalObject& aGlobal,
  41. const nsAString& aType,
  42. const CustomEventInit& aParam,
  43. ErrorResult& aRv)
  44. {
  45. nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
  46. RefPtr<CustomEvent> e = new CustomEvent(t, nullptr, nullptr);
  47. bool trusted = e->Init(t);
  48. JS::Rooted<JS::Value> detail(aGlobal.Context(), aParam.mDetail);
  49. e->InitCustomEvent(aGlobal.Context(), aType, aParam.mBubbles, aParam.mCancelable, detail, aRv);
  50. e->SetTrusted(trusted);
  51. e->SetComposed(aParam.mComposed);
  52. return e.forget();
  53. }
  54. JSObject*
  55. CustomEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
  56. {
  57. return mozilla::dom::CustomEventBinding::Wrap(aCx, this, aGivenProto);
  58. }
  59. NS_IMETHODIMP
  60. CustomEvent::InitCustomEvent(const nsAString& aType,
  61. bool aCanBubble,
  62. bool aCancelable,
  63. nsIVariant* aDetail)
  64. {
  65. NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK);
  66. AutoJSAPI jsapi;
  67. NS_ENSURE_STATE(jsapi.Init(GetParentObject()));
  68. JSContext* cx = jsapi.cx();
  69. JS::Rooted<JS::Value> detail(cx);
  70. if (!aDetail) {
  71. detail = JS::NullValue();
  72. } else if (NS_WARN_IF(!VariantToJsval(cx, aDetail, &detail))) {
  73. JS_ClearPendingException(cx);
  74. return NS_ERROR_FAILURE;
  75. }
  76. Event::InitEvent(aType, aCanBubble, aCancelable);
  77. mDetail = detail;
  78. return NS_OK;
  79. }
  80. void
  81. CustomEvent::InitCustomEvent(JSContext* aCx,
  82. const nsAString& aType,
  83. bool aCanBubble,
  84. bool aCancelable,
  85. JS::Handle<JS::Value> aDetail,
  86. ErrorResult& aRv)
  87. {
  88. NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
  89. Event::InitEvent(aType, aCanBubble, aCancelable);
  90. mDetail = aDetail;
  91. }
  92. NS_IMETHODIMP
  93. CustomEvent::GetDetail(nsIVariant** aDetail)
  94. {
  95. if (mDetail.isNull()) {
  96. *aDetail = nullptr;
  97. return NS_OK;
  98. }
  99. AutoJSAPI jsapi;
  100. NS_ENSURE_STATE(jsapi.Init(GetParentObject()));
  101. JSContext* cx = jsapi.cx();
  102. JS::Rooted<JS::Value> detail(cx, mDetail);
  103. nsIXPConnect* xpc = nsContentUtils::XPConnect();
  104. if (NS_WARN_IF(!xpc)) {
  105. return NS_ERROR_FAILURE;
  106. }
  107. return xpc->JSToVariant(cx, detail, aDetail);
  108. }
  109. void
  110. CustomEvent::GetDetail(JSContext* aCx,
  111. JS::MutableHandle<JS::Value> aRetval)
  112. {
  113. aRetval.set(mDetail);
  114. }
  115. already_AddRefed<CustomEvent>
  116. NS_NewDOMCustomEvent(EventTarget* aOwner,
  117. nsPresContext* aPresContext,
  118. mozilla::WidgetEvent* aEvent)
  119. {
  120. RefPtr<CustomEvent> it =
  121. new CustomEvent(aOwner, aPresContext, aEvent);
  122. return it.forget();
  123. }