1
|
=== modified file 'src/com/goldencode/p2j/main/WebClientSpawner.java'
|
2
|
--- src/com/goldencode/p2j/main/WebClientSpawner.java 2016-02-26 19:00:09 +0000
|
3
|
+++ src/com/goldencode/p2j/main/WebClientSpawner.java 2016-02-29 23:57:02 +0000
|
4
|
@@ -143,7 +143,7 @@
|
5
|
|
6
|
if (token != null)
|
7
|
{
|
8
|
- uri = uri + "?" + PARAM_TOKEN + "=" + token;
|
9
|
+ uri = uri + "index.html?" + PARAM_TOKEN + "=" + token;
|
10
|
}
|
11
|
}
|
12
|
}
|
13
|
|
14
|
=== modified file 'src/com/goldencode/p2j/ui/client/chui/driver/web/ChuiWebDriver.java'
|
15
|
--- src/com/goldencode/p2j/ui/client/chui/driver/web/ChuiWebDriver.java 2015-08-21 08:03:12 +0000
|
16
|
+++ src/com/goldencode/p2j/ui/client/chui/driver/web/ChuiWebDriver.java 2016-03-01 00:05:35 +0000
|
17
|
@@ -99,10 +99,9 @@
|
18
|
String welcomeUrl = getWelcomePageUrl(MAIN_TARGET, WELCOME_PAGE);
|
19
|
|
20
|
// create our handlers
|
21
|
- ChuiWebPageHandler[] hdlrs = new ChuiWebPageHandler[2];
|
22
|
+ ChuiWebPageHandler[] hdlrs = new ChuiWebPageHandler[1];
|
23
|
|
24
|
- hdlrs[0] = new ChuiWebPageHandler(config, MAIN_TARGET, welcomeUrl);
|
25
|
- hdlrs[1] = new ChuiWebPageHandler(config, WELCOME_PAGE, welcomeUrl);
|
26
|
+ hdlrs[0] = new ChuiWebPageHandler(config, WELCOME_PAGE, welcomeUrl);
|
27
|
|
28
|
WebClientProtocol websock = simulator.getWebSocket();
|
29
|
|
30
|
|
31
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/WebClientProtocol.java'
|
32
|
--- src/com/goldencode/p2j/ui/client/driver/web/WebClientProtocol.java 2016-02-24 22:48:55 +0000
|
33
|
+++ src/com/goldencode/p2j/ui/client/driver/web/WebClientProtocol.java 2016-03-01 00:00:23 +0000
|
34
|
@@ -379,6 +379,11 @@
|
35
|
sendBinaryMessage(MSG_PING_PONG);
|
36
|
handled = true;
|
37
|
}
|
38
|
+ else if (message[offset] == MSG_QUIT && length == 1)
|
39
|
+ {
|
40
|
+ // exit the client session
|
41
|
+ System.exit(0);
|
42
|
+ }
|
43
|
|
44
|
return handled;
|
45
|
}
|
46
|
|
47
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.js'
|
48
|
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.js 2016-01-04 15:02:23 +0000
|
49
|
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.js 2016-02-29 22:32:55 +0000
|
50
|
@@ -221,6 +221,94 @@
|
51
|
return canvas;
|
52
|
};
|
53
|
|
54
|
+ /**
|
55
|
+ * Save the target JS object serialized to a string value with the given key.
|
56
|
+ *
|
57
|
+ * @param {String} key
|
58
|
+ * The assigned key.
|
59
|
+ * @param {Object} obj
|
60
|
+ * The target JS object.
|
61
|
+ * @param {Boolean} local
|
62
|
+ * True value indicates that the object is persisted between opened and new sessions,
|
63
|
+ * otherwise the object is stored during the current session.
|
64
|
+ */
|
65
|
+ function saveObject(key, obj, local)
|
66
|
+ {
|
67
|
+ var sObj = JSON.stringify(obj);
|
68
|
+ var storage;
|
69
|
+ if (local)
|
70
|
+ {
|
71
|
+ storage = localStorage;
|
72
|
+ }
|
73
|
+ else
|
74
|
+ {
|
75
|
+ storage = sessionStorage;
|
76
|
+ }
|
77
|
+ storage.setItem(key, sObj);
|
78
|
+ return sObj;
|
79
|
+ }
|
80
|
+
|
81
|
+ me.saveObject = saveObject;
|
82
|
+
|
83
|
+ /**
|
84
|
+ * Try to restore a JS object from the retrieved string value for the given key.
|
85
|
+ *
|
86
|
+ * @param {String} key
|
87
|
+ * The provided key.
|
88
|
+ * @param {Boolean} local
|
89
|
+ * True value indicates that the local storage is used, otherwise the session
|
90
|
+ * storage is used.
|
91
|
+ *
|
92
|
+ * @return {Object} obj
|
93
|
+ * The target JS object or null.
|
94
|
+ */
|
95
|
+ function restoreObject(key, local)
|
96
|
+ {
|
97
|
+ var storage;
|
98
|
+ if (local)
|
99
|
+ {
|
100
|
+ storage = localStorage;
|
101
|
+ }
|
102
|
+ else
|
103
|
+ {
|
104
|
+ storage = sessionStorage;
|
105
|
+ }
|
106
|
+ var sObj = storage.getItem(key);
|
107
|
+ if (sObj)
|
108
|
+ {
|
109
|
+ var obj = JSON.parse(sObj);
|
110
|
+ return obj;
|
111
|
+ }
|
112
|
+ return null;
|
113
|
+ }
|
114
|
+
|
115
|
+ me.restoreObject = restoreObject;
|
116
|
+
|
117
|
+ /**
|
118
|
+ * Delete a JS object by the given key.
|
119
|
+ *
|
120
|
+ * @param {String} key
|
121
|
+ * The provided key.
|
122
|
+ * @param {Boolean} local
|
123
|
+ * True value indicates that the local storage is used, otherwise the session
|
124
|
+ * storage is used.
|
125
|
+ */
|
126
|
+ function deleteObject(key, local)
|
127
|
+ {
|
128
|
+ var storage;
|
129
|
+ if (local)
|
130
|
+ {
|
131
|
+ storage = localStorage;
|
132
|
+ }
|
133
|
+ else
|
134
|
+ {
|
135
|
+ storage = sessionStorage;
|
136
|
+ }
|
137
|
+ storage.removeItem(key);
|
138
|
+ }
|
139
|
+
|
140
|
+ me.deleteObject = deleteObject;
|
141
|
+
|
142
|
/* exports */
|
143
|
return me;
|
144
|
}());
|
145
|
|
146
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js'
|
147
|
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js 2016-02-25 05:44:49 +0000
|
148
|
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js 2016-03-01 00:12:31 +0000
|
149
|
@@ -42,7 +42,9 @@
|
150
|
** available for the browser.
|
151
|
** CA 20160629 Added a drawing cache (and cache management, when the hash was expired by the
|
152
|
** client-side).
|
153
|
-** SBI 20160225 Implemented MSG_PARTIAL, added MSG_PING_PONG and idle/connectivity timers.
|
154
|
+** SBI 20160225 Implemented MSG_PARTIAL, added MSG_PING_PONG and idle/connectivity timers,
|
155
|
+** added the default "Stay on page or Leave page" dialog if a user tries to close
|
156
|
+** or to refresh the web application page.
|
157
|
*/
|
158
|
|
159
|
"use strict";
|
160
|
@@ -92,6 +94,12 @@
|
161
|
var pingPongWatcher;
|
162
|
|
163
|
/**
|
164
|
+ * True value indicates the web page can be closed or redirected to the login page without
|
165
|
+ * the appearance of the default "stay on page or leave page" warning dialog.
|
166
|
+ */
|
167
|
+ var exitTheApplication = false;
|
168
|
+
|
169
|
+ /**
|
170
|
* The next unique message id.
|
171
|
*/
|
172
|
var nextMsgId = 0;
|
173
|
@@ -666,7 +674,7 @@
|
174
|
break;
|
175
|
case 0x85:
|
176
|
// quit
|
177
|
- window.location.replace(referrer);
|
178
|
+ doRedirectToLoginPage();
|
179
|
break;
|
180
|
case 0x86:
|
181
|
// switch mode p2j/vt100
|
182
|
@@ -1241,7 +1249,7 @@
|
183
|
{
|
184
|
kill();
|
185
|
}
|
186
|
- if (elapsed > period)
|
187
|
+ else if (elapsed > period)
|
188
|
{
|
189
|
callback();
|
190
|
}
|
191
|
@@ -1296,6 +1304,16 @@
|
192
|
}
|
193
|
|
194
|
this.kill = kill;
|
195
|
+
|
196
|
+ /**
|
197
|
+ * Tests if the timer is running.
|
198
|
+ *
|
199
|
+ * @return True if the timer is running, otherwise false.
|
200
|
+ */
|
201
|
+ this.isRunning = function()
|
202
|
+ {
|
203
|
+ return running;
|
204
|
+ }
|
205
|
}
|
206
|
|
207
|
/**
|
208
|
@@ -1321,11 +1339,31 @@
|
209
|
connected = true;
|
210
|
ws.binaryType = 'arraybuffer';
|
211
|
|
212
|
- connectivityTimer.kill();
|
213
|
- idleTimer.start();
|
214
|
-
|
215
|
- // notify the web socket has opened and the page is loaded
|
216
|
- me.sendNotification(0xff);
|
217
|
+ var exit = p2j.restoreObject("exitTheApplication", false);
|
218
|
+ var date = (new Date()).getTime();
|
219
|
+ // reload use case
|
220
|
+ if (exit && (date < exit.date + 1000))
|
221
|
+ {
|
222
|
+ // reload use case
|
223
|
+ doRedirectToLoginPage();
|
224
|
+ me.sendNotification(0x85);
|
225
|
+ }
|
226
|
+ else
|
227
|
+ {
|
228
|
+ if (exit)
|
229
|
+ {
|
230
|
+ // reopen use case
|
231
|
+ p2j.deleteObject("exitTheApplication", false);
|
232
|
+ }
|
233
|
+
|
234
|
+ exitTheApplication = false;
|
235
|
+
|
236
|
+ connectivityTimer.kill();
|
237
|
+ idleTimer.start();
|
238
|
+
|
239
|
+ // notify the web socket has opened and the page is loaded
|
240
|
+ me.sendNotification(0xff);
|
241
|
+ }
|
242
|
};
|
243
|
|
244
|
// on web socket message
|
245
|
@@ -1380,7 +1418,7 @@
|
246
|
// check the normal close reason
|
247
|
if (evt.code === 1000)
|
248
|
{
|
249
|
- setTimeout(function() { window.location.replace(referrer); }, 1000);
|
250
|
+ doRedirectToLoginPage();
|
251
|
}
|
252
|
else
|
253
|
{
|
254
|
@@ -1389,20 +1427,48 @@
|
255
|
};
|
256
|
|
257
|
/**
|
258
|
- * Web socket errors events handler
|
259
|
+ * Web socket errors events handler.
|
260
|
*
|
261
|
* @param {Event} evt
|
262
|
* The websocket error event
|
263
|
*/
|
264
|
ws.onerror = function(evt)
|
265
|
{
|
266
|
+ p2j.screen.error("Web socket error " + evt.detail);
|
267
|
connected = false;
|
268
|
idleTimer.kill();
|
269
|
- connectivityTimer.start();
|
270
|
+
|
271
|
+ if (exitTheApplication)
|
272
|
+ {
|
273
|
+ if (!connectivityTimer.isRunning())
|
274
|
+ {
|
275
|
+ // the reconnect tries are failed the websocket server is down due to the watchdog.
|
276
|
+ doRedirectToLoginPage();
|
277
|
+ }
|
278
|
+ }
|
279
|
+ else
|
280
|
+ {
|
281
|
+ if (!connectivityTimer.isRunning())
|
282
|
+ {
|
283
|
+ // try to reconnect within watchdog timeout if it is failed, then
|
284
|
+ // the websocket server is down
|
285
|
+ connectivityTimer.start();
|
286
|
+ exitTheApplication = true;
|
287
|
+ }
|
288
|
+ }
|
289
|
};
|
290
|
}
|
291
|
|
292
|
/**
|
293
|
+ * Force the web page to be redirected to the login page given by the referrer url.
|
294
|
+ */
|
295
|
+ function doRedirectToLoginPage()
|
296
|
+ {
|
297
|
+ exitTheApplication = true;
|
298
|
+ setTimeout(function() { window.location.replace(referrer); }, 1000);
|
299
|
+ }
|
300
|
+
|
301
|
+ /**
|
302
|
* Initialize module.
|
303
|
*
|
304
|
* @param {object} cfg configuration.
|
305
|
@@ -1451,6 +1517,10 @@
|
306
|
*/
|
307
|
function connect()
|
308
|
{
|
309
|
+ if (pingPongWatcher)
|
310
|
+ {
|
311
|
+ clearTimeout(pingPongWatcher);
|
312
|
+ }
|
313
|
// don't reconnect if the websocket state is CONNECTING(0) or OPEN(1) or CLOSING(2)
|
314
|
if (ws && ws.readyState !== 3)
|
315
|
{
|
316
|
@@ -1463,21 +1533,53 @@
|
317
|
|
318
|
connectivityTimer = new ControlTimer(Math.max(watchdogTimeout, maxIdleTime), 5000, connect);
|
319
|
|
320
|
- // TODO: offline mode
|
321
|
- window.addEventListener(
|
322
|
- "offline",
|
323
|
- function(e)
|
324
|
- {
|
325
|
- console.debug("offline");
|
326
|
- connectivityTimer.start();
|
327
|
- }, false);
|
328
|
+ /**
|
329
|
+ * If the user is navigating away from the application webpage.
|
330
|
+ *
|
331
|
+ * @param {PageTransitionEvent} evt
|
332
|
+ *
|
333
|
+ */
|
334
|
+ window.onpagehide = function(evt)
|
335
|
+ {
|
336
|
+ if (!exitTheApplication)
|
337
|
+ {
|
338
|
+ // close or reload cases
|
339
|
+ exitTheApplication = true;
|
340
|
+ p2j.saveObject(
|
341
|
+ "exitTheApplication",
|
342
|
+ {
|
343
|
+ exitTheApplication : exitTheApplication,
|
344
|
+ date: (new Date()).getTime()
|
345
|
+ },
|
346
|
+ false);
|
347
|
+ }
|
348
|
+ else
|
349
|
+ {
|
350
|
+ // after reload
|
351
|
+ p2j.deleteObject("exitTheApplication", false);
|
352
|
+ }
|
353
|
+ };
|
354
|
|
355
|
- // TODO: refresh
|
356
|
- window.onpagehide = function()
|
357
|
+ /**
|
358
|
+ * Occurs when the web application page are about to be unloaded.
|
359
|
+ *
|
360
|
+ * @param {Event} evt
|
361
|
+ * The beforeunload event.
|
362
|
+ *
|
363
|
+ * @return {String}
|
364
|
+ * The returned value will be used as a custom message for the default
|
365
|
+ * "Stay on Page or Leave Page" dialog.
|
366
|
+ */
|
367
|
+ window.onbeforeunload = function(evt)
|
368
|
{
|
369
|
- if (connected)
|
370
|
+ if (!exitTheApplication)
|
371
|
{
|
372
|
- ws.close();
|
373
|
+ var confirmationMessage = "Do you confirm to logout the P2J application?";
|
374
|
+
|
375
|
+ // Gecko + IE
|
376
|
+ (evt || window.event).returnValue = confirmationMessage;
|
377
|
+
|
378
|
+ return confirmationMessage;
|
379
|
}
|
380
|
};
|
381
|
|
382
|
|
383
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java'
|
384
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java 2016-02-05 08:56:45 +0000
|
385
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java 2016-02-29 14:35:25 +0000
|
386
|
@@ -216,10 +216,9 @@
|
387
|
String welcomeUrl = getWelcomePageUrl(MAIN_TARGET, WELCOME_PAGE);
|
388
|
|
389
|
// create our handlers
|
390
|
- GuiWebPageHandler[] hdlrs = new GuiWebPageHandler[2];
|
391
|
+ GuiWebPageHandler[] hdlrs = new GuiWebPageHandler[1];
|
392
|
|
393
|
- hdlrs[0] = new GuiWebPageHandler(config, MAIN_TARGET, welcomeUrl);
|
394
|
- hdlrs[1] = new GuiWebPageHandler(config, WELCOME_PAGE, welcomeUrl);
|
395
|
+ hdlrs[0] = new GuiWebPageHandler(config, WELCOME_PAGE, welcomeUrl);
|
396
|
|
397
|
// create our web socket
|
398
|
websock = new GuiWebSocket(lock, this, timeout, wdtimeout);
|
399
|
|
400
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js'
|
401
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js 2016-02-19 18:04:59 +0000
|
402
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js 2016-02-28 13:01:11 +0000
|
403
|
@@ -326,7 +326,7 @@
|
404
|
|
405
|
if (cachedDraw == undefined)
|
406
|
{
|
407
|
- me.error("Trying to draw unknown cached image for md5 " + md5 + "!");
|
408
|
+ p2j.screen.error("Trying to draw unknown cached image for md5 " + md5 + "!");
|
409
|
console.trace();
|
410
|
return;
|
411
|
}
|
412
|
|