]>
git.proxmox.com Git - mirror_novnc.git/blob - include/ui.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2011 Joel Martin
4 * Licensed under LGPL-3 (see LICENSE.txt)
6 * See README.md for usage and integration instructions.
10 /*jslint white: false, browser: true */
11 /*global window, $D, Util, WebUtil, RFB, Display */
17 // Render default UI and initialize settings menu
18 load: function(target
) {
19 var html
= '', i
, sheet
, sheets
, llevels
;
21 /* Populate the 'target' DOM element with default UI */
24 } else if (typeof target
=== 'string') {
28 if ((!document
.createElement('canvas').getContext
) &&
29 window
.ActiveXObject
) {
30 // Suggest Chrome frame for Internet Explorer users
31 html
+= '<center><div style="text-align: left; width: 400px">';
32 html
+= ' You are using a version of Internet Explorer ';
33 html
+= ' that does not have HTML5 Canvas support. ';
34 html
+= ' To use noVNC you must use a browser with HTML5 ';
35 html
+= ' Canvas support or install ';
36 html
+= ' <a href="http://google.com/chromeframe" target="cframe">';
37 html
+= ' Google Chrome Frame.</a>';
38 html
+= '</div></center>';
39 target
.innerHTML
= html
;
43 html
+= '<div id="VNC_controls">';
45 html
+= ' <li>Host: <input id="VNC_host"></li>';
46 html
+= ' <li>Port: <input id="VNC_port"></li>';
47 html
+= ' <li>Password: <input id="VNC_password"';
48 html
+= ' type="password"></li>';
49 html
+= ' <li><input id="VNC_connect_button" type="button"';
50 html
+= ' value="Loading" disabled></li>';
53 html
+= '<div id="VNC_screen">';
54 html
+= ' <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">';
55 html
+= ' <table border=0 width=100%><tr>';
56 html
+= ' <td><div id="VNC_status">Loading</div></td>';
58 // Mouse button selectors for touch devices
59 html
+= ' <td width=1%><div class="VNC_buttons_right">';
60 html
+= ' <nobr><span id="VNC_mouse_buttons" style="display: none;">';
61 html
+= ' <input type="button" class="VNC_status_button"';
62 html
+= ' id="VNC_mouse_button1" value="L" onclick="UI.setMouseButton(1);"';
63 html
+= ' ><input type="button" class="VNC_status_button"';
64 html
+= ' id="VNC_mouse_button2" value="M" onclick="UI.setMouseButton(2);"';
65 html
+= ' ><input type="button" class="VNC_status_button"';
66 html
+= ' id="VNC_mouse_button4" value="R" onclick="UI.setMouseButton(4);">';
67 html
+= ' </span></nobr></div></td>';
69 // Settings drop-down menu
70 html
+= ' <td width=1%><div class="VNC_buttons_right">';
71 html
+= ' <input type=button class="VNC_status_button" value="Settings"';
72 html
+= ' id="menuButton"';
73 html
+= ' onclick="UI.clickSettingsMenu();">';
74 html
+= ' <span id="VNC_settings_menu"';
75 html
+= ' onmouseover="UI.displayBlur();"';
76 html
+= ' onmouseout="UI.displayFocus();">';
78 html
+= ' <li><input id="VNC_encrypt"';
79 html
+= ' type="checkbox"> Encrypt</li>';
80 html
+= ' <li><input id="VNC_true_color"';
81 html
+= ' type="checkbox" checked> True Color</li>';
82 html
+= ' <li><input id="VNC_cursor"';
83 html
+= ' type="checkbox"> Local Cursor</li>';
84 html
+= ' <li><input id="VNC_shared"';
85 html
+= ' type="checkbox"> Shared Mode</li>';
86 html
+= ' <li><input id="VNC_connectTimeout"';
87 html
+= ' type="input"> Connect Timeout (s)</li>';
90 // Stylesheet selection dropdown
91 html
+= ' <li><select id="VNC_stylesheet" name="vncStyle">';
92 html
+= ' <option value="default">default</option>';
93 sheet
= WebUtil
.selectStylesheet();
94 sheets
= WebUtil
.getStylesheets();
95 for (i
= 0; i
< sheets
.length
; i
+= 1) {
96 html
+= '<option value="' + sheets
[i
].title
+ '">' + sheets
[i
].title
+ '</option>';
98 html
+= ' </select> Style</li>';
100 // Logging selection dropdown
101 html
+= ' <li><select id="VNC_logging" name="vncLogging">';
102 llevels
= ['error', 'warn', 'info', 'debug'];
103 for (i
= 0; i
< llevels
.length
; i
+= 1) {
104 html
+= '<option value="' + llevels
[i
] + '">' + llevels
[i
] + '</option>';
106 html
+= ' </select> Logging</li>';
109 html
+= ' <li><input type="button" id="VNC_apply" value="Apply"';
110 html
+= ' onclick="UI.settingsApply()"></li>';
112 html
+= ' </span></div></td>';
115 html
+= ' <td width=1%><div class="VNC_buttons_right">';
116 html
+= ' <input type=button class="VNC_status_button" value="CtrlAltDel"';
117 html
+= ' id="sendCtrlAltDelButton"';
118 html
+= ' onclick="UI.sendCtrlAltDel();"></div></td>';
120 html
+= ' </tr></table>';
122 html
+= ' <canvas id="VNC_canvas" width="640px" height="20px">';
123 html
+= ' Canvas not supported.';
124 html
+= ' </canvas>';
127 html
+= '<div id="VNC_clipboard">';
128 html
+= ' VNC Clipboard:';
129 html
+= ' <input id="VNC_clipboard_clear_button"';
130 html
+= ' type="button" value="Clear"';
131 html
+= ' onclick="UI.clipClear();">';
133 html
+= ' <textarea id="VNC_clipboard_text" cols=80 rows=5';
134 html
+= ' onfocus="UI.displayBlur();"';
135 html
+= ' onblur="UI.displayFocus();"';
136 html
+= ' onchange="UI.clipSend();"></textarea>';
138 target
.innerHTML
= html
;
140 // Settings with immediate effects
141 UI
.initSetting('logging', 'warn');
142 WebUtil
.init_logging(UI
.getSetting('logging'));
143 UI
.initSetting('stylesheet', 'default');
145 WebUtil
.selectStylesheet(null); // call twice to get around webkit bug
146 WebUtil
.selectStylesheet(UI
.getSetting('stylesheet'));
148 /* Populate the controls if defaults are provided in the URL */
149 UI
.initSetting('host', '');
150 UI
.initSetting('port', '');
151 UI
.initSetting('password', '');
152 UI
.initSetting('encrypt', false);
153 UI
.initSetting('true_color', true);
154 UI
.initSetting('cursor', false);
155 UI
.initSetting('shared', true);
156 UI
.initSetting('connectTimeout', 2);
158 UI
.rfb
= RFB({'target': $D('VNC_canvas'),
159 'onUpdateState': UI
.updateState
,
160 'onClipboard': UI
.clipReceive
});
162 // Unfocus clipboard when over the VNC area
163 $D('VNC_screen').onmousemove = function () {
164 var keyboard
= UI
.rfb
.get_keyboard();
165 if ((! keyboard
) || (! keyboard
.get_focused())) {
166 $D('VNC_clipboard_text').blur();
170 // Show mouse selector buttons on touch screen devices
171 if ('ontouchstart' in document
.documentElement
) {
172 $D('VNC_mouse_buttons').style
.display
= "inline";
178 // Read form control compatible setting from cookie
179 getSetting: function(name
) {
180 var val
, ctrl
= $D('VNC_' + name
);
181 val
= WebUtil
.readCookie(name
);
182 if (ctrl
.type
=== 'checkbox') {
183 if (val
.toLowerCase() in {'0':1, 'no':1, 'false':1}) {
192 // Update cookie and form control setting. If value is not set, then
193 // updates from control to current cookie setting.
194 updateSetting: function(name
, value
) {
195 var i
, ctrl
= $D('VNC_' + name
);
196 // Save the cookie for this session
197 if (typeof value
!== 'undefined') {
198 WebUtil
.createCookie(name
, value
);
201 // Update the settings control
202 value
= UI
.getSetting(name
);
203 if (ctrl
.type
=== 'checkbox') {
204 ctrl
.checked
= value
;
205 } else if (typeof ctrl
.options
!== 'undefined') {
206 for (i
= 0; i
< ctrl
.options
.length
; i
+= 1) {
207 if (ctrl
.options
[i
].value
=== value
) {
208 ctrl
.selectedIndex
= i
;
217 // Save control setting to cookie
218 saveSetting: function(name
) {
219 var val
, ctrl
= $D('VNC_' + name
);
220 if (ctrl
.type
=== 'checkbox') {
222 } else if (typeof ctrl
.options
!== 'undefined') {
223 val
= ctrl
.options
[ctrl
.selectedIndex
].value
;
227 WebUtil
.createCookie(name
, val
);
228 //Util.Debug("Setting saved '" + name + "=" + val + "'");
232 // Initial page load read/initialization of settings
233 initSetting: function(name
, defVal
) {
236 // Check Query string followed by cookie
237 val
= WebUtil
.getQueryVar(name
);
239 val
= WebUtil
.readCookie(name
, defVal
);
241 UI
.updateSetting(name
, val
);
242 //Util.Debug("Setting '" + name + "' initialized to '" + val + "'");
247 // Toggle the settings menu:
248 // On open, settings are refreshed from saved cookies.
249 // On close, settings are applied
250 clickSettingsMenu: function() {
251 if (UI
.settingsOpen
) {
254 UI
.closeSettingsMenu();
256 UI
.updateSetting('encrypt');
257 UI
.updateSetting('true_color');
258 if (UI
.rfb
.get_display().get_cursor_uri()) {
259 UI
.updateSetting('cursor');
261 UI
.updateSetting('cursor', false);
262 $D('VNC_cursor').disabled
= true;
264 UI
.updateSetting('shared');
265 UI
.updateSetting('connectTimeout');
266 UI
.updateSetting('stylesheet');
267 UI
.updateSetting('logging');
269 UI
.openSettingsMenu();
274 openSettingsMenu: function() {
275 $D('VNC_settings_menu').style
.display
= "block";
276 UI
.settingsOpen
= true;
279 // Close menu (without applying settings)
280 closeSettingsMenu: function() {
281 $D('VNC_settings_menu').style
.display
= "none";
282 UI
.settingsOpen
= false;
285 // Disable/enable controls depending on connection state
286 settingsDisabled: function(disabled
, rfb
) {
287 //Util.Debug(">> settingsDisabled");
288 $D('VNC_encrypt').disabled
= disabled
;
289 $D('VNC_true_color').disabled
= disabled
;
290 if (rfb
&& rfb
.get_display() && rfb
.get_display().get_cursor_uri()) {
291 $D('VNC_cursor').disabled
= disabled
;
293 UI
.updateSetting('cursor', false);
294 $D('VNC_cursor').disabled
= true;
296 $D('VNC_shared').disabled
= disabled
;
297 $D('VNC_connectTimeout').disabled
= disabled
;
298 //Util.Debug("<< settingsDisabled");
301 // Save/apply settings when 'Apply' button is pressed
302 settingsApply: function() {
303 //Util.Debug(">> settingsApply");
304 UI
.saveSetting('encrypt');
305 UI
.saveSetting('true_color');
306 if (UI
.rfb
.get_display().get_cursor_uri()) {
307 UI
.saveSetting('cursor');
309 UI
.saveSetting('shared');
310 UI
.saveSetting('connectTimeout');
311 UI
.saveSetting('stylesheet');
312 UI
.saveSetting('logging');
314 // Settings with immediate (non-connected related) effect
315 WebUtil
.selectStylesheet(UI
.getSetting('stylesheet'));
316 WebUtil
.init_logging(UI
.getSetting('logging'));
318 //Util.Debug("<< settingsApply");
323 setPassword: function() {
324 UI
.rfb
.sendPassword($D('VNC_password').value
);
328 sendCtrlAltDel: function() {
329 UI
.rfb
.sendCtrlAltDel();
332 setMouseButton: function(num
) {
333 var b
, blist
= [1,2,4], button
,
334 mouse
= UI
.rfb
.get_mouse();
336 if (typeof num
=== 'undefined') {
338 num
= mouse
.get_touchButton();
339 } else if (num
=== mouse
.get_touchButton()) {
340 // Set all buttons off (no clicks)
341 mouse
.set_touchButton(0);
344 // Turn on one button
345 mouse
.set_touchButton(num
);
348 for (b
= 0; b
< blist
.length
; b
++) {
349 button
= $D('VNC_mouse_button' + blist
[b
]);
350 if (blist
[b
] === num
) {
351 button
.style
.backgroundColor
= "black";
352 button
.style
.color
= "lightgray";
354 button
.style
.backgroundColor
= "";
355 button
.style
.color
= "";
361 updateState: function(rfb
, state
, oldstate
, msg
) {
362 var s
, sb
, c
, cad
, klass
;
363 s
= $D('VNC_status');
364 sb
= $D('VNC_status_bar');
365 c
= $D('VNC_connect_button');
366 cad
= $D('sendCtrlAltDelButton');
372 UI
.settingsDisabled(true, rfb
);
373 klass
= "VNC_status_error";
376 c
.value
= "Disconnect";
377 c
.onclick
= UI
.disconnect
;
379 cad
.disabled
= false;
380 UI
.settingsDisabled(true, rfb
);
381 klass
= "VNC_status_normal";
386 c
.onclick
= UI
.connect
;
390 UI
.settingsDisabled(false, rfb
);
391 klass
= "VNC_status_normal";
394 c
.value
= "Send Password";
395 c
.onclick
= UI
.setPassword
;
399 UI
.settingsDisabled(true, rfb
);
400 klass
= "VNC_status_warn";
405 UI
.settingsDisabled(true, rfb
);
406 klass
= "VNC_status_warn";
410 if (typeof(msg
) !== 'undefined') {
411 s
.setAttribute("class", klass
);
412 sb
.setAttribute("class", klass
);
418 clipReceive: function(rfb
, text
) {
419 Util
.Debug(">> UI.clipReceive: " + text
.substr(0,40) + "...");
420 $D('VNC_clipboard_text').value
= text
;
421 Util
.Debug("<< UI.clipReceive");
425 connect: function() {
426 var host
, port
, password
;
428 UI
.closeSettingsMenu();
430 host
= $D('VNC_host').value
;
431 port
= $D('VNC_port').value
;
432 password
= $D('VNC_password').value
;
433 if ((!host
) || (!port
)) {
434 throw("Must set host and port");
437 UI
.rfb
.set_encrypt(UI
.getSetting('encrypt'));
438 UI
.rfb
.set_true_color(UI
.getSetting('true_color'));
439 UI
.rfb
.set_local_cursor(UI
.getSetting('cursor'));
440 UI
.rfb
.set_shared(UI
.getSetting('shared'));
441 UI
.rfb
.set_connectTimeout(UI
.getSetting('connectTimeout'));
443 UI
.rfb
.connect(host
, port
, password
);
446 disconnect: function() {
447 UI
.closeSettingsMenu();
452 displayBlur: function() {
453 UI
.rfb
.get_keyboard().set_focused(false);
454 UI
.rfb
.get_mouse().set_focused(false);
457 displayFocus: function() {
458 UI
.rfb
.get_keyboard().set_focused(true);
459 UI
.rfb
.get_mouse().set_focused(true);
462 clipClear: function() {
463 $D('VNC_clipboard_text').value
= "";
464 UI
.rfb
.clipboardPasteFrom("");
467 clipSend: function() {
468 var text
= $D('VNC_clipboard_text').value
;
469 Util
.Debug(">> UI.clipSend: " + text
.substr(0,40) + "...");
470 UI
.rfb
.clipboardPasteFrom(text
);
471 Util
.Debug("<< UI.clipSend");