diff --git a/atom/browser/api/atom_api_notification.cc b/atom/browser/api/atom_api_notification.cc new file mode 100644 index 00000000000..791d574774c --- /dev/null +++ b/atom/browser/api/atom_api_notification.cc @@ -0,0 +1,174 @@ +// Copyright (c) 2014 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/api/atom_api_notification.h" + +#include "atom/browser/api/atom_api_menu.h" +#include "atom/browser/browser.h" +#include "atom/common/native_mate_converters/gfx_converter.h" +#include "atom/common/native_mate_converters/image_converter.h" +#include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/node_includes.h" +#include "base/strings/utf_string_conversions.h" +#include "brightray/browser/browser_client.h" +#include "native_mate/constructor.h" +#include "native_mate/dictionary.h" +#include "url/gurl.h" + +namespace atom { + +namespace api { + +Notification::Notification(v8::Isolate* isolate, + v8::Local wrapper, + mate::Arguments* args) { + InitWith(isolate, wrapper); + + presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter(); + + mate::Dictionary opts; + if (args->GetNext(&opts)) { + opts.Get("title", &title_); + opts.Get("body", &body_); + has_icon_ = opts.Get("icon", &icon_); + if (has_icon_) { + opts.Get("icon", &icon_path_); + } + opts.Get("silent", &silent_); + opts.Get("replyPlaceholder", &reply_placeholder_); + opts.Get("hasReply", &has_reply_); + } +} + +Notification::~Notification() { + if (notification_) + notification_->set_delegate(nullptr); +} + +// static +mate::WrappableBase* Notification::New(mate::Arguments* args) { + if (!Browser::Get()->is_ready()) { + args->ThrowError("Cannot create Notification before app is ready"); + return nullptr; + } + return new Notification(args->isolate(), args->GetThis(), args); +} + +// Getters +base::string16 Notification::GetTitle() { + return title_; +} + +base::string16 Notification::GetBody() { + return body_; +} + +bool Notification::GetSilent() { + return silent_; +} + +base::string16 Notification::GetReplyPlaceholder() { + return reply_placeholder_; +} + +bool Notification::GetHasReply() { + return has_reply_; +} + +// Setters +void Notification::SetTitle(const base::string16& new_title) { + title_ = new_title; +} + +void Notification::SetBody(const base::string16& new_body) { + body_ = new_body; +} + +void Notification::SetSilent(bool new_silent) { + silent_ = new_silent; +} + +void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) { + reply_placeholder_ = new_placeholder; +} + +void Notification::SetHasReply(bool new_has_reply) { + has_reply_ = new_has_reply; +} + +void Notification::NotificationClick() { + Emit("click"); +} + +void Notification::NotificationReplied(const std::string& reply) { + Emit("reply", reply); +} + +void Notification::NotificationDisplayed() { + Emit("show"); +} + +void Notification::NotificationDestroyed() { + Emit("close"); +} + +void Notification::NotificationClosed() { +} + +// Showing notifications +void Notification::Show() { + if (presenter_) { + notification_ = presenter_->CreateNotification(this); + if (notification_) { + notification_->Show(title_, body_, "", GURL(), icon_.AsBitmap(), silent_, + has_reply_, reply_placeholder_); + } + } +} + +bool Notification::IsSupported() { + return !!brightray::BrowserClient::Get()->GetNotificationPresenter(); +} + +// static +void Notification::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + prototype->SetClassName(mate::StringToV8(isolate, "Notification")); + mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + .MakeDestroyable() + .SetMethod("show", &Notification::Show) + .SetProperty("title", &Notification::GetTitle, &Notification::SetTitle) + .SetProperty("body", &Notification::GetBody, &Notification::SetBody) + .SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent) + .SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder, + &Notification::SetReplyPlaceholder) + .SetProperty("hasReply", &Notification::GetHasReply, + &Notification::SetHasReply); +} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::Notification; + +void Initialize(v8::Local exports, + v8::Local unused, + v8::Local context, + void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + Notification::SetConstructor(isolate, base::Bind(&Notification::New)); + + mate::Dictionary dict(isolate, exports); + dict.Set("Notification", + Notification::GetConstructor(isolate)->GetFunction()); + + dict.SetMethod("isSupported", &Notification::IsSupported); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_notification, Initialize) diff --git a/atom/browser/api/atom_api_notification.h b/atom/browser/api/atom_api_notification.h new file mode 100644 index 00000000000..9e1c47eeb74 --- /dev/null +++ b/atom/browser/api/atom_api_notification.h @@ -0,0 +1,83 @@ +// Copyright (c) 2014 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_ +#define ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_ + +#include +#include +#include + +#include "atom/browser/api/trackable_object.h" +#include "base/strings/utf_string_conversions.h" +#include "brightray/browser/notification.h" +#include "brightray/browser/notification_delegate.h" +#include "brightray/browser/notification_presenter.h" +#include "native_mate/handle.h" +#include "ui/gfx/image/image.h" + +namespace atom { + +namespace api { + +class Notification : public mate::TrackableObject, + public brightray::NotificationDelegate { + public: + static mate::WrappableBase* New(mate::Arguments* args); + static bool IsSupported(); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + // NotificationDelegate: + void NotificationClick() override; + void NotificationReplied(const std::string& reply) override; + void NotificationDisplayed() override; + void NotificationDestroyed() override; + void NotificationClosed() override; + + protected: + Notification(v8::Isolate* isolate, + v8::Local wrapper, + mate::Arguments* args); + ~Notification() override; + + void Show(); + + // Prop Getters + base::string16 GetTitle(); + base::string16 GetBody(); + bool GetSilent(); + base::string16 GetReplyPlaceholder(); + bool GetHasReply(); + + // Prop Setters + void SetTitle(const base::string16& new_title); + void SetBody(const base::string16& new_body); + void SetSilent(bool new_silent); + void SetReplyPlaceholder(const base::string16& new_reply_placeholder); + void SetHasReply(bool new_has_reply); + + private: + base::string16 title_; + base::string16 body_; + gfx::Image icon_; + base::string16 icon_path_; + bool has_icon_ = false; + bool silent_ = false; + base::string16 reply_placeholder_; + bool has_reply_ = false; + + brightray::NotificationPresenter* presenter_; + + base::WeakPtr notification_; + + DISALLOW_COPY_AND_ASSIGN(Notification); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_ diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 2a7be576276..03e96ae8a4f 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -56,6 +56,7 @@ REFERENCE_MODULE(atom_common_asar); REFERENCE_MODULE(atom_common_clipboard); REFERENCE_MODULE(atom_common_crash_reporter); REFERENCE_MODULE(atom_common_native_image); +REFERENCE_MODULE(atom_common_notification); REFERENCE_MODULE(atom_common_screen); REFERENCE_MODULE(atom_common_shell); REFERENCE_MODULE(atom_common_v8_util); diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc index 5aa3208dafc..26445aabded 100644 --- a/brightray/browser/browser_client.cc +++ b/brightray/browser/browser_client.cc @@ -36,7 +36,7 @@ BrowserClient::~BrowserClient() { NotificationPresenter* BrowserClient::GetNotificationPresenter() { if (!notification_presenter_) { - // Create a new presenter if on OS X, Linux, or Windows 8+ + // Create a new presenter if on OS X, Linux, or Windows 7+ notification_presenter_.reset(NotificationPresenter::Create()); } return notification_presenter_.get(); diff --git a/brightray/browser/linux/libnotify_notification.cc b/brightray/browser/linux/libnotify_notification.cc index 9706fbd3d69..ff3e6111010 100644 --- a/brightray/browser/linux/libnotify_notification.cc +++ b/brightray/browser/linux/libnotify_notification.cc @@ -88,7 +88,9 @@ void LibnotifyNotification::Show(const base::string16& title, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) { + bool silent, + bool has_reply, + const base::string16& reply_placeholder) { notification_ = libnotify_loader_.notify_notification_new( base::UTF16ToUTF8(title).c_str(), base::UTF16ToUTF8(body).c_str(), @@ -137,7 +139,8 @@ void LibnotifyNotification::Show(const base::string16& title, return; } - delegate()->NotificationDisplayed(); + if (delegate()) + delegate()->NotificationDisplayed(); } void LibnotifyNotification::Dismiss() { diff --git a/brightray/browser/linux/libnotify_notification.h b/brightray/browser/linux/libnotify_notification.h index b6163ae9b56..dbc34f27ae4 100644 --- a/brightray/browser/linux/libnotify_notification.h +++ b/brightray/browser/linux/libnotify_notification.h @@ -27,7 +27,9 @@ class LibnotifyNotification : public Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) override; + bool silent, + bool has_reply, + const base::string16& reply_placeholder) override; void Dismiss() override; private: diff --git a/brightray/browser/mac/cocoa_notification.h b/brightray/browser/mac/cocoa_notification.h index e95b490a70a..4e043dd7d8f 100644 --- a/brightray/browser/mac/cocoa_notification.h +++ b/brightray/browser/mac/cocoa_notification.h @@ -26,10 +26,13 @@ class CocoaNotification : public Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) override; + bool silent, + const bool has_reply, + const base::string16& reply_placeholder) override; void Dismiss() override; void NotificationDisplayed(); + void NotificationReplied(const std::string& reply); NSUserNotification* notification() const { return notification_; } diff --git a/brightray/browser/mac/cocoa_notification.mm b/brightray/browser/mac/cocoa_notification.mm index 354dc8d484b..5a16d40d1a7 100644 --- a/brightray/browser/mac/cocoa_notification.mm +++ b/brightray/browser/mac/cocoa_notification.mm @@ -28,7 +28,9 @@ void CocoaNotification::Show(const base::string16& title, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) { + bool silent, + bool has_reply, + const base::string16& reply_placeholder) { notification_.reset([[NSUserNotification alloc] init]); [notification_ setTitle:base::SysUTF16ToNSString(title)]; [notification_ setInformativeText:base::SysUTF16ToNSString(body)]; @@ -46,6 +48,11 @@ void CocoaNotification::Show(const base::string16& title, [notification_ setSoundName:NSUserNotificationDefaultSoundName]; } + if (has_reply) { + [notification_ setResponsePlaceholder:base::SysUTF16ToNSString(reply_placeholder)]; + [notification_ setHasReplyButton:true]; + } + [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification_]; } @@ -58,7 +65,13 @@ void CocoaNotification::Dismiss() { } void CocoaNotification::NotificationDisplayed() { - delegate()->NotificationDisplayed(); + if (delegate()) + delegate()->NotificationDisplayed(); +} + +void CocoaNotification::NotificationReplied(const std::string& reply) { + if (delegate()) + delegate()->NotificationReplied(reply); } } // namespace brightray diff --git a/brightray/browser/mac/notification_center_delegate.mm b/brightray/browser/mac/notification_center_delegate.mm index 42632cd8a9d..e0b4dfa0e8f 100644 --- a/brightray/browser/mac/notification_center_delegate.mm +++ b/brightray/browser/mac/notification_center_delegate.mm @@ -28,8 +28,13 @@ - (void)userNotificationCenter:(NSUserNotificationCenter*)center didActivateNotification:(NSUserNotification *)notif { auto notification = presenter_->GetNotification(notif); - if (notification) - notification->NotificationClicked(); + if (notification) { + if (notif.activationType == NSUserNotificationActivationTypeReplied){ + notification->NotificationReplied([notif.response.string UTF8String]); + } else { + notification->NotificationClicked(); + } + } } - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center diff --git a/brightray/browser/notification.cc b/brightray/browser/notification.cc index 8f7bef97947..2db8e5ce4fb 100644 --- a/brightray/browser/notification.cc +++ b/brightray/browser/notification.cc @@ -17,21 +17,25 @@ Notification::Notification(NotificationDelegate* delegate, } Notification::~Notification() { - delegate()->NotificationDestroyed(); + if (delegate()) + delegate()->NotificationDestroyed(); } void Notification::NotificationClicked() { - delegate()->NotificationClick(); + if (delegate()) + delegate()->NotificationClick(); Destroy(); } void Notification::NotificationDismissed() { - delegate()->NotificationClosed(); + if (delegate()) + delegate()->NotificationClosed(); Destroy(); } void Notification::NotificationFailed() { - delegate()->NotificationFailed(); + if (delegate()) + delegate()->NotificationFailed(); Destroy(); } diff --git a/brightray/browser/notification.h b/brightray/browser/notification.h index e59cab7a0cd..f5e00a23a9b 100644 --- a/brightray/browser/notification.h +++ b/brightray/browser/notification.h @@ -20,13 +20,17 @@ class NotificationPresenter; class Notification { public: + virtual ~Notification(); + // Shows the notification. virtual void Show(const base::string16& title, const base::string16& msg, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) = 0; + bool silent, + bool has_reply, + const base::string16& reply_placeholder) = 0; // Closes the notification, this instance will be destroyed after the // notification gets closed. virtual void Dismiss() = 0; @@ -43,6 +47,7 @@ class Notification { return weak_factory_.GetWeakPtr(); } + void set_delegate(NotificationDelegate* delegate) { delegate_ = delegate; } NotificationDelegate* delegate() const { return delegate_; } NotificationPresenter* presenter() const { return presenter_; } @@ -50,9 +55,6 @@ class Notification { Notification(NotificationDelegate* delegate, NotificationPresenter* presenter); - public: - virtual ~Notification(); - private: NotificationDelegate* delegate_; NotificationPresenter* presenter_; diff --git a/brightray/browser/notification_delegate.h b/brightray/browser/notification_delegate.h index c036b83bcfe..8493fdc3a5a 100644 --- a/brightray/browser/notification_delegate.h +++ b/brightray/browser/notification_delegate.h @@ -5,6 +5,8 @@ #ifndef BRIGHTRAY_BROWSER_NOTIFICATION_DELEGATE_H_ #define BRIGHTRAY_BROWSER_NOTIFICATION_DELEGATE_H_ +#include + #include "content/public/browser/desktop_notification_delegate.h" namespace brightray { @@ -16,6 +18,9 @@ class NotificationDelegate : public content::DesktopNotificationDelegate { // Failed to send the notification. virtual void NotificationFailed() {} + + // Notification was replied to + virtual void NotificationReplied(const std::string& reply) {} }; } // namespace brightray diff --git a/brightray/browser/platform_notification_service.cc b/brightray/browser/platform_notification_service.cc index 1c88a7461d5..964fa67f521 100644 --- a/brightray/browser/platform_notification_service.cc +++ b/brightray/browser/platform_notification_service.cc @@ -4,6 +4,7 @@ #include "brightray/browser/platform_notification_service.h" +#include "base/strings/utf_string_conversions.h" #include "brightray/browser/browser_client.h" #include "brightray/browser/notification.h" #include "brightray/browser/notification_delegate_adapter.h" @@ -30,7 +31,8 @@ void OnWebNotificationAllowed(base::WeakPtr notification, return; if (allowed) notification->Show(data.title, data.body, data.tag, data.icon, icon, - audio_muted ? true : data.silent); + audio_muted ? true : data.silent, false, + base::UTF8ToUTF16("")); else notification->Destroy(); } diff --git a/brightray/browser/win/win32_notification.cc b/brightray/browser/win/win32_notification.cc index 21e3b6ce8fa..ea3b35ab2c4 100644 --- a/brightray/browser/win/win32_notification.cc +++ b/brightray/browser/win/win32_notification.cc @@ -12,7 +12,8 @@ namespace brightray { void Win32Notification::Show( const base::string16& title, const base::string16& msg, const std::string& tag, const GURL& icon_url, - const SkBitmap& icon, const bool silent) { + const SkBitmap& icon, bool silent, + bool has_reply, const base::string16& reply_placeholder) { auto presenter = static_cast(this->presenter()); if (!presenter) return; diff --git a/brightray/browser/win/win32_notification.h b/brightray/browser/win/win32_notification.h index ce0ba3a0925..3ec6dfb17e5 100644 --- a/brightray/browser/win/win32_notification.h +++ b/brightray/browser/win/win32_notification.h @@ -12,7 +12,8 @@ class Win32Notification : public brightray::Notification { } void Show(const base::string16& title, const base::string16& msg, const std::string& tag, const GURL& icon_url, - const SkBitmap& icon, const bool silent) override; + const SkBitmap& icon, bool silent, + bool has_reply, const base::string16& reply_placeholder) override; void Dismiss() override; const DesktopNotificationController::Notification& GetRef() const { diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 5b5b7764ebd..335b2d924fd 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -89,7 +89,9 @@ void WindowsToastNotification::Show(const base::string16& title, const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) { + bool silent, + bool has_reply, + const base::string16& reply_placeholder) { auto presenter_win = static_cast(presenter()); std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url); @@ -131,7 +133,8 @@ void WindowsToastNotification::Show(const base::string16& title, return; } - delegate()->NotificationDisplayed(); + if (delegate()) + delegate()->NotificationDisplayed(); } void WindowsToastNotification::Dismiss() { @@ -144,7 +147,7 @@ bool WindowsToastNotification::GetToastXml( const std::wstring& title, const std::wstring& msg, const std::wstring& icon_path, - const bool silent, + bool silent, IXmlDocument** toast_xml) { ABI::Windows::UI::Notifications::ToastTemplateType template_type; if (title.empty() || msg.empty()) { diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index b36a5cc3797..0b96f43c34f 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -55,7 +55,9 @@ class WindowsToastNotification : public Notification { const std::string& tag, const GURL& icon_url, const SkBitmap& icon, - const bool silent) override; + bool silent, + bool has_reply, + const base::string16& reply_placeholder) override; void Dismiss() override; private: diff --git a/docs/api/notification.md b/docs/api/notification.md new file mode 100644 index 00000000000..01bb12a34a9 --- /dev/null +++ b/docs/api/notification.md @@ -0,0 +1,95 @@ +# Notification + +> Create OS desktop notifications + +Process: [Main](../glossary.md#main-process) + +## Using in the renderer process + +If you want to show Notifications from a renderer process you should use the [HTML5 Notification API](../tutorial/notifications.md) + +## Class: Notification + +> Create OS desktop notifications + +Process: [Main](../glossary.md#main-process) + +`Notification` is an +[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). + +It creates a new `Notification` with native properties as set by the `options`. + +### Static Methods + +The `Notification` class has the following static methods: + +#### `BrowserWindow.isSupported()` + +Returns `Boolean` - Whether or not desktop notifications are supported on the current system + +### `new Notification([options])` _Experimental_ + +* `options` Object + * `title` String - A title for the notification, which will be shown at the top of the notification window when it is shown + * `body` String - The body text of the notification, which will be displayed below the title + * `silent` Boolean - (Optional) Whether or not to emit an OS notification noise when showing the notification + * `icon` [NativeImage](native-image.md) - (Optional) An icon to use in the notification + * `hasReply` Boolean - (Optional) Whether or not to add an inline reply option to the notification. _macOS_ + * `replyPlaceholder` String - (Optional) The placeholder to write in the inline reply input field. _macOS_ + + +### Instance Events + +Objects created with `new Notification` emit the following events: + +**Note:** Some events are only available on specific operating systems and are +labeled as such. + +#### Event: 'show' + +Returns: + +* `event` Event + +Emitted when the notification is shown to the user, note this could be fired +multiple times as a notification can be shown multiple times through the +`show()` method. + +#### Event: 'click' + +Returns: + +* `event` Event + +Emitted when the notification is clicked by the user. + +#### Event: 'close' + +Returns: + +* `event` Event + +Emitted when the notification is closed by manual intervention from the user. + +This event is not guarunteed to be emitted in all cases where the notification +is closed. + +#### Event: 'reply' _macOS_ + +Returns: + +* `event` Event +* `reply` String - The string the user entered into the inline reply field + +Emitted when the user clicks the "Reply" button on a notification with `hasReply: true`. + +### Instance Methods + +Objects created with `new Notification` have the following instance methods: + +#### `notification.show()` + +Immediately shows the notification to the user, please note this means unlike the +HTML5 Notification implementation, simply instantiating a `new Notification` does +not immediately show it to the user, you need to call this method before the OS +will display it. diff --git a/docs/tutorial/notifications.md b/docs/tutorial/notifications.md index 34c64ad9bb4..2ded823f917 100644 --- a/docs/tutorial/notifications.md +++ b/docs/tutorial/notifications.md @@ -5,7 +5,9 @@ to the user. Electron conveniently allows developers to send notifications with the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. -**Note:** Since this is an HTML5 API it is only available in the renderer process. +**Note:** Since this is an HTML5 API it is only available in the renderer process. If +you want to show Notifications in the main process please check out the +[Notification](../api/notification.md) module. ```javascript let myNotification = new Notification('Title', { diff --git a/filenames.gypi b/filenames.gypi index f3e9eb06b35..86c27b9ae9a 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -26,6 +26,7 @@ 'lib/browser/api/module-list.js', 'lib/browser/api/navigation-controller.js', 'lib/browser/api/net.js', + 'lib/browser/api/notification.js', 'lib/browser/api/power-monitor.js', 'lib/browser/api/power-save-blocker.js', 'lib/browser/api/protocol.js', @@ -127,6 +128,8 @@ 'atom/browser/api/atom_api_menu_views.h', 'atom/browser/api/atom_api_net.cc', 'atom/browser/api/atom_api_net.h', + 'atom/browser/api/atom_api_notification.cc', + 'atom/browser/api/atom_api_notification.h', 'atom/browser/api/atom_api_power_monitor.cc', 'atom/browser/api/atom_api_power_monitor.h', 'atom/browser/api/atom_api_power_save_blocker.cc', diff --git a/lib/browser/api/module-list.js b/lib/browser/api/module-list.js index 64b2829064b..d8b20c5bec1 100644 --- a/lib/browser/api/module-list.js +++ b/lib/browser/api/module-list.js @@ -11,6 +11,7 @@ module.exports = [ {name: 'Menu', file: 'menu'}, {name: 'MenuItem', file: 'menu-item'}, {name: 'net', file: 'net'}, + {name: 'Notification', file: 'notification'}, {name: 'powerMonitor', file: 'power-monitor'}, {name: 'powerSaveBlocker', file: 'power-save-blocker'}, {name: 'protocol', file: 'protocol'}, diff --git a/lib/browser/api/notification.js b/lib/browser/api/notification.js new file mode 100644 index 00000000000..d9885ae2aa2 --- /dev/null +++ b/lib/browser/api/notification.js @@ -0,0 +1,8 @@ +const {EventEmitter} = require('events') +const {Notification, isSupported} = process.atomBinding('notification') + +Object.setPrototypeOf(Notification.prototype, EventEmitter.prototype) + +Notification.isSupported = isSupported + +module.exports = Notification