From b55d2b53df9385f5db9987a8eb98ad06a11d69ec Mon Sep 17 00:00:00 2001 From: Ivanq Date: Wed, 17 Apr 2019 12:39:00 +0300 Subject: [PATCH 1/4] Support Notification API --- src/Ui/UiWebsocket.py | 2 + src/Ui/media/Wrapper.coffee | 34 +++++++++++++ src/Ui/media/all.js | 95 ++++++++++++++++++++++++++++++++----- 3 files changed, 120 insertions(+), 11 deletions(-) diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py index af3657d8..ba84f3a3 100644 --- a/src/Ui/UiWebsocket.py +++ b/src/Ui/UiWebsocket.py @@ -868,6 +868,8 @@ class UiWebsocket(object): self.response(to, _["Modify your client's configuration and access all site"] + " " + _["(Dangerous!)"] + "") elif permission == "NOSANDBOX": self.response(to, _["Modify your client's configuration and access all site"] + " " + _["(Dangerous!)"] + "") + elif permission == "PushNotification": + self.response(to, _["Send notifications"]) else: self.response(to, "") diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee index 599d95f8..c14b08cc 100644 --- a/src/Ui/media/Wrapper.coffee +++ b/src/Ui/media/Wrapper.coffee @@ -190,6 +190,8 @@ class Wrapper @actionPermissionAdd(message) else if cmd == "wrapperRequestFullscreen" @actionRequestFullscreen() + else if cmd == "wrapperPushNotification" + @actionPushNotification(message) else # Send to websocket if message.id < 1000000 if message.cmd == "fileWrite" and not @modified_panel_updater_timer and site_info?.settings?.own @@ -236,6 +238,38 @@ class Wrapper request_fullscreen = elem.requestFullScreen || elem.webkitRequestFullscreen || elem.mozRequestFullScreen || elem.msRequestFullScreen request_fullscreen.call(elem) + actionPushNotification: (message) -> + $.when(@event_site_info).done => + # Check that this site may send notifications + if "PushNotifications" not in @site_info.settings.permissions + res = {"error": "No PushNotifications permission"} + @sendInner {"cmd": "response", "to": message.id, "result": res} + return + # Check that the wrapper may send notifications + if Notification.permission == "granted" + @displayPushNotification message + else if Notification.permission == "denied" + res = {"error": "Push notifications are disabled by the user"} + @sendInner {"cmd": "response", "to": message.id, "result": res} + else + Notification.requestPermission().then (permission) => + if permission == "granted" + @displayPushNotification message + + displayPushNotification: (message) -> + title = message.params[0] + id = message.params[1] + options = message.params[2] + notification = new Notification(title, options) + notification.onshow = () => + @sendInner {"cmd": "response", "to": message.id, "result": "ok"} + notification.onclick = (e) => + if not options.focus_tab + e.preventDefault() + @sendInner {"cmd": "pushNotificationClick", "params": {"id": id}} + notification.onclose = () => + @sendInner {"cmd": "pushNotificationClose", "params": {"id": id}} + actionPermissionAdd: (message) -> permission = message.params $.when(@event_site_info).done => diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js index 4b59cf8f..60278c4d 100644 --- a/src/Ui/media/all.js +++ b/src/Ui/media/all.js @@ -34,7 +34,6 @@ }).call(this); - /* ---- src/Ui/media/lib/Translate.coffee ---- */ @@ -45,7 +44,6 @@ }).call(this); - /* ---- src/Ui/media/lib/ZeroWebsocket.coffee ---- */ @@ -201,7 +199,6 @@ }).call(this); - /* ---- src/Ui/media/lib/jquery.cssanim.js ---- */ @@ -307,7 +304,6 @@ if (window.getComputedStyle(document.body).transform) { }).call(this); - /* ---- src/Ui/media/lib/jquery.easing.js ---- */ @@ -535,7 +531,6 @@ $.extend( $.easing, }).call(this); - /* ---- src/Ui/media/Infopanel.coffee ---- */ @@ -626,7 +621,6 @@ $.extend( $.easing, }).call(this); - /* ---- src/Ui/media/Loading.coffee ---- */ @@ -773,7 +767,6 @@ $.extend( $.easing, }).call(this); - /* ---- src/Ui/media/Notifications.coffee ---- */ @@ -908,7 +901,6 @@ $.extend( $.easing, }).call(this); - /* ---- src/Ui/media/Wrapper.coffee ---- */ @@ -1171,6 +1163,8 @@ $.extend( $.easing, return this.actionPermissionAdd(message); } else if (cmd === "wrapperRequestFullscreen") { return this.actionRequestFullscreen(); + } else if (cmd === "wrapperPushNotification") { + return this.actionPushNotification(message); } else { if (message.id < 1000000) { if (message.cmd === "fileWrite" && !this.modified_panel_updater_timer && (typeof site_info !== "undefined" && site_info !== null ? (ref = site_info.settings) != null ? ref.own : void 0 : void 0)) { @@ -1239,6 +1233,83 @@ $.extend( $.easing, return request_fullscreen.call(elem); }; + Wrapper.prototype.actionPushNotification = function(message) { + return $.when(this.event_site_info).done((function(_this) { + return function() { + var res; + if (indexOf.call(_this.site_info.settings.permissions, "PushNotifications") < 0) { + res = { + "error": "No PushNotifications permission" + }; + _this.sendInner({ + "cmd": "response", + "to": message.id, + "result": res + }); + return; + } + if (Notification.permission === "granted") { + return _this.displayPushNotification(message); + } else if (Notification.permission === "denied") { + res = { + "error": "Push notifications are disabled by the user" + }; + return _this.sendInner({ + "cmd": "response", + "to": message.id, + "result": res + }); + } else { + return Notification.requestPermission().then(function(permission) { + if (permission === "granted") { + return _this.displayPushNotification(message); + } + }); + } + }; + })(this)); + }; + + Wrapper.prototype.displayPushNotification = function(message) { + var id, notification, options, title; + title = message.params[0]; + id = message.params[1]; + options = message.params[2]; + notification = new Notification(title, options); + notification.onshow = (function(_this) { + return function() { + return _this.sendInner({ + "cmd": "response", + "to": message.id, + "result": "ok" + }); + }; + })(this); + notification.onclick = (function(_this) { + return function(e) { + if (!options.focus_tab) { + e.preventDefault(); + } + return _this.sendInner({ + "cmd": "pushNotificationClick", + "params": { + "id": id + } + }); + }; + })(this); + return notification.onclose = (function(_this) { + return function() { + return _this.sendInner({ + "cmd": "pushNotificationClose", + "params": { + "id": id + } + }); + }; + })(this); + }; + Wrapper.prototype.actionPermissionAdd = function(message) { var permission; permission = message.params; @@ -1328,9 +1399,11 @@ $.extend( $.easing, Wrapper.prototype.displayPrompt = function(message, type, caption, placeholder, cb) { var body, button, input; body = $("").html(message); - if (placeholder == null) { + if (placeholder != null) { + placeholder; + } else { placeholder = ""; - } + }; input = $("", { type: type, "class": "input button-" + type, @@ -1946,4 +2019,4 @@ $.extend( $.easing, window.zeroframe = new WrapperZeroFrame(window.wrapper); -}).call(this); +}).call(this); \ No newline at end of file From e618c0e9ef6ddcdae3556cd6269dc011206c5f70 Mon Sep 17 00:00:00 2001 From: Ivanq Date: Wed, 17 Apr 2019 19:56:19 +0300 Subject: [PATCH 2/4] Add closePushNotification --- src/Ui/media/Wrapper.coffee | 15 +++++++++++++++ src/Ui/media/all.js | 28 +++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee index c14b08cc..6da1410c 100644 --- a/src/Ui/media/Wrapper.coffee +++ b/src/Ui/media/Wrapper.coffee @@ -33,6 +33,7 @@ class Wrapper @address = null @opener_tested = false @announcer_line = null + @push_notifications = {} @allowed_event_constructors = [window.MouseEvent, window.KeyboardEvent, window.PointerEvent] # Allowed event constructors @@ -192,6 +193,8 @@ class Wrapper @actionRequestFullscreen() else if cmd == "wrapperPushNotification" @actionPushNotification(message) + else if cmd == "wrapperClosePushNotification" + @actionClosePushNotification(message) else # Send to websocket if message.id < 1000000 if message.cmd == "fileWrite" and not @modified_panel_updater_timer and site_info?.settings?.own @@ -256,11 +259,22 @@ class Wrapper if permission == "granted" @displayPushNotification message + actionClosePushNotification: (message) -> + $.when(@event_site_info).done => + # Check that this site may send notifications + if "PushNotifications" not in @site_info.settings.permissions + res = {"error": "No PushNotifications permission"} + @sendInner {"cmd": "response", "to": message.id, "result": res} + return + id = message.params[0] + @push_notifications[id].close() + displayPushNotification: (message) -> title = message.params[0] id = message.params[1] options = message.params[2] notification = new Notification(title, options) + @push_notifications[id] = notification notification.onshow = () => @sendInner {"cmd": "response", "to": message.id, "result": "ok"} notification.onclick = (e) => @@ -269,6 +283,7 @@ class Wrapper @sendInner {"cmd": "pushNotificationClick", "params": {"id": id}} notification.onclose = () => @sendInner {"cmd": "pushNotificationClose", "params": {"id": id}} + delete @push_notifications[id] actionPermissionAdd: (message) -> permission = message.params diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js index 60278c4d..7ba3a780 100644 --- a/src/Ui/media/all.js +++ b/src/Ui/media/all.js @@ -961,6 +961,7 @@ $.extend( $.easing, this.address = null; this.opener_tested = false; this.announcer_line = null; + this.push_notifications = {}; this.allowed_event_constructors = [window.MouseEvent, window.KeyboardEvent, window.PointerEvent]; window.onload = this.onPageLoad; window.onhashchange = (function(_this) { @@ -1165,6 +1166,8 @@ $.extend( $.easing, return this.actionRequestFullscreen(); } else if (cmd === "wrapperPushNotification") { return this.actionPushNotification(message); + } else if (cmd === "wrapperClosePushNotification") { + return this.actionClosePushNotification(message); } else { if (message.id < 1000000) { if (message.cmd === "fileWrite" && !this.modified_panel_updater_timer && (typeof site_info !== "undefined" && site_info !== null ? (ref = site_info.settings) != null ? ref.own : void 0 : void 0)) { @@ -1270,12 +1273,34 @@ $.extend( $.easing, })(this)); }; + Wrapper.prototype.actionClosePushNotification = function(message) { + return $.when(this.event_site_info).done((function(_this) { + return function() { + var id, res; + if (indexOf.call(_this.site_info.settings.permissions, "PushNotifications") < 0) { + res = { + "error": "No PushNotifications permission" + }; + _this.sendInner({ + "cmd": "response", + "to": message.id, + "result": res + }); + return; + } + id = message.params[0]; + return _this.push_notifications[id].close(); + }; + })(this)); + }; + Wrapper.prototype.displayPushNotification = function(message) { var id, notification, options, title; title = message.params[0]; id = message.params[1]; options = message.params[2]; notification = new Notification(title, options); + this.push_notifications[id] = notification; notification.onshow = (function(_this) { return function() { return _this.sendInner({ @@ -1300,12 +1325,13 @@ $.extend( $.easing, })(this); return notification.onclose = (function(_this) { return function() { - return _this.sendInner({ + _this.sendInner({ "cmd": "pushNotificationClose", "params": { "id": id } }); + return delete _this.push_notifications[id]; }; })(this); }; From 9ddb984004cb5c6bcedde5cb3553dccab129e4a3 Mon Sep 17 00:00:00 2001 From: Ivanq Date: Fri, 19 Apr 2019 19:08:49 +0300 Subject: [PATCH 3/4] Rename Push notifications to Web notifications --- src/Ui/media/Wrapper.coffee | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee index 6da1410c..496737ca 100644 --- a/src/Ui/media/Wrapper.coffee +++ b/src/Ui/media/Wrapper.coffee @@ -33,7 +33,7 @@ class Wrapper @address = null @opener_tested = false @announcer_line = null - @push_notifications = {} + @web_notifications = {} @allowed_event_constructors = [window.MouseEvent, window.KeyboardEvent, window.PointerEvent] # Allowed event constructors @@ -191,10 +191,10 @@ class Wrapper @actionPermissionAdd(message) else if cmd == "wrapperRequestFullscreen" @actionRequestFullscreen() - else if cmd == "wrapperPushNotification" - @actionPushNotification(message) - else if cmd == "wrapperClosePushNotification" - @actionClosePushNotification(message) + else if cmd == "wrapperWebNotification" + @actionWebNotification(message) + else if cmd == "wrapperCloseWebNotification" + @actionCloseWebNotification(message) else # Send to websocket if message.id < 1000000 if message.cmd == "fileWrite" and not @modified_panel_updater_timer and site_info?.settings?.own @@ -241,49 +241,49 @@ class Wrapper request_fullscreen = elem.requestFullScreen || elem.webkitRequestFullscreen || elem.mozRequestFullScreen || elem.msRequestFullScreen request_fullscreen.call(elem) - actionPushNotification: (message) -> + actionWebNotification: (message) -> $.when(@event_site_info).done => # Check that this site may send notifications - if "PushNotifications" not in @site_info.settings.permissions - res = {"error": "No PushNotifications permission"} + if "WebNotifications" not in @site_info.settings.permissions + res = {"error": "No WebNotifications permission"} @sendInner {"cmd": "response", "to": message.id, "result": res} return # Check that the wrapper may send notifications if Notification.permission == "granted" - @displayPushNotification message + @displayWebNotification message else if Notification.permission == "denied" - res = {"error": "Push notifications are disabled by the user"} + res = {"error": "Web notifications are disabled by the user"} @sendInner {"cmd": "response", "to": message.id, "result": res} else Notification.requestPermission().then (permission) => if permission == "granted" - @displayPushNotification message + @displayWebNotification message - actionClosePushNotification: (message) -> + actionCloseWebNotification: (message) -> $.when(@event_site_info).done => # Check that this site may send notifications - if "PushNotifications" not in @site_info.settings.permissions - res = {"error": "No PushNotifications permission"} + if "WebNotifications" not in @site_info.settings.permissions + res = {"error": "No WebNotifications permission"} @sendInner {"cmd": "response", "to": message.id, "result": res} return id = message.params[0] - @push_notifications[id].close() + @web_notifications[id].close() - displayPushNotification: (message) -> + displayWebNotification: (message) -> title = message.params[0] id = message.params[1] options = message.params[2] notification = new Notification(title, options) - @push_notifications[id] = notification + @web_notifications[id] = notification notification.onshow = () => @sendInner {"cmd": "response", "to": message.id, "result": "ok"} notification.onclick = (e) => if not options.focus_tab e.preventDefault() - @sendInner {"cmd": "pushNotificationClick", "params": {"id": id}} + @sendInner {"cmd": "webNotificationClick", "params": {"id": id}} notification.onclose = () => - @sendInner {"cmd": "pushNotificationClose", "params": {"id": id}} - delete @push_notifications[id] + @sendInner {"cmd": "webNotificationClose", "params": {"id": id}} + delete @web_notifications[id] actionPermissionAdd: (message) -> permission = message.params From 6e58e8d50f8c94f53dfc596383017b122524a41a Mon Sep 17 00:00:00 2001 From: Ivanq Date: Fri, 26 Apr 2019 12:55:33 +0300 Subject: [PATCH 4/4] Don't require WebNotifications permission --- src/Ui/media/Wrapper.coffee | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee index 496737ca..247f4f6a 100644 --- a/src/Ui/media/Wrapper.coffee +++ b/src/Ui/media/Wrapper.coffee @@ -243,11 +243,6 @@ class Wrapper actionWebNotification: (message) -> $.when(@event_site_info).done => - # Check that this site may send notifications - if "WebNotifications" not in @site_info.settings.permissions - res = {"error": "No WebNotifications permission"} - @sendInner {"cmd": "response", "to": message.id, "result": res} - return # Check that the wrapper may send notifications if Notification.permission == "granted" @displayWebNotification message @@ -261,11 +256,6 @@ class Wrapper actionCloseWebNotification: (message) -> $.when(@event_site_info).done => - # Check that this site may send notifications - if "WebNotifications" not in @site_info.settings.permissions - res = {"error": "No WebNotifications permission"} - @sendInner {"cmd": "response", "to": message.id, "result": res} - return id = message.params[0] @web_notifications[id].close()