event_emitter.h 4.1 KB

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