]>
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 */
16 connSettingsOpen
: true,
19 // Render default UI and initialize settings menu
21 var html
= '', i
, sheet
, sheets
, llevels
;
23 // Stylesheet selection dropdown
24 sheet
= WebUtil
.selectStylesheet();
25 sheets
= WebUtil
.getStylesheets();
26 for (i
= 0; i
< sheets
.length
; i
+= 1) {
27 UI
.addOption($D('noVNC_stylesheet'),sheets
[i
].title
, sheets
[i
].title
);
30 // Logging selection dropdown
31 llevels
= ['error', 'warn', 'info', 'debug'];
32 for (i
= 0; i
< llevels
.length
; i
+= 1) {
33 UI
.addOption($D('noVNC_logging'),llevels
[i
], llevels
[i
]);
36 // Settings with immediate effects
37 UI
.initSetting('logging', 'warn');
38 WebUtil
.init_logging(UI
.getSetting('logging'));
39 UI
.initSetting('stylesheet', 'default');
41 WebUtil
.selectStylesheet(null);
42 // call twice to get around webkit bug
43 WebUtil
.selectStylesheet(UI
.getSetting('stylesheet'));
45 /* Populate the controls if defaults are provided in the URL */
46 UI
.initSetting('host', '');
47 UI
.initSetting('port', '');
48 UI
.initSetting('password', '');
49 UI
.initSetting('encrypt', false);
50 UI
.initSetting('true_color', true);
51 UI
.initSetting('cursor', false);
52 UI
.initSetting('shared', true);
53 UI
.initSetting('connectTimeout', 2);
55 UI
.rfb
= RFB({'target': $D('noVNC_canvas'),
56 'onUpdateState': UI
.updateState
,
57 'onClipboard': UI
.clipReceive
});
59 // Unfocus clipboard when over the VNC area
60 //$D('VNC_screen').onmousemove = function () {
61 // var keyboard = UI.rfb.get_keyboard();
62 // if ((! keyboard) || (! keyboard.get_focused())) {
63 // $D('VNC_clipboard_text').blur();
67 // Show mouse selector buttons on touch screen devices
68 if ('ontouchstart' in document
.documentElement
) {
69 $D('noVNC_mobile_buttons').style
.display
= "inline";
71 window
.scrollTo(0, 1);
74 //iOS Safari does not support CSS position:fixed.
75 //This detects iOS devices and enables javascript workaround.
76 if ((navigator
.userAgent
.match(/iPhone/i)) ||
77 (navigator
.userAgent
.match(/iPod/i)) ||
78 (navigator
.userAgent
.match(/iPad/i))) {
83 $D('noVNC_host').focus();
86 // Read form control compatible setting from cookie
87 getSetting: function(name
) {
88 var val
, ctrl
= $D('noVNC_' + name
);
89 val
= WebUtil
.readCookie(name
);
90 if (ctrl
.type
=== 'checkbox') {
91 if (val
.toLowerCase() in {'0':1, 'no':1, 'false':1}) {
100 // Update cookie and form control setting. If value is not set, then
101 // updates from control to current cookie setting.
102 updateSetting: function(name
, value
) {
104 var i
, ctrl
= $D('noVNC_' + name
);
105 // Save the cookie for this session
106 if (typeof value
!== 'undefined') {
107 WebUtil
.createCookie(name
, value
);
110 // Update the settings control
111 value
= UI
.getSetting(name
);
113 if (ctrl
.type
=== 'checkbox') {
114 ctrl
.checked
= value
;
116 } else if (typeof ctrl
.options
!== 'undefined') {
117 for (i
= 0; i
< ctrl
.options
.length
; i
+= 1) {
118 if (ctrl
.options
[i
].value
=== value
) {
119 ctrl
.selectedIndex
= i
;
124 /*Weird IE9 error leads to 'null' appearring
125 in textboxes instead of ''.*/
126 if (value
=== null) {
133 // Save control setting to cookie
134 saveSetting: function(name
) {
135 var val
, ctrl
= $D('noVNC_' + name
);
136 if (ctrl
.type
=== 'checkbox') {
138 } else if (typeof ctrl
.options
!== 'undefined') {
139 val
= ctrl
.options
[ctrl
.selectedIndex
].value
;
143 WebUtil
.createCookie(name
, val
);
144 //Util.Debug("Setting saved '" + name + "=" + val + "'");
148 // Initial page load read/initialization of settings
149 initSetting: function(name
, defVal
) {
152 // Check Query string followed by cookie
153 val
= WebUtil
.getQueryVar(name
);
155 val
= WebUtil
.readCookie(name
, defVal
);
157 UI
.updateSetting(name
, val
);
158 //Util.Debug("Setting '" + name + "' initialized to '" + val + "'");
163 // Toggle the settings menu:
164 // On open, settings are refreshed from saved cookies.
165 // On close, settings are applied
166 clickSettingsMenu: function() {
167 if (UI
.settingsOpen
) {
170 UI
.closeSettingsMenu();
172 UI
.updateSetting('encrypt');
173 UI
.updateSetting('true_color');
174 if (UI
.rfb
.get_display().get_cursor_uri()) {
175 UI
.updateSetting('cursor');
177 UI
.updateSetting('cursor', false);
178 $D('noVNC_cursor').disabled
= true;
180 UI
.updateSetting('shared');
181 UI
.updateSetting('connectTimeout');
182 UI
.updateSetting('stylesheet');
183 UI
.updateSetting('logging');
185 UI
.openSettingsMenu();
190 openSettingsMenu: function() {
191 if (UI
.clipboardOpen
== true) {
194 //Close connection settings if open
195 if (UI
.connSettingsOpen
== true) {
196 UI
.connectPanelbutton();
198 $D('noVNC_Settings').style
.display
= "block";
199 UI
.settingsOpen
= true;
202 // Close menu (without applying settings)
203 closeSettingsMenu: function() {
204 $D('noVNC_Settings').style
.display
= "none";
205 UI
.settingsOpen
= false;
208 // Disable/enable controls depending on connection state
209 settingsDisabled: function(disabled
, rfb
) {
210 //Util.Debug(">> settingsDisabled");
211 $D('noVNC_encrypt').disabled
= disabled
;
212 $D('noVNC_true_color').disabled
= disabled
;
213 if (rfb
&& rfb
.get_display() && rfb
.get_display().get_cursor_uri()) {
214 $D('noVNC_cursor').disabled
= disabled
;
216 UI
.updateSetting('cursor', false);
217 $D('noVNC_cursor').disabled
= true;
219 $D('noVNC_shared').disabled
= disabled
;
220 $D('noVNC_connectTimeout').disabled
= disabled
;
221 //Util.Debug("<< settingsDisabled");
224 // Save/apply settings when 'Apply' button is pressed
225 settingsApply: function() {
226 //Util.Debug(">> settingsApply");
227 UI
.saveSetting('encrypt');
228 UI
.saveSetting('true_color');
229 if (UI
.rfb
.get_display().get_cursor_uri()) {
230 UI
.saveSetting('cursor');
232 UI
.saveSetting('shared');
233 UI
.saveSetting('connectTimeout');
234 UI
.saveSetting('stylesheet');
235 UI
.saveSetting('logging');
237 // Settings with immediate (non-connected related) effect
238 WebUtil
.selectStylesheet(UI
.getSetting('stylesheet'));
239 WebUtil
.init_logging(UI
.getSetting('logging'));
240 //Util.Debug("<< settingsApply");
245 setPassword: function() {
246 UI
.rfb
.sendPassword($D('noVNC_password').value
);
247 //Reset connect button.
248 $D('noVNC_connect_button').value
= "Connect";
249 $D('noVNC_connect_button').onclick
= UI
.Connect
;
250 //Hide connection panel.
251 UI
.connectPanelbutton();
255 sendCtrlAltDel: function() {
256 UI
.rfb
.sendCtrlAltDel();
259 setMouseButton: function(num
) {
260 var b
, blist
= [1,2,4], button
,
261 mouse
= UI
.rfb
.get_mouse();
263 if (typeof num
=== 'undefined') {
265 num
= mouse
.get_touchButton();
266 } else if (num
=== mouse
.get_touchButton()) {
267 // Set all buttons off (no clicks)
268 mouse
.set_touchButton(0);
271 // Turn on one button
272 mouse
.set_touchButton(num
);
275 for (b
= 0; b
< blist
.length
; b
++) {
276 button
= $D('noVNC_mouse_button' + blist
[b
]);
277 if (blist
[b
] === num
) {
278 button
.style
.backgroundColor
= "black";
279 button
.style
.color
= "lightgray";
281 button
.style
.backgroundColor
= "";
282 button
.style
.color
= "";
287 updateState: function(rfb
, state
, oldstate
, msg
) {
288 var s
, sb
, c
, cad
, klass
;
289 s
= $D('noVNC_status');
290 sb
= $D('noVNC_status_bar');
291 c
= $D('connectPanelbutton');
292 cad
= $D('sendCtrlAltDelButton');
297 cad
.style
.display
= "none";
298 UI
.settingsDisabled(true, rfb
);
299 klass
= "noVNC_status_error";
302 c
.value
= "Disconnect";
303 c
.onclick
= UI
.disconnect
;
305 cad
.style
.display
= "block";
306 UI
.settingsDisabled(true, rfb
);
307 klass
= "noVNC_status_normal";
310 $D('noVNC_logo').style
.display
= "block";
311 c
.value
= "Connection";
312 c
.onclick
= UI
.connectPanelbutton
;
314 c
.value
= "Connection";
315 c
.onclick
= UI
.connectPanelbutton
;
317 cad
.style
.display
= "none";
318 UI
.settingsDisabled(false, rfb
);
319 klass
= "noVNC_status_normal";
322 UI
.connectPanelbutton();
324 $D('noVNC_connect_button').value
= "Send Password";
325 $D('noVNC_connect_button').onclick
= UI
.setPassword
;
326 $D('noVNC_password').focus();
329 cad
.style
.display
= "none";
330 UI
.settingsDisabled(true, rfb
);
331 klass
= "noVNC_status_warn";
335 cad
.style
.display
= "none";
336 UI
.settingsDisabled(true, rfb
);
337 klass
= "noVNC_status_warn";
341 if (typeof(msg
) !== 'undefined') {
342 s
.setAttribute("class", klass
);
343 sb
.setAttribute("class", klass
);
349 clipReceive: function(rfb
, text
) {
350 Util
.Debug(">> UI.clipReceive: " + text
.substr(0,40) + "...");
351 $D('noVNC_clipboard_text').value
= text
;
352 Util
.Debug("<< UI.clipReceive");
356 connect: function() {
357 var host
, port
, password
;
359 UI
.closeSettingsMenu();
360 UI
.connectPanelbutton();
362 host
= $D('noVNC_host').value
;
363 port
= $D('noVNC_port').value
;
364 password
= $D('noVNC_password').value
;
365 if ((!host
) || (!port
)) {
366 throw("Must set host and port");
369 UI
.rfb
.set_encrypt(UI
.getSetting('encrypt'));
370 UI
.rfb
.set_true_color(UI
.getSetting('true_color'));
371 UI
.rfb
.set_local_cursor(UI
.getSetting('cursor'));
372 UI
.rfb
.set_shared(UI
.getSetting('shared'));
373 UI
.rfb
.set_connectTimeout(UI
.getSetting('connectTimeout'));
375 UI
.rfb
.connect(host
, port
, password
);
377 setTimeout(UI
.setBarPosition
, 100);
378 $D('noVNC_logo').style
.display
= "none";
381 disconnect: function() {
382 UI
.closeSettingsMenu();
385 $D('noVNC_logo').style
.display
= "block";
386 UI
.connSettingsOpen
= false;
387 UI
.connectPanelbutton();
390 displayBlur: function() {
391 UI
.rfb
.get_keyboard().set_focused(false);
392 UI
.rfb
.get_mouse().set_focused(false);
395 displayFocus: function() {
396 UI
.rfb
.get_keyboard().set_focused(true);
397 UI
.rfb
.get_mouse().set_focused(true);
400 clipClear: function() {
401 $D('noVNC_clipboard_text').value
= "";
402 UI
.rfb
.clipboardPasteFrom("");
405 clipSend: function() {
406 var text
= $D('noVNC_clipboard_text').value
;
407 Util
.Debug(">> UI.clipSend: " + text
.substr(0,40) + "...");
408 UI
.rfb
.clipboardPasteFrom(text
);
409 Util
.Debug("<< UI.clipSend");
412 showClipboard: function() {
413 //Close settings if open
414 if (UI
.settingsOpen
== true) {
415 UI
.closeSettingsMenu();
417 //Close connection settings if open
418 if (UI
.connSettingsOpen
== true) {
419 UI
.connectPanelbutton();
421 //Toggle Connection Panel
422 if (UI
.clipboardOpen
== true) {
423 $D('noVNC_clipboard').style
.display
= "none";
424 UI
.clipboardOpen
= false;
426 $D('noVNC_clipboard').style
.display
= "block";
427 UI
.clipboardOpen
= true;
432 showKeyboard: function() {
433 //Get Current Scroll Position
435 (document
.all
)?document
.body
.scrollLeft
:window
.pageXOffset
;
437 (document
.all
)?document
.body
.scrollTop
:window
.pageYOffset
;
439 //Stop browser zooming on textbox.
441 $D('keyboardinput').focus();
442 scroll(scrollx
,scrolly
);
447 zoomDisable: function() {
448 //Change viewport meta data to disable zooming.
449 UI
.changeViewportMeta("user-scalable=0");
452 zoomEnable: function(){
453 //Change viewport meta data to enable user zooming.
454 UI
.changeViewportMeta("user-scalable=1");
457 changeViewportMeta: function (newattributes
) {
459 // First, get the array of meta-tag elements
460 var metatags
= document
.getElementsByTagName("meta");
462 // Update only the Viewport meta tag
463 for (var cnt
= 0; cnt
< metatags
.length
; cnt
++)
465 var name
= metatags
[cnt
].getAttribute("name");
466 var content
= metatags
[cnt
].getAttribute("content");
468 // Update the Viewport meta tag
469 if (metatags
[cnt
].getAttribute("name") == "viewport") {
470 metatags
[cnt
].setAttribute("content", newattributes
);
475 //iOS < Version 5 does not support position fixed. Javascript workaround:
476 setOnscroll: function() {
477 window
.onscroll = function() {
482 setResize: function () {
483 window
.onResize = function() {
488 //Helper to add options to dropdown.
489 addOption: function(selectbox
,text
,value
)
491 var optn
= document
.createElement("OPTION");
494 selectbox
.options
.add(optn
);
497 setBarPosition: function() {
498 $D('noVNC-control-bar').style
.top
= (window
.pageYOffset
) + 'px';
499 $D('noVNC_mobile_buttons').style
.left
= (window
.pageXOffset
) + 'px';
500 $D('noVNC_buttons_right').style
.right
= 0 + 'px';
502 var vncwidth
= $D('noVNC_screen').style
.offsetWidth
;
503 $D('noVNC-control-bar').style
.width
= vncwidth
+ 'px';
506 connectPanelbutton: function() {
507 //Close connection settings if open
508 if (UI
.settingsOpen
== true) {
509 UI
.closeSettingsMenu();
511 if (UI
.clipboardOpen
== true) {
515 //Toggle Connection Panel
516 if (UI
.connSettingsOpen
== true) {
517 $D('noVNC_controls').style
.display
= "none";
518 UI
.connSettingsOpen
= false;
520 $D('noVNC_controls').style
.display
= "block";
521 UI
.connSettingsOpen
= true;
522 $D('noVNC_host').focus();