novnc-rails 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +0 -0
  3. data/LICENSE.txt +0 -0
  4. data/README.md +0 -0
  5. data/lib/novnc-rails.rb +8 -0
  6. data/lib/novnc-rails/version.rb +5 -0
  7. data/vendor/assets/javascripts/noVNC/Orbitron700.ttf +0 -0
  8. data/vendor/assets/javascripts/noVNC/Orbitron700.woff +0 -0
  9. data/vendor/assets/javascripts/noVNC/base.css +512 -0
  10. data/vendor/assets/javascripts/noVNC/base64.js +113 -0
  11. data/vendor/assets/javascripts/noVNC/black.css +71 -0
  12. data/vendor/assets/javascripts/noVNC/blue.css +64 -0
  13. data/vendor/assets/javascripts/noVNC/des.js +276 -0
  14. data/vendor/assets/javascripts/noVNC/display.js +751 -0
  15. data/vendor/assets/javascripts/noVNC/input.js +388 -0
  16. data/vendor/assets/javascripts/noVNC/jsunzip.js +676 -0
  17. data/vendor/assets/javascripts/noVNC/keyboard.js +543 -0
  18. data/vendor/assets/javascripts/noVNC/keysym.js +378 -0
  19. data/vendor/assets/javascripts/noVNC/keysymdef.js +15 -0
  20. data/vendor/assets/javascripts/noVNC/logo.js +1 -0
  21. data/vendor/assets/javascripts/noVNC/playback.js +102 -0
  22. data/vendor/assets/javascripts/noVNC/rfb.js +1889 -0
  23. data/vendor/assets/javascripts/noVNC/ui.js +979 -0
  24. data/vendor/assets/javascripts/noVNC/util.js +656 -0
  25. data/vendor/assets/javascripts/noVNC/web-socket-js/README.txt +109 -0
  26. data/vendor/assets/javascripts/noVNC/web-socket-js/WebSocketMain.swf +0 -0
  27. data/vendor/assets/javascripts/noVNC/web-socket-js/swfobject.js +4 -0
  28. data/vendor/assets/javascripts/noVNC/web-socket-js/web_socket.js +391 -0
  29. data/vendor/assets/javascripts/noVNC/websock.js +388 -0
  30. data/vendor/assets/javascripts/noVNC/webutil.js +239 -0
  31. metadata +86 -0
