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.
- checksums.yaml +7 -0
- data/COPYING +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +0 -0
- data/lib/novnc-rails.rb +8 -0
- data/lib/novnc-rails/version.rb +5 -0
- data/vendor/assets/javascripts/noVNC/Orbitron700.ttf +0 -0
- data/vendor/assets/javascripts/noVNC/Orbitron700.woff +0 -0
- data/vendor/assets/javascripts/noVNC/base.css +512 -0
- data/vendor/assets/javascripts/noVNC/base64.js +113 -0
- data/vendor/assets/javascripts/noVNC/black.css +71 -0
- data/vendor/assets/javascripts/noVNC/blue.css +64 -0
- data/vendor/assets/javascripts/noVNC/des.js +276 -0
- data/vendor/assets/javascripts/noVNC/display.js +751 -0
- data/vendor/assets/javascripts/noVNC/input.js +388 -0
- data/vendor/assets/javascripts/noVNC/jsunzip.js +676 -0
- data/vendor/assets/javascripts/noVNC/keyboard.js +543 -0
- data/vendor/assets/javascripts/noVNC/keysym.js +378 -0
- data/vendor/assets/javascripts/noVNC/keysymdef.js +15 -0
- data/vendor/assets/javascripts/noVNC/logo.js +1 -0
- data/vendor/assets/javascripts/noVNC/playback.js +102 -0
- data/vendor/assets/javascripts/noVNC/rfb.js +1889 -0
- data/vendor/assets/javascripts/noVNC/ui.js +979 -0
- data/vendor/assets/javascripts/noVNC/util.js +656 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/README.txt +109 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/WebSocketMain.swf +0 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/swfobject.js +4 -0
- data/vendor/assets/javascripts/noVNC/web-socket-js/web_socket.js +391 -0
- data/vendor/assets/javascripts/noVNC/websock.js +388 -0
- data/vendor/assets/javascripts/noVNC/webutil.js +239 -0
- 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
|
+
})();
|