event_emitter.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright (c) 2014 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #ifndef ATOM_BROWSER_API_EVENT_EMITTER_H_
  5. #define ATOM_BROWSER_API_EVENT_EMITTER_H_
  6. #include <utility>
  7. #include <vector>
  8. #include "atom/common/api/event_emitter_caller.h"
  9. #include "base/optional.h"
  10. #include "content/public/browser/browser_thread.h"
  11. #include "electron/atom/common/api/api.mojom.h"
  12. #include "native_mate/wrappable.h"
  13. namespace content {
  14. class RenderFrameHost;
  15. }
  16. namespace mate {
  17. namespace internal {
  18. v8::Local<v8::Object> CreateJSEvent(
  19. v8::Isolate* isolate,
  20. v8::Local<v8::Object> object,
  21. content::RenderFrameHost* sender,
  22. base::Optional<atom::mojom::ElectronBrowser::MessageSyncCallback> callback);
  23. v8::Local<v8::Object> CreateCustomEvent(v8::Isolate* isolate,
  24. v8::Local<v8::Object> object,
  25. v8::Local<v8::Object> event);
  26. v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
  27. } // namespace internal
  28. // Provide helperers to emit event in JavaScript.
  29. template <typename T>
  30. class EventEmitter : public Wrappable<T> {
  31. public:
  32. typedef std::vector<v8::Local<v8::Value>> ValueArray;
  33. // Make the convinient methods visible:
  34. // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
  35. v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
  36. v8::Local<v8::Object> GetWrapper() const {
  37. return Wrappable<T>::GetWrapper();
  38. }
  39. // this.emit(name, event, args...);
  40. template <typename... Args>
  41. bool EmitCustomEvent(const base::StringPiece& name,
  42. v8::Local<v8::Object> event,
  43. const Args&... args) {
  44. return EmitWithEvent(
  45. name, internal::CreateCustomEvent(isolate(), GetWrapper(), event),
  46. args...);
  47. }
  48. // this.emit(name, new Event(flags), args...);
  49. template <typename... Args>
  50. bool EmitWithFlags(const base::StringPiece& name,
  51. int flags,
  52. const Args&... args) {
  53. return EmitCustomEvent(
  54. name, internal::CreateEventFromFlags(isolate(), flags), args...);
  55. }
  56. // this.emit(name, new Event(), args...);
  57. template <typename... Args>
  58. bool Emit(const base::StringPiece& name, const Args&... args) {
  59. return EmitWithSender(name, nullptr, base::nullopt, args...);
  60. }
  61. // this.emit(name, new Event(sender, message), args...);
  62. template <typename... Args>
  63. bool EmitWithSender(
  64. const base::StringPiece& name,
  65. content::RenderFrameHost* sender,
  66. base::Optional<atom::mojom::ElectronBrowser::MessageSyncCallback>
  67. callback,
  68. const Args&... args) {
  69. v8::Locker locker(isolate());
  70. v8::HandleScope handle_scope(isolate());
  71. v8::Local<v8::Object> wrapper = GetWrapper();
  72. if (wrapper.IsEmpty()) {
  73. return false;
  74. }
  75. v8::Local<v8::Object> event = internal::CreateJSEvent(
  76. isolate(), wrapper, sender, std::move(callback));
  77. return EmitWithEvent(name, event, args...);
  78. }
  79. protected:
  80. EventEmitter() {}
  81. private:
  82. // this.emit(name, event, args...);
  83. template <typename... Args>
  84. bool EmitWithEvent(const base::StringPiece& name,
  85. v8::Local<v8::Object> event,
  86. const Args&... args) {
  87. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  88. v8::Locker locker(isolate());
  89. v8::HandleScope handle_scope(isolate());
  90. EmitEvent(isolate(), GetWrapper(), name, event, args...);
  91. auto context = isolate()->GetCurrentContext();
  92. v8::Local<v8::Value> defaultPrevented;
  93. if (event->Get(context, StringToV8(isolate(), "defaultPrevented"))
  94. .ToLocal(&defaultPrevented)) {
  95. return defaultPrevented->BooleanValue(isolate());
  96. }
  97. return false;
  98. }
  99. DISALLOW_COPY_AND_ASSIGN(EventEmitter);
  100. };
  101. } // namespace mate
  102. #endif // ATOM_BROWSER_API_EVENT_EMITTER_H_