]> git.proxmox.com Git - mirror_novnc.git/blame - include/ui.js
Disable static canvas logo.
[mirror_novnc.git] / include / ui.js
CommitLineData
15046f00
JM
1/*
2 * noVNC: HTML5 VNC client
d0c29bb6 3 * Copyright (C) 2011 Joel Martin
5f409eee 4 * Licensed under LGPL-3 (see LICENSE.txt)
15046f00
JM
5 *
6 * See README.md for usage and integration instructions.
7 */
43cf7bd8 8
15046f00 9"use strict";
43cf7bd8 10/*jslint white: false, browser: true */
d890e864 11/*global window, $D, Util, WebUtil, RFB, Display */
15046f00 12
f7ec5b2c 13var UI = {
91308399 14
da6dd893 15settingsOpen : false,
8e0f0088 16connSettingsOpen : true,
53fc7392 17clipboardOpen: false,
da6dd893 18
f7ec5b2c 19// Render default UI and initialize settings menu
53fc7392 20load: function() {
f7ec5b2c 21 var html = '', i, sheet, sheets, llevels;
91308399 22
53fc7392 23 // Stylesheet selection dropdown
8d5d2c82
AM
24 sheet = WebUtil.selectStylesheet();
25 sheets = WebUtil.getStylesheets();
8db09746 26 for (i = 0; i < sheets.length; i += 1) {
8e0f0088 27 UI.addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title);
da6dd893 28 }
da6dd893
JM
29
30 // Logging selection dropdown
da6dd893 31 llevels = ['error', 'warn', 'info', 'debug'];
8db09746 32 for (i = 0; i < llevels.length; i += 1) {
8e0f0088 33 UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]);
da6dd893 34 }
53fc7392 35
da6dd893 36 // Settings with immediate effects
f7ec5b2c
JM
37 UI.initSetting('logging', 'warn');
38 WebUtil.init_logging(UI.getSetting('logging'));
39 UI.initSetting('stylesheet', 'default');
8db09746 40
8e0f0088
CG
41 WebUtil.selectStylesheet(null);
42 // call twice to get around webkit bug
f7ec5b2c 43 WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
da6dd893 44
91308399 45 /* Populate the controls if defaults are provided in the URL */
53fc7392 46 UI.initSetting('host', '');
f7ec5b2c
JM
47 UI.initSetting('port', '');
48 UI.initSetting('password', '');
49 UI.initSetting('encrypt', false);
50 UI.initSetting('true_color', true);
51 UI.initSetting('cursor', false);
53fc7392 52 UI.initSetting('shared', true);
f7ec5b2c
JM
53 UI.initSetting('connectTimeout', 2);
54
53fc7392 55 UI.rfb = RFB({'target': $D('noVNC_canvas'),
d890e864
JM
56 'onUpdateState': UI.updateState,
57 'onClipboard': UI.clipReceive});
53fc7392 58
8db09746 59 // Unfocus clipboard when over the VNC area
53fc7392
CG
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();
64 // }
65 // };
66
ad3f7624
JM
67 // Show mouse selector buttons on touch screen devices
68 if ('ontouchstart' in document.documentElement) {
53fc7392 69 $D('noVNC_mobile_buttons').style.display = "inline";
ad3f7624 70 UI.setMouseButton();
53fc7392 71 window.scrollTo(0, 1);
ad3f7624
JM
72 }
73
8e0f0088
CG
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))) {
79 UI.setOnscroll();
80 UI.setResize();
53fc7392 81 }
8e0f0088
CG
82
83 $D('noVNC_host').focus();
91308399
JM
84},
85
da6dd893
JM
86// Read form control compatible setting from cookie
87getSetting: function(name) {
53fc7392 88 var val, ctrl = $D('noVNC_' + name);
8d5d2c82 89 val = WebUtil.readCookie(name);
da6dd893
JM
90 if (ctrl.type === 'checkbox') {
91 if (val.toLowerCase() in {'0':1, 'no':1, 'false':1}) {
92 val = false;
93 } else {
94 val = true;
95 }
96 }
97 return val;
98},
99
100// Update cookie and form control setting. If value is not set, then
101// updates from control to current cookie setting.
102updateSetting: function(name, value) {
53fc7392
CG
103
104 var i, ctrl = $D('noVNC_' + name);
da6dd893
JM
105 // Save the cookie for this session
106 if (typeof value !== 'undefined') {
8d5d2c82 107 WebUtil.createCookie(name, value);
da6dd893 108 }
53fc7392
CG
109 if(name === 'host')
110 {
111
112
113 }
da6dd893 114 // Update the settings control
f7ec5b2c 115 value = UI.getSetting(name);
53fc7392 116
da6dd893
JM
117 if (ctrl.type === 'checkbox') {
118 ctrl.checked = value;
53fc7392 119
da6dd893 120 } else if (typeof ctrl.options !== 'undefined') {
8db09746 121 for (i = 0; i < ctrl.options.length; i += 1) {
da6dd893
JM
122 if (ctrl.options[i].value === value) {
123 ctrl.selectedIndex = i;
124 break;
125 }
126 }
127 } else {
8e0f0088
CG
128 /*Weird IE9 error leads to 'null' appearring
129 in textboxes instead of ''.*/
53fc7392
CG
130 if(value === null)
131 {
132 value = "";
133 }
da6dd893
JM
134 ctrl.value = value;
135 }
136},
137
138// Save control setting to cookie
139saveSetting: function(name) {
53fc7392 140 var val, ctrl = $D('noVNC_' + name);
da6dd893
JM
141 if (ctrl.type === 'checkbox') {
142 val = ctrl.checked;
143 } else if (typeof ctrl.options !== 'undefined') {
144 val = ctrl.options[ctrl.selectedIndex].value;
145 } else {
146 val = ctrl.value;
147 }
8d5d2c82 148 WebUtil.createCookie(name, val);
8db09746 149 //Util.Debug("Setting saved '" + name + "=" + val + "'");
da6dd893
JM
150 return val;
151},
152
153// Initial page load read/initialization of settings
154initSetting: function(name, defVal) {
a8edf9d8 155 var val;
da6dd893
JM
156
157 // Check Query string followed by cookie
8d5d2c82 158 val = WebUtil.getQueryVar(name);
da6dd893 159 if (val === null) {
8d5d2c82 160 val = WebUtil.readCookie(name, defVal);
da6dd893 161 }
f7ec5b2c 162 UI.updateSetting(name, val);
8e0f0088 163 //Util.Debug("Setting '" + name + "' initialized to '" + val + "'");
da6dd893
JM
164 return val;
165},
166
167
168// Toggle the settings menu:
169// On open, settings are refreshed from saved cookies.
170// On close, settings are applied
171clickSettingsMenu: function() {
f7ec5b2c
JM
172 if (UI.settingsOpen) {
173 UI.settingsApply();
da6dd893 174
f7ec5b2c 175 UI.closeSettingsMenu();
da6dd893 176 } else {
f7ec5b2c
JM
177 UI.updateSetting('encrypt');
178 UI.updateSetting('true_color');
d890e864 179 if (UI.rfb.get_display().get_cursor_uri()) {
f7ec5b2c 180 UI.updateSetting('cursor');
da6dd893 181 } else {
f7ec5b2c 182 UI.updateSetting('cursor', false);
53fc7392 183 $D('noVNC_cursor').disabled = true;
da6dd893 184 }
f7ec5b2c
JM
185 UI.updateSetting('shared');
186 UI.updateSetting('connectTimeout');
187 UI.updateSetting('stylesheet');
188 UI.updateSetting('logging');
da6dd893 189
f7ec5b2c 190 UI.openSettingsMenu();
da6dd893
JM
191 }
192},
193
194// Open menu
195openSettingsMenu: function() {
53fc7392
CG
196 if(UI.clipboardOpen == true)
197 {
198 UI.showClipboard();
199 }
200 //Close connection settings if open
8e0f0088
CG
201 if(UI.connSettingsOpen == true) {
202 UI.connectPanelbutton();
53fc7392
CG
203 }
204 $D('noVNC_Settings').style.display = "block";
f7ec5b2c 205 UI.settingsOpen = true;
da6dd893
JM
206},
207
208// Close menu (without applying settings)
209closeSettingsMenu: function() {
53fc7392 210 $D('noVNC_Settings').style.display = "none";
f7ec5b2c 211 UI.settingsOpen = false;
da6dd893
JM
212},
213
214// Disable/enable controls depending on connection state
b5087acc
JM
215settingsDisabled: function(disabled, rfb) {
216 //Util.Debug(">> settingsDisabled");
53fc7392
CG
217 $D('noVNC_encrypt').disabled = disabled;
218 $D('noVNC_true_color').disabled = disabled;
d890e864 219 if (rfb && rfb.get_display() && rfb.get_display().get_cursor_uri()) {
53fc7392 220 $D('noVNC_cursor').disabled = disabled;
da6dd893 221 } else {
f7ec5b2c 222 UI.updateSetting('cursor', false);
53fc7392 223 $D('noVNC_cursor').disabled = true;
da6dd893 224 }
53fc7392
CG
225 $D('noVNC_shared').disabled = disabled;
226 $D('noVNC_connectTimeout').disabled = disabled;
b5087acc 227 //Util.Debug("<< settingsDisabled");
da6dd893
JM
228},
229
230// Save/apply settings when 'Apply' button is pressed
231settingsApply: function() {
8db09746 232 //Util.Debug(">> settingsApply");
f7ec5b2c
JM
233 UI.saveSetting('encrypt');
234 UI.saveSetting('true_color');
d890e864 235 if (UI.rfb.get_display().get_cursor_uri()) {
f7ec5b2c 236 UI.saveSetting('cursor');
da6dd893 237 }
f7ec5b2c
JM
238 UI.saveSetting('shared');
239 UI.saveSetting('connectTimeout');
240 UI.saveSetting('stylesheet');
241 UI.saveSetting('logging');
da6dd893
JM
242
243 // Settings with immediate (non-connected related) effect
f7ec5b2c
JM
244 WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
245 WebUtil.init_logging(UI.getSetting('logging'));
8db09746 246 //Util.Debug("<< settingsApply");
da6dd893
JM
247},
248
249
250
f00b1e37 251setPassword: function() {
53fc7392 252 UI.rfb.sendPassword($D('noVNC_password').value);
8e0f0088
CG
253 //Reset connect button.
254 $D('noVNC_connect_button').value = "Connect";
255 $D('noVNC_connect_button').onclick = UI.Connect;
256 //Hide connection panel.
257 UI.connectPanelbutton();
f00b1e37
JM
258 return false;
259},
260
63708ff5 261sendCtrlAltDel: function() {
f7ec5b2c 262 UI.rfb.sendCtrlAltDel();
63708ff5
JM
263},
264
ad3f7624
JM
265setMouseButton: function(num) {
266 var b, blist = [1,2,4], button,
267 mouse = UI.rfb.get_mouse();
268
269 if (typeof num === 'undefined') {
270 // Show the default
271 num = mouse.get_touchButton();
272 } else if (num === mouse.get_touchButton()) {
273 // Set all buttons off (no clicks)
274 mouse.set_touchButton(0);
275 num = 0;
276 } else {
277 // Turn on one button
278 mouse.set_touchButton(num);
279 }
280
281 for (b = 0; b < blist.length; b++) {
53fc7392 282 button = $D('noVNC_mouse_button' + blist[b]);
ad3f7624
JM
283 if (blist[b] === num) {
284 button.style.backgroundColor = "black";
285 button.style.color = "lightgray";
286 } else {
287 button.style.backgroundColor = "";
288 button.style.color = "";
289 }
290 }
ad3f7624
JM
291},
292
8db09746 293updateState: function(rfb, state, oldstate, msg) {
a7a89626 294 var s, sb, c, cad, klass;
53fc7392
CG
295 s = $D('noVNC_status');
296 sb = $D('noVNC_status_bar');
8e0f0088 297 c = $D('connectPanelbutton');
e4671910 298 cad = $D('sendCtrlAltDelButton');
91308399
JM
299 switch (state) {
300 case 'failed':
f00b1e37 301 case 'fatal':
91308399 302 c.disabled = true;
8e0f0088 303 cad.style.display = "none";
f7ec5b2c 304 UI.settingsDisabled(true, rfb);
53fc7392 305 klass = "noVNC_status_error";
91308399 306 break;
8e0f0088 307 case 'normal':
91308399 308 c.value = "Disconnect";
f7ec5b2c 309 c.onclick = UI.disconnect;
91308399 310 c.disabled = false;
8e0f0088 311 cad.style.display = "block";
f7ec5b2c 312 UI.settingsDisabled(true, rfb);
53fc7392 313 klass = "noVNC_status_normal";
91308399
JM
314 break;
315 case 'disconnected':
8e0f0088
CG
316 $D('noVNC_defaultScreen').style.display = "block";
317 c.value = "Connection";
318 c.onclick = UI.connectPanelbutton;
f00b1e37 319 case 'loaded':
8e0f0088
CG
320 c.value = "Connection";
321 c.onclick = UI.connectPanelbutton;
91308399 322 c.disabled = false;
8e0f0088 323 cad.style.display = "none";
f7ec5b2c 324 UI.settingsDisabled(false, rfb);
53fc7392 325 klass = "noVNC_status_normal";
91308399 326 break;
f00b1e37 327 case 'password':
8e0f0088 328 UI.connectPanelbutton();
f00b1e37 329
8e0f0088
CG
330 $D('noVNC_connect_button').value = "Send Password";
331 $D('noVNC_connect_button').onclick = UI.setPassword;
332 $D('noVNC_password').focus();
333
f00b1e37 334 c.disabled = false;
8e0f0088 335 cad.style.display = "none";
f7ec5b2c 336 UI.settingsDisabled(true, rfb);
53fc7392 337 klass = "noVNC_status_warn";
f00b1e37 338 break;
91308399
JM
339 default:
340 c.disabled = true;
8e0f0088 341 cad.style.display = "none";
f7ec5b2c 342 UI.settingsDisabled(true, rfb);
53fc7392 343 klass = "noVNC_status_warn";
91308399
JM
344 break;
345 }
346
347 if (typeof(msg) !== 'undefined') {
348 s.setAttribute("class", klass);
63708ff5 349 sb.setAttribute("class", klass);
91308399
JM
350 s.innerHTML = msg;
351 }
352
353},
354
8db09746 355clipReceive: function(rfb, text) {
f7ec5b2c 356 Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
53fc7392 357 $D('noVNC_clipboard_text').value = text;
f7ec5b2c 358 Util.Debug("<< UI.clipReceive");
8db09746
JM
359},
360
361
91308399 362connect: function() {
f7ec5b2c 363 var host, port, password;
da6dd893 364
f7ec5b2c 365 UI.closeSettingsMenu();
8e0f0088
CG
366 UI.connectPanelbutton();
367
53fc7392
CG
368 host = $D('noVNC_host').value;
369 port = $D('noVNC_port').value;
370 password = $D('noVNC_password').value;
91308399 371 if ((!host) || (!port)) {
63708ff5 372 throw("Must set host and port");
91308399
JM
373 }
374
f7ec5b2c
JM
375 UI.rfb.set_encrypt(UI.getSetting('encrypt'));
376 UI.rfb.set_true_color(UI.getSetting('true_color'));
377 UI.rfb.set_local_cursor(UI.getSetting('cursor'));
378 UI.rfb.set_shared(UI.getSetting('shared'));
379 UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout'));
da6dd893 380
f7ec5b2c 381 UI.rfb.connect(host, port, password);
53fc7392
CG
382 //Close dialog.
383 setTimeout("setBarPosition()",100);
384 $D('noVNC_defaultScreen').style.display = "none";
91308399
JM
385},
386
387disconnect: function() {
f7ec5b2c 388 UI.closeSettingsMenu();
f7ec5b2c 389 UI.rfb.disconnect();
8e0f0088 390
53fc7392 391 $D('noVNC_defaultScreen').style.display = "block";
8e0f0088
CG
392 UI.connSettingsOpen = false;
393 UI.connectPanelbutton();
91308399
JM
394},
395
d890e864 396displayBlur: function() {
d1bd5ec7
JM
397 UI.rfb.get_keyboard().set_focused(false);
398 UI.rfb.get_mouse().set_focused(false);
91308399
JM
399},
400
d890e864 401displayFocus: function() {
d1bd5ec7
JM
402 UI.rfb.get_keyboard().set_focused(true);
403 UI.rfb.get_mouse().set_focused(true);
91308399
JM
404},
405
406clipClear: function() {
53fc7392 407 $D('noVNC_clipboard_text').value = "";
f7ec5b2c 408 UI.rfb.clipboardPasteFrom("");
91308399
JM
409},
410
411clipSend: function() {
53fc7392 412 var text = $D('noVNC_clipboard_text').value;
f7ec5b2c
JM
413 Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "...");
414 UI.rfb.clipboardPasteFrom(text);
415 Util.Debug("<< UI.clipSend");
53fc7392
CG
416},
417
418showClipboard: function() {
419 //Close settings if open
420 if(UI.settingsOpen == true) {
421 UI.closeSettingsMenu();
422 }
423 //Close connection settings if open
8e0f0088
CG
424 if(UI.connSettingsOpen == true) {
425 UI.connectPanelbutton();
53fc7392
CG
426 }
427 //Toggle Connection Panel
428 if(UI.clipboardOpen == true)
429 { $D('noVNC_clipboard').style.display = "none";
430 UI.clipboardOpen = false;
431 } else {
432 $D('noVNC_clipboard').style.display = "block";
433 UI.clipboardOpen = true;
434 }
8e0f0088 435},
91308399 436
7825b9ee 437
8e0f0088
CG
438showKeyboard: function() {
439 //Get Current Scroll Position
440 var scrollx =
441 (document.all)?document.body.scrollLeft:window.pageXOffset;
442 var scrolly =
443 (document.all)?document.body.scrollTop:window.pageYOffset;
7825b9ee 444
8e0f0088
CG
445 //Stop browser zooming on textbox.
446 UI.zoomDisable();
447 $D('keyboardinput').focus();
448 scroll(scrollx,scrolly);
449 //Renable user zoom.
450 UI.zoomEnable();
451},
7825b9ee 452
8e0f0088 453zoomDisable: function() {
7825b9ee 454 //Change viewport meta data to disable zooming.
8e0f0088
CG
455 UI.changeViewportMeta("user-scalable=0");
456},
7825b9ee 457
8e0f0088 458zoomEnable: function(){
7825b9ee 459 //Change viewport meta data to enable user zooming.
8e0f0088
CG
460 UI.changeViewportMeta("user-scalable=1");
461},
1734b5e4 462
8e0f0088 463changeViewportMeta: function (newattributes) {
1734b5e4
CG
464
465 // First, get the array of meta-tag elements
8e0f0088 466 var metatags = document.getElementsByTagName("meta");
1734b5e4
CG
467
468 // Update only the Viewport meta tag
469 for (var cnt = 0; cnt < metatags.length; cnt++)
470 {
471
472 var name = metatags[cnt].getAttribute("name");
473 var content = metatags[cnt].getAttribute("content");
474
475 // Update the Viewport meta tag
476 if (metatags[cnt].getAttribute("name") == "viewport")
477 metatags[cnt].setAttribute("content", newattributes);
478 }
8e0f0088 479},
53fc7392
CG
480
481//iOS < Version 5 does not support position fixed. Javascript workaround:
8e0f0088 482setOnscroll: function() {
53fc7392 483 window.onscroll = function() {
8e0f0088 484 UI.setBarPosition();
53fc7392 485 };
8e0f0088 486},
53fc7392 487
8e0f0088 488setResize: function () {
53fc7392 489 window.onResize = function() {
8e0f0088 490 UI.setBarPosition();
53fc7392 491 };
8e0f0088 492},
53fc7392 493
8e0f0088
CG
494//Helper to add options to dropdown.
495addOption: function(selectbox,text,value )
496{
497 var optn = document.createElement("OPTION");
498 optn.text = text;
499 optn.value = value;
500 selectbox.options.add(optn);
501},
502
503setBarPosition: function() {
c327865b
CG
504 $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px';
505 $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
506 $D('noVNC_mobile_buttons_right').style.right = 0 + 'px';
53fc7392 507
c327865b
CG
508 var vncwidth = $('#noVNC_screen').width();
509 $D('noVNC-control-bar').style.width = vncwidth + 'px';
8e0f0088 510},
53fc7392 511
8e0f0088
CG
512connectPanelbutton: function() {
513 //Close connection settings if open
514 if(UI.settingsOpen == true) {
515 UI.closeSettingsMenu();
516 }
517 if(UI.clipboardOpen == true)
518 {
519 UI.showClipboard();
520 }
521
522 //Toggle Connection Panel
523 if(UI.connSettingsOpen == true)
524 {
525 $D('noVNC_controls').style.display = "none";
526 UI.connSettingsOpen = false;
527 } else {
528 $D('noVNC_controls').style.display = "block";
529 UI.connSettingsOpen = true;
530 $D('noVNC_host').focus();
531 }
53fc7392 532}
8e0f0088
CG
533
534};
535
536
537
538