@@ -0,0 +1,979 @@
1
+ /*
2
+ * noVNC: HTML5 VNC client
3
+ * Copyright (C) 2012 Joel Martin
4
+ * Copyright (C) 2013 Samuel Mannehed for Cendio AB
5
+ * Licensed under MPL 2.0 (see LICENSE.txt)
6
+ *
7
+ * See README.md for usage and integration instructions.
8
+ */
9
+
10
+ /* jslint white: false, browser: true */
11
+ /* global window, $D, Util, WebUtil, RFB, Display */
12
+
13
+ var UI;
14
+
15
+ (function () {
16
+ "use strict";
17
+
18
+ // Load supporting scripts
19
+ window.onscriptsload = function () { UI.load(); };
20
+ window.onload = function () { UI.keyboardinputReset(); };
21
+ Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
22
+ "keysymdef.js", "keyboard.js", "input.js", "display.js",
23
+ "jsunzip.js", "rfb.js", "keysym.js"]);
24
+
25
+ UI = {
26
+
27
+ rfb_state : 'loaded',
28
+ settingsOpen : false,
29
+ connSettingsOpen : false,
30
+ popupStatusOpen : false,
31
+ clipboardOpen: false,
32
+ keyboardVisible: false,
33
+ hideKeyboardTimeout: null,
34
+ lastKeyboardinput: null,
35
+ defaultKeyboardinputLen: 100,
36
+ extraKeysVisible: false,
37
+ ctrlOn: false,
38
+ altOn: false,
39
+ isTouchDevice: false,
40
+
41
+ // Setup rfb object, load settings from browser storage, then call
42
+ // UI.init to setup the UI/menus
43
+ load: function (callback) {
44
+ WebUtil.initSettings(UI.start, callback);
45
+ },
46
+
47
+ // Render default UI and initialize settings menu
48
+ start: function(callback) {
49
+ UI.isTouchDevice = 'ontouchstart' in document.documentElement;
50
+
51
+ // Stylesheet selection dropdown
52
+ var sheet = WebUtil.selectStylesheet();
53
+ var sheets = WebUtil.getStylesheets();
54
+ var i;
55
+ for (i = 0; i < sheets.length; i += 1) {
56
+ UI.addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title);
57
+ }
58
+
59
+ // Logging selection dropdown
60
+ var llevels = ['error', 'warn', 'info', 'debug'];
61
+ for (i = 0; i < llevels.length; i += 1) {
62
+ UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]);
63
+ }
64
+
65
+ // Settings with immediate effects
66
+ UI.initSetting('logging', 'warn');
67
+ WebUtil.init_logging(UI.getSetting('logging'));
68
+
69
+ UI.initSetting('stylesheet', 'default');
70
+ WebUtil.selectStylesheet(null);
71
+ // call twice to get around webkit bug
72
+ WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
73
+
74
+ // if port == 80 (or 443) then it won't be present and should be
75
+ // set manually
76
+ var port = window.location.port;
77
+ if (!port) {
78
+ if (window.location.protocol.substring(0,5) == 'https') {
79
+ port = 443;
80
+ }
81
+ else if (window.location.protocol.substring(0,4) == 'http') {
82
+ port = 80;
83
+ }
84
+ }
85
+
86
+ /* Populate the controls if defaults are provided in the URL */
87
+ UI.initSetting('host', window.location.hostname);
88
+ UI.initSetting('port', port);
89
+ UI.initSetting('password', '');
90
+ UI.initSetting('encrypt', (window.location.protocol === "https:"));
91
+ UI.initSetting('true_color', true);
92
+ UI.initSetting('cursor', !UI.isTouchDevice);
93
+ UI.initSetting('shared', true);
94
+ UI.initSetting('view_only', false);
95
+ UI.initSetting('path', 'websockify');
96
+ UI.initSetting('repeaterID', '');
97
+
98
+ UI.rfb = new RFB({'target': $D('noVNC_canvas'),
99
+ 'onUpdateState': UI.updateState,
100
+ 'onXvpInit': UI.updateXvpVisualState,
101
+ 'onClipboard': UI.clipReceive,
102
+ 'onDesktopName': UI.updateDocumentTitle});
103
+
104
+ var autoconnect = WebUtil.getQueryVar('autoconnect', false);
105
+ if (autoconnect === 'true' || autoconnect == '1') {
106
+ autoconnect = true;
107
+ UI.connect();
108
+ } else {
109
+ autoconnect = false;
110
+ }
111
+
112
+ UI.updateVisualState();
113
+
114
+ // Show mouse selector buttons on touch screen devices
115
+ if (UI.isTouchDevice) {
116
+ // Show mobile buttons
117
+ $D('noVNC_mobile_buttons').style.display = "inline";
118
+ UI.setMouseButton();
119
+ // Remove the address bar
120
+ setTimeout(function() { window.scrollTo(0, 1); }, 100);
121
+ UI.forceSetting('clip', true);
122
+ $D('noVNC_clip').disabled = true;
123
+ } else {
124
+ UI.initSetting('clip', false);
125
+ }
126
+
127
+ //iOS Safari does not support CSS position:fixed.
128
+ //This detects iOS devices and enables javascript workaround.
129
+ if ((navigator.userAgent.match(/iPhone/i)) ||
130
+ (navigator.userAgent.match(/iPod/i)) ||
131
+ (navigator.userAgent.match(/iPad/i))) {
132
+ //UI.setOnscroll();
133
+ //UI.setResize();
134
+ }
135
+ UI.setBarPosition();
136
+
137
+ $D('noVNC_host').focus();
138
+
139
+ UI.setViewClip();
140
+ Util.addEvent(window, 'resize', UI.setViewClip);
141
+
142
+ Util.addEvent(window, 'beforeunload', function () {
143
+ if (UI.rfb_state === 'normal') {
144
+ return "You are currently connected.";
145
+ }
146
+ } );
147
+
148
+ // Show description by default when hosted at for kanaka.github.com
149
+ if (location.host === "kanaka.github.io") {
150
+ // Open the description dialog
151
+ $D('noVNC_description').style.display = "block";
152
+ } else {
153
+ // Show the connect panel on first load unless autoconnecting
154
+ if (autoconnect === UI.connSettingsOpen) {
155
+ UI.toggleConnectPanel();
156
+ }
157
+ }
158
+
159
+ // Add mouse event click/focus/blur event handlers to the UI
160
+ UI.addMouseHandlers();
161
+
162
+ if (typeof callback === "function") {
163
+ callback(UI.rfb);
164
+ }
165
+ },
166
+
167
+ addMouseHandlers: function() {
168
+ // Setup interface handlers that can't be inline
169
+ $D("noVNC_view_drag_button").onclick = UI.setViewDrag;
170
+ $D("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); };
171
+ $D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); };
172
+ $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
173
+ $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
174
+ $D("showKeyboard").onclick = UI.showKeyboard;
175
+
176
+ $D("keyboardinput").oninput = UI.keyInput;
177
+ $D("keyboardinput").onblur = UI.keyInputBlur;
178
+
179
+ $D("showExtraKeysButton").onclick = UI.showExtraKeys;
180
+ $D("toggleCtrlButton").onclick = UI.toggleCtrl;
181
+ $D("toggleAltButton").onclick = UI.toggleAlt;
182
+ $D("sendTabButton").onclick = UI.sendTab;
183
+ $D("sendEscButton").onclick = UI.sendEsc;
184
+
185
+ $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel;
186
+ $D("xvpShutdownButton").onclick = UI.xvpShutdown;
187
+ $D("xvpRebootButton").onclick = UI.xvpReboot;
188
+ $D("xvpResetButton").onclick = UI.xvpReset;
189
+ $D("noVNC_status").onclick = UI.togglePopupStatusPanel;
190
+ $D("noVNC_popup_status_panel").onclick = UI.togglePopupStatusPanel;
191
+ $D("xvpButton").onclick = UI.toggleXvpPanel;
192
+ $D("clipboardButton").onclick = UI.toggleClipboardPanel;
193
+ $D("settingsButton").onclick = UI.toggleSettingsPanel;
194
+ $D("connectButton").onclick = UI.toggleConnectPanel;
195
+ $D("disconnectButton").onclick = UI.disconnect;
196
+ $D("descriptionButton").onclick = UI.toggleConnectPanel;
197
+
198
+ $D("noVNC_clipboard_text").onfocus = UI.displayBlur;
199
+ $D("noVNC_clipboard_text").onblur = UI.displayFocus;
200
+ $D("noVNC_clipboard_text").onchange = UI.clipSend;
201
+ $D("noVNC_clipboard_clear_button").onclick = UI.clipClear;
202
+
203
+ $D("noVNC_settings_menu").onmouseover = UI.displayBlur;
204
+ $D("noVNC_settings_menu").onmouseover = UI.displayFocus;
205
+ $D("noVNC_apply").onclick = UI.settingsApply;
206
+
207
+ $D("noVNC_connect_button").onclick = UI.connect;
208
+ },
209
+
210
+ // Read form control compatible setting from cookie
211
+ getSetting: function(name) {
212
+ var ctrl = $D('noVNC_' + name);
213
+ var val = WebUtil.readSetting(name);
214
+ if (val !== null && ctrl.type === 'checkbox') {
215
+ if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) {
216
+ val = false;
217
+ } else {
218
+ val = true;
219
+ }
220
+ }
221
+ return val;
222
+ },
223
+
224
+ // Update cookie and form control setting. If value is not set, then
225
+ // updates from control to current cookie setting.
226
+ updateSetting: function(name, value) {
227
+
228
+ // Save the cookie for this session
229
+ if (typeof value !== 'undefined') {
230
+ WebUtil.writeSetting(name, value);
231
+ }
232
+
233
+ // Update the settings control
234
+ value = UI.getSetting(name);
235
+
236
+ var ctrl = $D('noVNC_' + name);
237
+ if (ctrl.type === 'checkbox') {
238
+ ctrl.checked = value;
239
+
240
+ } else if (typeof ctrl.options !== 'undefined') {
241
+ for (var i = 0; i < ctrl.options.length; i += 1) {
242
+ if (ctrl.options[i].value === value) {
243
+ ctrl.selectedIndex = i;
244
+ break;
245
+ }
246
+ }
247
+ } else {
248
+ /*Weird IE9 error leads to 'null' appearring
249
+ in textboxes instead of ''.*/
250
+ if (value === null) {
251
+ value = "";
252
+ }
253
+ ctrl.value = value;
254
+ }
255
+ },
256
+
257
+ // Save control setting to cookie
258
+ saveSetting: function(name) {
259
+ var val, ctrl = $D('noVNC_' + name);
260
+ if (ctrl.type === 'checkbox') {
261
+ val = ctrl.checked;
262
+ } else if (typeof ctrl.options !== 'undefined') {
263
+ val = ctrl.options[ctrl.selectedIndex].value;
264
+ } else {
265
+ val = ctrl.value;
266
+ }
267
+ WebUtil.writeSetting(name, val);
268
+ //Util.Debug("Setting saved '" + name + "=" + val + "'");
269
+ return val;
270
+ },
271
+
272
+ // Initial page load read/initialization of settings
273
+ initSetting: function(name, defVal) {
274
+ // Check Query string followed by cookie
275
+ var val = WebUtil.getQueryVar(name);
276
+ if (val === null) {
277
+ val = WebUtil.readSetting(name, defVal);
278
+ }
279
+ UI.updateSetting(name, val);
280
+ return val;
281
+ },
282
+
283
+ // Force a setting to be a certain value
284
+ forceSetting: function(name, val) {
285
+ UI.updateSetting(name, val);
286
+ return val;
287
+ },
288
+
289
+
290
+ // Show the popup status panel
291
+ togglePopupStatusPanel: function() {
292
+ var psp = $D('noVNC_popup_status_panel');
293
+ if (UI.popupStatusOpen === true) {
294
+ psp.style.display = "none";
295
+ UI.popupStatusOpen = false;
296
+ } else {
297
+ psp.innerHTML = $D('noVNC_status').innerHTML;
298
+ psp.style.display = "block";
299
+ psp.style.left = window.innerWidth/2 -
300
+ parseInt(window.getComputedStyle(psp, false).width)/2 -30 + "px";
301
+ UI.popupStatusOpen = true;
302
+ }
303
+ },
304
+
305
+ // Show the XVP panel
306
+ toggleXvpPanel: function() {
307
+ // Close the description panel
308
+ $D('noVNC_description').style.display = "none";
309
+ // Close settings if open
310
+ if (UI.settingsOpen === true) {
311
+ UI.settingsApply();
312
+ UI.closeSettingsMenu();
313
+ }
314
+ // Close connection settings if open
315
+ if (UI.connSettingsOpen === true) {
316
+ UI.toggleConnectPanel();
317
+ }
318
+ // Close popup status panel if open
319
+ if (UI.popupStatusOpen === true) {
320
+ UI.togglePopupStatusPanel();
321
+ }
322
+ // Close clipboard panel if open
323
+ if (UI.clipboardOpen === true) {
324
+ UI.toggleClipboardPanel();
325
+ }
326
+ // Toggle XVP panel
327
+ if (UI.xvpOpen === true) {
328
+ $D('noVNC_xvp').style.display = "none";
329
+ $D('xvpButton').className = "noVNC_status_button";
330
+ UI.xvpOpen = false;
331
+ } else {
332
+ $D('noVNC_xvp').style.display = "block";
333
+ $D('xvpButton').className = "noVNC_status_button_selected";
334
+ UI.xvpOpen = true;
335
+ }
336
+ },
337
+
338
+ // Show the clipboard panel
339
+ toggleClipboardPanel: function() {
340
+ // Close the description panel
341
+ $D('noVNC_description').style.display = "none";
342
+ // Close settings if open
343
+ if (UI.settingsOpen === true) {
344
+ UI.settingsApply();
345
+ UI.closeSettingsMenu();
346
+ }
347
+ // Close connection settings if open
348
+ if (UI.connSettingsOpen === true) {
349
+ UI.toggleConnectPanel();
350
+ }
351
+ // Close popup status panel if open
352
+ if (UI.popupStatusOpen === true) {
353
+ UI.togglePopupStatusPanel();
354
+ }
355
+ // Close XVP panel if open
356
+ if (UI.xvpOpen === true) {
357
+ UI.toggleXvpPanel();
358
+ }
359
+ // Toggle Clipboard Panel
360
+ if (UI.clipboardOpen === true) {
361
+ $D('noVNC_clipboard').style.display = "none";
362
+ $D('clipboardButton').className = "noVNC_status_button";
363
+ UI.clipboardOpen = false;
364
+ } else {
365
+ $D('noVNC_clipboard').style.display = "block";
366
+ $D('clipboardButton').className = "noVNC_status_button_selected";
367
+ UI.clipboardOpen = true;
368
+ }
369
+ },
370
+
371
+ // Show the connection settings panel/menu
372
+ toggleConnectPanel: function() {
373
+ // Close the description panel
374
+ $D('noVNC_description').style.display = "none";
375
+ // Close connection settings if open
376
+ if (UI.settingsOpen === true) {
377
+ UI.settingsApply();
378
+ UI.closeSettingsMenu();
379
+ $D('connectButton').className = "noVNC_status_button";
380
+ }
381
+ // Close clipboard panel if open
382
+ if (UI.clipboardOpen === true) {
383
+ UI.toggleClipboardPanel();
384
+ }
385
+ // Close popup status panel if open
386
+ if (UI.popupStatusOpen === true) {
387
+ UI.togglePopupStatusPanel();
388
+ }
389
+ // Close XVP panel if open
390
+ if (UI.xvpOpen === true) {
391
+ UI.toggleXvpPanel();
392
+ }
393
+
394
+ // Toggle Connection Panel
395
+ if (UI.connSettingsOpen === true) {
396
+ $D('noVNC_controls').style.display = "none";
397
+ $D('connectButton').className = "noVNC_status_button";
398
+ UI.connSettingsOpen = false;
399
+ UI.saveSetting('host');
400
+ UI.saveSetting('port');
401
+ //UI.saveSetting('password');
402
+ } else {
403
+ $D('noVNC_controls').style.display = "block";
404
+ $D('connectButton').className = "noVNC_status_button_selected";
405
+ UI.connSettingsOpen = true;
406
+ $D('noVNC_host').focus();
407
+ }
408
+ },
409
+
410
+ // Toggle the settings menu:
411
+ // On open, settings are refreshed from saved cookies.
412
+ // On close, settings are applied
413
+ toggleSettingsPanel: function() {
414
+ // Close the description panel
415
+ $D('noVNC_description').style.display = "none";
416
+ if (UI.settingsOpen) {
417
+ UI.settingsApply();
418
+ UI.closeSettingsMenu();
419
+ } else {
420
+ UI.updateSetting('encrypt');
421
+ UI.updateSetting('true_color');
422
+ if (UI.rfb.get_display().get_cursor_uri()) {
423
+ UI.updateSetting('cursor');
424
+ } else {
425
+ UI.updateSetting('cursor', !UI.isTouchDevice);
426
+ $D('noVNC_cursor').disabled = true;
427
+ }
428
+ UI.updateSetting('clip');
429
+ UI.updateSetting('shared');
430
+ UI.updateSetting('view_only');
431
+ UI.updateSetting('path');
432
+ UI.updateSetting('repeaterID');
433
+ UI.updateSetting('stylesheet');
434
+ UI.updateSetting('logging');
435
+
436
+ UI.openSettingsMenu();
437
+ }
438
+ },
439
+
440
+ // Open menu
441
+ openSettingsMenu: function() {
442
+ // Close the description panel
443
+ $D('noVNC_description').style.display = "none";
444
+ // Close clipboard panel if open
445
+ if (UI.clipboardOpen === true) {
446
+ UI.toggleClipboardPanel();
447
+ }
448
+ // Close connection settings if open
449
+ if (UI.connSettingsOpen === true) {
450
+ UI.toggleConnectPanel();
451
+ }
452
+ // Close popup status panel if open
453
+ if (UI.popupStatusOpen === true) {
454
+ UI.togglePopupStatusPanel();
455
+ }
456
+ // Close XVP panel if open
457
+ if (UI.xvpOpen === true) {
458
+ UI.toggleXvpPanel();
459
+ }
460
+ $D('noVNC_settings').style.display = "block";
461
+ $D('settingsButton').className = "noVNC_status_button_selected";
462
+ UI.settingsOpen = true;
463
+ },
464
+
465
+ // Close menu (without applying settings)
466
+ closeSettingsMenu: function() {
467
+ $D('noVNC_settings').style.display = "none";
468
+ $D('settingsButton').className = "noVNC_status_button";
469
+ UI.settingsOpen = false;
470
+ },
471
+
472
+ // Save/apply settings when 'Apply' button is pressed
473
+ settingsApply: function() {
474
+ //Util.Debug(">> settingsApply");
475
+ UI.saveSetting('encrypt');
476
+ UI.saveSetting('true_color');
477
+ if (UI.rfb.get_display().get_cursor_uri()) {
478
+ UI.saveSetting('cursor');
479
+ }
480
+ UI.saveSetting('clip');
481
+ UI.saveSetting('shared');
482
+ UI.saveSetting('view_only');
483
+ UI.saveSetting('path');
484
+ UI.saveSetting('repeaterID');
485
+ UI.saveSetting('stylesheet');
486
+ UI.saveSetting('logging');
487
+
488
+ // Settings with immediate (non-connected related) effect
489
+ WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
490
+ WebUtil.init_logging(UI.getSetting('logging'));
491
+ UI.setViewClip();
492
+ UI.setViewDrag(UI.rfb.get_viewportDrag());
493
+ //Util.Debug("<< settingsApply");
494
+ },
495
+
496
+
497
+
498
+ setPassword: function() {
499
+ UI.rfb.sendPassword($D('noVNC_password').value);
500
+ //Reset connect button.
501
+ $D('noVNC_connect_button').value = "Connect";
502
+ $D('noVNC_connect_button').onclick = UI.Connect;
503
+ //Hide connection panel.
504
+ UI.toggleConnectPanel();
505
+ return false;
506
+ },
507
+
508
+ sendCtrlAltDel: function() {
509
+ UI.rfb.sendCtrlAltDel();
510
+ },
511
+
512
+ xvpShutdown: function() {
513
+ UI.rfb.xvpShutdown();
514
+ },
515
+
516
+ xvpReboot: function() {
517
+ UI.rfb.xvpReboot();
518
+ },
519
+
520
+ xvpReset: function() {
521
+ UI.rfb.xvpReset();
522
+ },
523
+
524
+ setMouseButton: function(num) {
525
+ if (typeof num === 'undefined') {
526
+ // Disable mouse buttons
527
+ num = -1;
528
+ }
529
+ if (UI.rfb) {
530
+ UI.rfb.get_mouse().set_touchButton(num);
531
+ }
532
+
533
+ var blist = [0, 1,2,4];
534
+ for (var b = 0; b < blist.length; b++) {
535
+ var button = $D('noVNC_mouse_button' + blist[b]);
536
+ if (blist[b] === num) {
537
+ button.style.display = "";
538
+ } else {
539
+ button.style.display = "none";
540
+ }
541
+ }
542
+ },
543
+
544
+ updateState: function(rfb, state, oldstate, msg) {
545
+ UI.rfb_state = state;
546
+ var klass;
547
+ switch (state) {
548
+ case 'failed':
549
+ case 'fatal':
550
+ klass = "noVNC_status_error";
551
+ break;
552
+ case 'normal':
553
+ klass = "noVNC_status_normal";
554
+ break;
555
+ case 'disconnected':
556
+ $D('noVNC_logo').style.display = "block";
557
+ /* falls through */
558
+ case 'loaded':
559
+ klass = "noVNC_status_normal";
560
+ break;
561
+ case 'password':
562
+ UI.toggleConnectPanel();
563
+
564
+ $D('noVNC_connect_button').value = "Send Password";
565
+ $D('noVNC_connect_button').onclick = UI.setPassword;
566
+ $D('noVNC_password').focus();
567
+
568
+ klass = "noVNC_status_warn";
569
+ break;
570
+ default:
571
+ klass = "noVNC_status_warn";
572
+ break;
573
+ }
574
+
575
+ if (typeof(msg) !== 'undefined') {
576
+ $D('noVNC-control-bar').setAttribute("class", klass);
577
+ $D('noVNC_status').innerHTML = msg;
578
+ }
579
+
580
+ UI.updateVisualState();
581
+ },
582
+
583
+ // Disable/enable controls depending on connection state
584
+ updateVisualState: function() {
585
+ var connected = UI.rfb_state === 'normal' ? true : false;
586
+
587
+ //Util.Debug(">> updateVisualState");
588
+ $D('noVNC_encrypt').disabled = connected;
589
+ $D('noVNC_true_color').disabled = connected;
590
+ if (UI.rfb && UI.rfb.get_display() &&
591
+ UI.rfb.get_display().get_cursor_uri()) {
592
+ $D('noVNC_cursor').disabled = connected;
593
+ } else {
594
+ UI.updateSetting('cursor', !UI.isTouchDevice);
595
+ $D('noVNC_cursor').disabled = true;
596
+ }
597
+ $D('noVNC_shared').disabled = connected;
598
+ $D('noVNC_view_only').disabled = connected;
599
+ $D('noVNC_path').disabled = connected;
600
+ $D('noVNC_repeaterID').disabled = connected;
601
+
602
+ if (connected) {
603
+ UI.setViewClip();
604
+ UI.setMouseButton(1);
605
+ $D('clipboardButton').style.display = "inline";
606
+ $D('showKeyboard').style.display = "inline";
607
+ $D('noVNC_extra_keys').style.display = "";
608
+ $D('sendCtrlAltDelButton').style.display = "inline";
609
+ } else {
610
+ UI.setMouseButton();
611
+ $D('clipboardButton').style.display = "none";
612
+ $D('showKeyboard').style.display = "none";
613
+ $D('noVNC_extra_keys').style.display = "none";
614
+ $D('sendCtrlAltDelButton').style.display = "none";
615
+ UI.updateXvpVisualState(0);
616
+ }
617
+
618
+ // State change disables viewport dragging.
619
+ // It is enabled (toggled) by direct click on the button
620
+ UI.setViewDrag(false);
621
+
622
+ switch (UI.rfb_state) {
623
+ case 'fatal':
624
+ case 'failed':
625
+ case 'loaded':
626
+ case 'disconnected':
627
+ $D('connectButton').style.display = "";
628
+ $D('disconnectButton').style.display = "none";
629
+ break;
630
+ default:
631
+ $D('connectButton').style.display = "none";
632
+ $D('disconnectButton').style.display = "";
633
+ break;
634
+ }
635
+
636
+ //Util.Debug("<< updateVisualState");
637
+ },
638
+
639
+ // Disable/enable XVP button
640
+ updateXvpVisualState: function(ver) {
641
+ if (ver >= 1) {
642
+ $D('xvpButton').style.display = 'inline';
643
+ } else {
644
+ $D('xvpButton').style.display = 'none';
645
+ // Close XVP panel if open
646
+ if (UI.xvpOpen === true) {
647
+ UI.toggleXvpPanel();
648
+ }
649
+ }
650
+ },
651
+
652
+ // Display the desktop name in the document title
653
+ updateDocumentTitle: function(rfb, name) {
654
+ document.title = name + " - noVNC";
655
+ },
656
+
657
+ clipReceive: function(rfb, text) {
658
+ Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
659
+ $D('noVNC_clipboard_text').value = text;
660
+ Util.Debug("<< UI.clipReceive");
661
+ },
662
+
663
+ connect: function() {
664
+ UI.closeSettingsMenu();
665
+ UI.toggleConnectPanel();
666
+
667
+ var host = $D('noVNC_host').value;
668
+ var port = $D('noVNC_port').value;
669
+ var password = $D('noVNC_password').value;
670
+ var path = $D('noVNC_path').value;
671
+ if ((!host) || (!port)) {
672
+ throw new Error("Must set host and port");
673
+ }
674
+
675
+ UI.rfb.set_encrypt(UI.getSetting('encrypt'));
676
+ UI.rfb.set_true_color(UI.getSetting('true_color'));
677
+ UI.rfb.set_local_cursor(UI.getSetting('cursor'));
678
+ UI.rfb.set_shared(UI.getSetting('shared'));
679
+ UI.rfb.set_view_only(UI.getSetting('view_only'));
680
+ UI.rfb.set_repeaterID(UI.getSetting('repeaterID'));
681
+
682
+ UI.rfb.connect(host, port, password, path);
683
+
684
+ //Close dialog.
685
+ setTimeout(UI.setBarPosition, 100);
686
+ $D('noVNC_logo').style.display = "none";
687
+ },
688
+
689
+ disconnect: function() {
690
+ UI.closeSettingsMenu();
691
+ UI.rfb.disconnect();
692
+
693
+ $D('noVNC_logo').style.display = "block";
694
+ UI.connSettingsOpen = false;
695
+ UI.toggleConnectPanel();
696
+ },
697
+
698
+ displayBlur: function() {
699
+ UI.rfb.get_keyboard().set_focused(false);
700
+ UI.rfb.get_mouse().set_focused(false);
701
+ },
702
+
703
+ displayFocus: function() {
704
+ UI.rfb.get_keyboard().set_focused(true);
705
+ UI.rfb.get_mouse().set_focused(true);
706
+ },
707
+
708
+ clipClear: function() {
709
+ $D('noVNC_clipboard_text').value = "";
710
+ UI.rfb.clipboardPasteFrom("");
711
+ },
712
+
713
+ clipSend: function() {
714
+ var text = $D('noVNC_clipboard_text').value;
715
+ Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "...");
716
+ UI.rfb.clipboardPasteFrom(text);
717
+ Util.Debug("<< UI.clipSend");
718
+ },
719
+
720
+ // Enable/disable and configure viewport clipping
721
+ setViewClip: function(clip) {
722
+ var display;
723
+ if (UI.rfb) {
724
+ display = UI.rfb.get_display();
725
+ } else {
726
+ return;
727
+ }
728
+
729
+ var cur_clip = display.get_viewport();
730
+
731
+ if (typeof(clip) !== 'boolean') {
732
+ // Use current setting
733
+ clip = UI.getSetting('clip');
734
+ }
735
+
736
+ if (clip && !cur_clip) {
737
+ // Turn clipping on
738
+ UI.updateSetting('clip', true);
739
+ } else if (!clip && cur_clip) {
740
+ // Turn clipping off
741
+ UI.updateSetting('clip', false);
742
+ display.set_viewport(false);
743
+ $D('noVNC_canvas').style.position = 'static';
744
+ display.viewportChange();
745
+ }
746
+ if (UI.getSetting('clip')) {
747
+ // If clipping, update clipping settings
748
+ $D('noVNC_canvas').style.position = 'absolute';
749
+ var pos = Util.getPosition($D('noVNC_canvas'));
750
+ var new_w = window.innerWidth - pos.x;
751
+ var new_h = window.innerHeight - pos.y;
752
+ display.set_viewport(true);
753
+ display.viewportChange(0, 0, new_w, new_h);
754
+ }
755
+ },
756
+
757
+ // Toggle/set/unset the viewport drag/move button
758
+ setViewDrag: function(drag) {
759
+ var vmb = $D('noVNC_view_drag_button');
760
+ if (!UI.rfb) { return; }
761
+
762
+ if (UI.rfb_state === 'normal' &&
763
+ UI.rfb.get_display().get_viewport()) {
764
+ vmb.style.display = "inline";
765
+ } else {
766
+ vmb.style.display = "none";
767
+ }
768
+
769
+ if (typeof(drag) === "undefined" ||
770
+ typeof(drag) === "object") {
771
+ // If not specified, then toggle
772
+ drag = !UI.rfb.get_viewportDrag();
773
+ }
774
+ if (drag) {
775
+ vmb.className = "noVNC_status_button_selected";
776
+ UI.rfb.set_viewportDrag(true);
777
+ } else {
778
+ vmb.className = "noVNC_status_button";
779
+ UI.rfb.set_viewportDrag(false);
780
+ }
781
+ },
782
+
783
+ // On touch devices, show the OS keyboard
784
+ showKeyboard: function() {
785
+ var kbi = $D('keyboardinput');
786
+ var skb = $D('showKeyboard');
787
+ var l = kbi.value.length;
788
+ if(UI.keyboardVisible === false) {
789
+ kbi.focus();
790
+ try { kbi.setSelectionRange(l, l); } // Move the caret to the end
791
+ catch (err) {} // setSelectionRange is undefined in Google Chrome
792
+ UI.keyboardVisible = true;
793
+ skb.className = "noVNC_status_button_selected";
794
+ } else if(UI.keyboardVisible === true) {
795
+ kbi.blur();
796
+ skb.className = "noVNC_status_button";
797
+ UI.keyboardVisible = false;
798
+ }
799
+ },
800
+
801
+ keepKeyboard: function() {
802
+ clearTimeout(UI.hideKeyboardTimeout);
803
+ if(UI.keyboardVisible === true) {
804
+ $D('keyboardinput').focus();
805
+ $D('showKeyboard').className = "noVNC_status_button_selected";
806
+ } else if(UI.keyboardVisible === false) {
807
+ $D('keyboardinput').blur();
808
+ $D('showKeyboard').className = "noVNC_status_button";
809
+ }
810
+ },
811
+
812
+ keyboardinputReset: function() {
813
+ var kbi = $D('keyboardinput');
814
+ kbi.value = new Array(UI.defaultKeyboardinputLen).join("_");
815
+ UI.lastKeyboardinput = kbi.value;
816
+ },
817
+
818
+ // When normal keyboard events are left uncought, use the input events from
819
+ // the keyboardinput element instead and generate the corresponding key events.
820
+ // This code is required since some browsers on Android are inconsistent in
821
+ // sending keyCodes in the normal keyboard events when using on screen keyboards.
822
+ keyInput: function(event) {
823
+ var newValue = event.target.value;
824
+ var oldValue = UI.lastKeyboardinput;
825
+
826
+ var newLen;
827
+ try {
828
+ // Try to check caret position since whitespace at the end
829
+ // will not be considered by value.length in some browsers
830
+ newLen = Math.max(event.target.selectionStart, newValue.length);
831
+ } catch (err) {
832
+ // selectionStart is undefined in Google Chrome
833
+ newLen = newValue.length;
834
+ }
835
+ var oldLen = oldValue.length;
836
+
837
+ var backspaces;
838
+ var inputs = newLen - oldLen;
839
+ if (inputs < 0) {
840
+ backspaces = -inputs;
841
+ } else {
842
+ backspaces = 0;
843
+ }
844
+
845
+ // Compare the old string with the new to account for
846
+ // text-corrections or other input that modify existing text
847
+ var i;
848
+ for (i = 0; i < Math.min(oldLen, newLen); i++) {
849
+ if (newValue.charAt(i) != oldValue.charAt(i)) {
850
+ inputs = newLen - i;
851
+ backspaces = oldLen - i;
852
+ break;
853
+ }
854
+ }
855
+
856
+ // Send the key events
857
+ for (i = 0; i < backspaces; i++) {
858
+ UI.rfb.sendKey(XK_BackSpace);
859
+ }
860
+ for (i = newLen - inputs; i < newLen; i++) {
861
+ UI.rfb.sendKey(newValue.charCodeAt(i));
862
+ }
863
+
864
+ // Control the text content length in the keyboardinput element
865
+ if (newLen > 2 * UI.defaultKeyboardinputLen) {
866
+ UI.keyboardinputReset();
867
+ } else if (newLen < 1) {
868
+ // There always have to be some text in the keyboardinput
869
+ // element with which backspace can interact.
870
+ UI.keyboardinputReset();
871
+ // This sometimes causes the keyboard to disappear for a second
872
+ // but it is required for the android keyboard to recognize that
873
+ // text has been added to the field
874
+ event.target.blur();
875
+ // This has to be ran outside of the input handler in order to work
876
+ setTimeout(function() { UI.keepKeyboard(); }, 0);
877
+ } else {
878
+ UI.lastKeyboardinput = newValue;
879
+ }
880
+ },
881
+
882
+ keyInputBlur: function() {
883
+ $D('showKeyboard').className = "noVNC_status_button";
884
+ //Weird bug in iOS if you change keyboardVisible
885
+ //here it does not actually occur so next time
886
+ //you click keyboard icon it doesnt work.
887
+ UI.hideKeyboardTimeout = setTimeout(function() { UI.setKeyboard(); },100);
888
+ },
889
+
890
+ showExtraKeys: function() {
891
+ UI.keepKeyboard();
892
+ if(UI.extraKeysVisible === false) {
893
+ $D('toggleCtrlButton').style.display = "inline";
894
+ $D('toggleAltButton').style.display = "inline";
895
+ $D('sendTabButton').style.display = "inline";
896
+ $D('sendEscButton').style.display = "inline";
897
+ $D('showExtraKeysButton').className = "noVNC_status_button_selected";
898
+ UI.extraKeysVisible = true;
899
+ } else if(UI.extraKeysVisible === true) {
900
+ $D('toggleCtrlButton').style.display = "";
901
+ $D('toggleAltButton').style.display = "";
902
+ $D('sendTabButton').style.display = "";
903
+ $D('sendEscButton').style.display = "";
904
+ $D('showExtraKeysButton').className = "noVNC_status_button";
905
+ UI.extraKeysVisible = false;
906
+ }
907
+ },
908
+
909
+ toggleCtrl: function() {
910
+ UI.keepKeyboard();
911
+ if(UI.ctrlOn === false) {
912
+ UI.rfb.sendKey(XK_Control_L, true);
913
+ $D('toggleCtrlButton').className = "noVNC_status_button_selected";
914
+ UI.ctrlOn = true;
915
+ } else if(UI.ctrlOn === true) {
916
+ UI.rfb.sendKey(XK_Control_L, false);
917
+ $D('toggleCtrlButton').className = "noVNC_status_button";
918
+ UI.ctrlOn = false;
919
+ }
920
+ },
921
+
922
+ toggleAlt: function() {
923
+ UI.keepKeyboard();
924
+ if(UI.altOn === false) {
925
+ UI.rfb.sendKey(XK_Alt_L, true);
926
+ $D('toggleAltButton').className = "noVNC_status_button_selected";
927
+ UI.altOn = true;
928
+ } else if(UI.altOn === true) {
929
+ UI.rfb.sendKey(XK_Alt_L, false);
930
+ $D('toggleAltButton').className = "noVNC_status_button";
931
+ UI.altOn = false;
932
+ }
933
+ },
934
+
935
+ sendTab: function() {
936
+ UI.keepKeyboard();
937
+ UI.rfb.sendKey(XK_Tab);
938
+ },
939
+
940
+ sendEsc: function() {
941
+ UI.keepKeyboard();
942
+ UI.rfb.sendKey(XK_Escape);
943
+ },
944
+
945
+ setKeyboard: function() {
946
+ UI.keyboardVisible = false;
947
+ },
948
+
949
+ // iOS < Version 5 does not support position fixed. Javascript workaround:
950
+ setOnscroll: function() {
951
+ window.onscroll = function() {
952
+ UI.setBarPosition();
953
+ };
954
+ },
955
+
956
+ setResize: function () {
957
+ window.onResize = function() {
958
+ UI.setBarPosition();
959
+ };
960
+ },
961
+
962
+ //Helper to add options to dropdown.
963
+ addOption: function(selectbox, text, value) {
964
+ var optn = document.createElement("OPTION");
965
+ optn.text = text;
966
+ optn.value = value;
967
+ selectbox.options.add(optn);
968
+ },
969
+
970
+ setBarPosition: function() {
971
+ $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px';
972
+ $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
973
+
974
+ var vncwidth = $D('noVNC_screen').style.offsetWidth;
975
+ $D('noVNC-control-bar').style.width = vncwidth + 'px';
976
+ }
977
+
978
+ };
979
+ })();