annotate sat_templates/templates/default/static/websocket.js @ 229:739c3e6999fa

base: `scripts` variable can be used to create suitable tags + new `body_onload` variable
author Goffi <goffi@goffi.org>
date Sun, 26 Apr 2020 22:06:07 +0200
parents e9f0a4215e46
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
84
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 /*
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 SàT templates: suit of templates for Salut à Toi
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 Copyright (C) 2017 Jérôme Poisson (goffi@goffi.org)
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 it under the terms of the GNU Affero General Public License as published by
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 the Free Software Foundation, either version 3 of the License, or
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 (at your option) any later version.
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 GNU Affero General Public License for more details.
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 You should have received a copy of the GNU Affero General Public License
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 */
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 /* websocket handler */
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 //TODO: retry websocket instead of reload
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 function WSHandler(url, token, debug=false) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 var socket = new WebSocket(url, 'libervia_page_' + token );
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 var retried = 0;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 var errorHandler = function(error) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 if (retried > 20) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 console.error("Too many tries, can't start websocket");
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 alert("Dynamic connection with server can't be established, please try to reload this page in a while or contact your service administrator");
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 return;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 var delay = Math.floor((Math.random() * 10) + 1) + 30 * Math.min(retried, 6);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 notifyRetry(delay, function() {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 retried++;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 socket = new WebSocket(url, 'libervia_page_' + token );
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 socket.addEventListener('error', errorHandler);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 });
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 };
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 socket.addEventListener('error', errorHandler);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 if (debug) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 socket.addEventListener('message', function(event) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 console.log('WS in <== ', JSON.parse(event.data));
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 });
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 socket.addEventListener('message', function(event) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 try {data = JSON.parse(event.data);}
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 catch (e) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 console.warn('invalid websocket message received: %s', e);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 return;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 switch (data.type) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 case 'reload':
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 location.reload(true);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 break;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 case 'dom':
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 selected_element = document.body.querySelector(data.selectors);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 switch (data.update_type) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 case 'append':
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 var template = document.createElement('template');
127
27d6453a6209 js (websocket): fixed parsing of new HTML
Goffi <goffi@goffi.org>
parents: 84
diff changeset
64 template.innerHTML = data.html.trim();
84
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 new_element = template.content.firstChild;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 selected_element.appendChild(new_element);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 break;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 default:
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 console.warn('Unknown DOM update type: %s', data.update_type);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 break;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 default:
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 console.warn('Unknown data type: %s', data.type);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 });
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 socket.addEventListener('open', function (event) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 console.log('Websocket opened');
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 retried = 0;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 }.bind(this));
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
81
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 this.send = function(data) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 if (debug) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 console.log('WS out ==> ', data);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 socket.send(JSON.stringify(data));
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 };
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 function notifyRetry(timeout, retryCb) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 /* Show a notification dialog informing the user that server can't be reach
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 * and call retryCb after timeout seconds.
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 * A "retry now" link allows to retry immediately"
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 *
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 * @param timeout(int): delay before retrying, in seconds
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 * @param retryCb(function): function to call when retrying
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 */
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 var startTime = Date.now() / 1000;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 var retryIntervalID;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 var notif = document.createElement("div");
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 notif.setAttribute('class', 'notification retry');
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 //FIXME: we use English without translation for now, must be changed when we can use gettext in Libervia pages
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 notif.innerHTML = "<p>Can't reach the server, retrying in <span id='retry_counter'></span> seconds</p><p><a id='retry_now'>retry now</a></p>";
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 document.body.appendChild(notif);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 var retryCounter = document.getElementById('retry_counter');
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 retryCounter.textContent = timeout;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
106
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 var retry = function () {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 clearInterval(retryIntervalID);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 notif.parentNode.removeChild(notif);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 retryCb();
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 };
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
112
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 var updateTimer = function () {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 var elapsed = Math.floor(Date.now() / 1000 - startTime);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 var remaining = timeout - elapsed;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 if (remaining < 0) {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 retry();
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 else {
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 retryCounter.textContent = remaining;
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 };
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 var retryNow = document.getElementById('retry_now');
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 retryNow.addEventListener('click', function(){
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 retry();
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 });
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
128
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 retryIntervalID = setInterval(updateTimer, 1000);
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 }
b2ef34e602cf base, js (websocket), css (main style): dynamic pages implementation, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 }