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..247f4f6a 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 + @web_notifications = {} @allowed_event_constructors = [window.MouseEvent, window.KeyboardEvent, window.PointerEvent] # Allowed event constructors @@ -190,6 +191,10 @@ class Wrapper @actionPermissionAdd(message) else if cmd == "wrapperRequestFullscreen" @actionRequestFullscreen() + 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 @@ -236,6 +241,40 @@ class Wrapper request_fullscreen = elem.requestFullScreen || elem.webkitRequestFullscreen || elem.mozRequestFullScreen || elem.msRequestFullScreen request_fullscreen.call(elem) + actionWebNotification: (message) -> + $.when(@event_site_info).done => + # Check that the wrapper may send notifications + if Notification.permission == "granted" + @displayWebNotification message + else if Notification.permission == "denied" + 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" + @displayWebNotification message + + actionCloseWebNotification: (message) -> + $.when(@event_site_info).done => + id = message.params[0] + @web_notifications[id].close() + + displayWebNotification: (message) -> + title = message.params[0] + id = message.params[1] + options = message.params[2] + notification = new Notification(title, options) + @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": "webNotificationClick", "params": {"id": id}} + notification.onclose = () => + @sendInner {"cmd": "webNotificationClose", "params": {"id": id}} + delete @web_notifications[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..7ba3a780 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 ---- */ @@ -969,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) { @@ -1171,6 +1164,10 @@ $.extend( $.easing, return this.actionPermissionAdd(message); } else if (cmd === "wrapperRequestFullscreen") { 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)) { @@ -1239,6 +1236,106 @@ $.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.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({ + "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() { + _this.sendInner({ + "cmd": "pushNotificationClose", + "params": { + "id": id + } + }); + return delete _this.push_notifications[id]; + }; + })(this); + }; + Wrapper.prototype.actionPermissionAdd = function(message) { var permission; permission = message.params; @@ -1328,9 +1425,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 +2045,4 @@ $.extend( $.easing, window.zeroframe = new WrapperZeroFrame(window.wrapper); -}).call(this); +}).call(this); \ No newline at end of file