]> git.proxmox.com Git - mirror_novnc.git/blob - include/ui.js
Merge pull request #269 from phildriscoll/master
[mirror_novnc.git] / include / ui.js
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 "use strict";
11 /*jslint white: false, browser: true */
12 /*global window, $D, Util, WebUtil, RFB, Display */
13
14 // Load supporting scripts
15 window.onscriptsload = function () { UI.load(); };
16 Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
17 "input.js", "display.js", "jsunzip.js", "rfb.js"]);
18
19 var UI = {
20
21 rfb_state : 'loaded',
22 settingsOpen : false,
23 connSettingsOpen : false,
24 popupStatusOpen : false,
25 clipboardOpen: false,
26 keyboardVisible: false,
27
28 // Setup rfb object, load settings from browser storage, then call
29 // UI.init to setup the UI/menus
30 load: function (callback) {
31 WebUtil.initSettings(UI.start, callback);
32 },
33
34 // Render default UI and initialize settings menu
35 start: function(callback) {
36 var html = '', i, sheet, sheets, llevels, port;
37
38 // Stylesheet selection dropdown
39 sheet = WebUtil.selectStylesheet();
40 sheets = WebUtil.getStylesheets();
41 for (i = 0; i < sheets.length; i += 1) {
42 UI.addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title);
43 }
44
45 // Logging selection dropdown
46 llevels = ['error', 'warn', 'info', 'debug'];
47 for (i = 0; i < llevels.length; i += 1) {
48 UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]);
49 }
50
51 // Settings with immediate effects
52 UI.initSetting('logging', 'warn');
53 WebUtil.init_logging(UI.getSetting('logging'));
54
55 UI.initSetting('stylesheet', 'default');
56 WebUtil.selectStylesheet(null);
57 // call twice to get around webkit bug
58 WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
59
60 // if port == 80 (or 443) then it won't be present and should be
61 // set manually
62 port = window.location.port;
63 if (!port) {
64 if (window.location.protocol.substring(0,5) == 'https') {
65 port = 443;
66 }
67 else if (window.location.protocol.substring(0,4) == 'http') {
68 port = 80;
69 }
70 }
71
72 /* Populate the controls if defaults are provided in the URL */
73 UI.initSetting('host', window.location.hostname);
74 UI.initSetting('port', port);
75 UI.initSetting('password', '');
76 UI.initSetting('encrypt', (window.location.protocol === "https:"));
77 UI.initSetting('true_color', true);
78 UI.initSetting('cursor', false);
79 UI.initSetting('shared', true);
80 UI.initSetting('view_only', false);
81 UI.initSetting('connectTimeout', 2);
82 UI.initSetting('path', 'websockify');
83 UI.initSetting('repeaterID', '');
84
85 UI.rfb = RFB({'target': $D('noVNC_canvas'),
86 'onUpdateState': UI.updateState,
87 'onClipboard': UI.clipReceive,
88 'onDesktopName': UI.updateDocumentTitle});
89 UI.updateVisualState();
90
91 // Unfocus clipboard when over the VNC area
92 //$D('VNC_screen').onmousemove = function () {
93 // var keyboard = UI.rfb.get_keyboard();
94 // if ((! keyboard) || (! keyboard.get_focused())) {
95 // $D('VNC_clipboard_text').blur();
96 // }
97 // };
98
99 // Show mouse selector buttons on touch screen devices
100 if ('ontouchstart' in document.documentElement) {
101 // Show mobile buttons
102 $D('noVNC_mobile_buttons').style.display = "inline";
103 UI.setMouseButton();
104 // Remove the address bar
105 setTimeout(function() { window.scrollTo(0, 1); }, 100);
106 UI.forceSetting('clip', true);
107 $D('noVNC_clip').disabled = true;
108 } else {
109 UI.initSetting('clip', false);
110 }
111
112 //iOS Safari does not support CSS position:fixed.
113 //This detects iOS devices and enables javascript workaround.
114 if ((navigator.userAgent.match(/iPhone/i)) ||
115 (navigator.userAgent.match(/iPod/i)) ||
116 (navigator.userAgent.match(/iPad/i))) {
117 //UI.setOnscroll();
118 //UI.setResize();
119 }
120 UI.setBarPosition();
121
122 $D('noVNC_host').focus();
123
124 UI.setViewClip();
125 Util.addEvent(window, 'resize', UI.setViewClip);
126
127 Util.addEvent(window, 'beforeunload', function () {
128 if (UI.rfb_state === 'normal') {
129 return "You are currently connected.";
130 }
131 } );
132
133 // Show description by default when hosted at for kanaka.github.com
134 if (location.host === "kanaka.github.com") {
135 // Open the description dialog
136 $D('noVNC_description').style.display = "block";
137 } else {
138 // Open the connect panel on first load
139 UI.toggleConnectPanel();
140 }
141
142 // Add mouse event click/focus/blur event handlers to the UI
143 UI.addMouseHandlers();
144
145 if (typeof callback === "function") {
146 callback(UI.rfb);
147 }
148 },
149
150 addMouseHandlers: function() {
151 // Setup interface handlers that can't be inline
152 $D("noVNC_view_drag_button").onclick = UI.setViewDrag;
153 $D("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); };
154 $D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); };
155 $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
156 $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
157 $D("showKeyboard").onclick = UI.showKeyboard;
158 //$D("keyboardinput").onkeydown = function (event) { onKeyDown(event); };
159 $D("keyboardinput").onblur = UI.keyInputBlur;
160
161 $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel;
162 $D("noVNC_status").onclick = UI.togglePopupStatusPanel;
163 $D("noVNC_popup_status_panel").onclick = UI.togglePopupStatusPanel;
164 $D("clipboardButton").onclick = UI.toggleClipboardPanel;
165 $D("settingsButton").onclick = UI.toggleSettingsPanel;
166 $D("connectButton").onclick = UI.toggleConnectPanel;
167 $D("disconnectButton").onclick = UI.disconnect;
168 $D("descriptionButton").onclick = UI.toggleConnectPanel;
169
170 $D("noVNC_clipboard_text").onfocus = UI.displayBlur;
171 $D("noVNC_clipboard_text").onblur = UI.displayFocus;
172 $D("noVNC_clipboard_text").onchange = UI.clipSend;
173 $D("noVNC_clipboard_clear_button").onclick = UI.clipClear;
174
175 $D("noVNC_settings_menu").onmouseover = UI.displayBlur;
176 $D("noVNC_settings_menu").onmouseover = UI.displayFocus;
177 $D("noVNC_apply").onclick = UI.settingsApply;
178
179 $D("noVNC_connect_button").onclick = UI.connect;
180 },
181
182 // Read form control compatible setting from cookie
183 getSetting: function(name) {
184 var val, ctrl = $D('noVNC_' + name);
185 val = WebUtil.readSetting(name);
186 if (val !== null && ctrl.type === 'checkbox') {
187 if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) {
188 val = false;
189 } else {
190 val = true;
191 }
192 }
193 return val;
194 },
195
196 // Update cookie and form control setting. If value is not set, then
197 // updates from control to current cookie setting.
198 updateSetting: function(name, value) {
199
200 var i, ctrl = $D('noVNC_' + name);
201 // Save the cookie for this session
202 if (typeof value !== 'undefined') {
203 WebUtil.writeSetting(name, value);
204 }
205
206 // Update the settings control
207 value = UI.getSetting(name);
208
209 if (ctrl.type === 'checkbox') {
210 ctrl.checked = value;
211
212 } else if (typeof ctrl.options !== 'undefined') {
213 for (i = 0; i < ctrl.options.length; i += 1) {
214 if (ctrl.options[i].value === value) {
215 ctrl.selectedIndex = i;
216 break;
217 }
218 }
219 } else {
220 /*Weird IE9 error leads to 'null' appearring
221 in textboxes instead of ''.*/
222 if (value === null) {
223 value = "";
224 }
225 ctrl.value = value;
226 }
227 },
228
229 // Save control setting to cookie
230 saveSetting: function(name) {
231 var val, ctrl = $D('noVNC_' + name);
232 if (ctrl.type === 'checkbox') {
233 val = ctrl.checked;
234 } else if (typeof ctrl.options !== 'undefined') {
235 val = ctrl.options[ctrl.selectedIndex].value;
236 } else {
237 val = ctrl.value;
238 }
239 WebUtil.writeSetting(name, val);
240 //Util.Debug("Setting saved '" + name + "=" + val + "'");
241 return val;
242 },
243
244 // Initial page load read/initialization of settings
245 initSetting: function(name, defVal) {
246 var val;
247
248 // Check Query string followed by cookie
249 val = WebUtil.getQueryVar(name);
250 if (val === null) {
251 val = WebUtil.readSetting(name, defVal);
252 }
253 UI.updateSetting(name, val);
254 //Util.Debug("Setting '" + name + "' initialized to '" + val + "'");
255 return val;
256 },
257
258 // Force a setting to be a certain value
259 forceSetting: function(name, val) {
260 UI.updateSetting(name, val);
261 return val;
262 },
263
264
265 // Show the popup status panel
266 togglePopupStatusPanel: function() {
267 var psp = $D('noVNC_popup_status_panel');
268 if (UI.popupStatusOpen === true) {
269 psp.style.display = "none";
270 UI.popupStatusOpen = false;
271 } else {
272 psp.innerHTML = $D('noVNC_status').innerHTML;
273 psp.style.display = "block";
274 psp.style.left = window.innerWidth/2 -
275 parseInt(window.getComputedStyle(psp, false).width)/2 -30 + "px";
276 UI.popupStatusOpen = true;
277 }
278 },
279
280 // Show the clipboard panel
281 toggleClipboardPanel: function() {
282 // Close the description panel
283 $D('noVNC_description').style.display = "none";
284 // Close settings if open
285 if (UI.settingsOpen === true) {
286 UI.settingsApply();
287 UI.closeSettingsMenu();
288 }
289 // Close connection settings if open
290 if (UI.connSettingsOpen === true) {
291 UI.toggleConnectPanel();
292 }
293 // Close popup status panel if open
294 if (UI.popupStatusOpen === true) {
295 UI.togglePopupStatusPanel();
296 }
297 // Toggle Clipboard Panel
298 if (UI.clipboardOpen === true) {
299 $D('noVNC_clipboard').style.display = "none";
300 $D('clipboardButton').className = "noVNC_status_button";
301 UI.clipboardOpen = false;
302 } else {
303 $D('noVNC_clipboard').style.display = "block";
304 $D('clipboardButton').className = "noVNC_status_button_selected";
305 UI.clipboardOpen = true;
306 }
307 },
308
309 // Show the connection settings panel/menu
310 toggleConnectPanel: function() {
311 // Close the description panel
312 $D('noVNC_description').style.display = "none";
313 // Close connection settings if open
314 if (UI.settingsOpen === true) {
315 UI.settingsApply();
316 UI.closeSettingsMenu();
317 $D('connectButton').className = "noVNC_status_button";
318 }
319 // Close clipboard panel if open
320 if (UI.clipboardOpen === true) {
321 UI.toggleClipboardPanel();
322 }
323 // Close popup status panel if open
324 if (UI.popupStatusOpen === true) {
325 UI.togglePopupStatusPanel();
326 }
327
328 // Toggle Connection Panel
329 if (UI.connSettingsOpen === true) {
330 $D('noVNC_controls').style.display = "none";
331 $D('connectButton').className = "noVNC_status_button";
332 UI.connSettingsOpen = false;
333 UI.saveSetting('host');
334 UI.saveSetting('port');
335 //UI.saveSetting('password');
336 } else {
337 $D('noVNC_controls').style.display = "block";
338 $D('connectButton').className = "noVNC_status_button_selected";
339 UI.connSettingsOpen = true;
340 $D('noVNC_host').focus();
341 }
342 },
343
344 // Toggle the settings menu:
345 // On open, settings are refreshed from saved cookies.
346 // On close, settings are applied
347 toggleSettingsPanel: function() {
348 // Close the description panel
349 $D('noVNC_description').style.display = "none";
350 if (UI.settingsOpen) {
351 UI.settingsApply();
352 UI.closeSettingsMenu();
353 } else {
354 UI.updateSetting('encrypt');
355 UI.updateSetting('true_color');
356 if (UI.rfb.get_display().get_cursor_uri()) {
357 UI.updateSetting('cursor');
358 } else {
359 UI.updateSetting('cursor', false);
360 $D('noVNC_cursor').disabled = true;
361 }
362 UI.updateSetting('clip');
363 UI.updateSetting('shared');
364 UI.updateSetting('view_only');
365 UI.updateSetting('connectTimeout');
366 UI.updateSetting('path');
367 UI.updateSetting('repeaterID');
368 UI.updateSetting('stylesheet');
369 UI.updateSetting('logging');
370
371 UI.openSettingsMenu();
372 }
373 },
374
375 // Open menu
376 openSettingsMenu: function() {
377 // Close the description panel
378 $D('noVNC_description').style.display = "none";
379 // Close clipboard panel if open
380 if (UI.clipboardOpen === true) {
381 UI.toggleClipboardPanel();
382 }
383 // Close connection settings if open
384 if (UI.connSettingsOpen === true) {
385 UI.toggleConnectPanel();
386 }
387 // Close popup status panel if open
388 if (UI.popupStatusOpen === true) {
389 UI.togglePopupStatusPanel();
390 }
391 $D('noVNC_settings').style.display = "block";
392 $D('settingsButton').className = "noVNC_status_button_selected";
393 UI.settingsOpen = true;
394 },
395
396 // Close menu (without applying settings)
397 closeSettingsMenu: function() {
398 $D('noVNC_settings').style.display = "none";
399 $D('settingsButton').className = "noVNC_status_button";
400 UI.settingsOpen = false;
401 },
402
403 // Save/apply settings when 'Apply' button is pressed
404 settingsApply: function() {
405 //Util.Debug(">> settingsApply");
406 UI.saveSetting('encrypt');
407 UI.saveSetting('true_color');
408 if (UI.rfb.get_display().get_cursor_uri()) {
409 UI.saveSetting('cursor');
410 }
411 UI.saveSetting('clip');
412 UI.saveSetting('shared');
413 UI.saveSetting('view_only');
414 UI.saveSetting('connectTimeout');
415 UI.saveSetting('path');
416 UI.saveSetting('repeaterID');
417 UI.saveSetting('stylesheet');
418 UI.saveSetting('logging');
419
420 // Settings with immediate (non-connected related) effect
421 WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
422 WebUtil.init_logging(UI.getSetting('logging'));
423 UI.setViewClip();
424 UI.setViewDrag(UI.rfb.get_viewportDrag());
425 //Util.Debug("<< settingsApply");
426 },
427
428
429
430 setPassword: function() {
431 UI.rfb.sendPassword($D('noVNC_password').value);
432 //Reset connect button.
433 $D('noVNC_connect_button').value = "Connect";
434 $D('noVNC_connect_button').onclick = UI.Connect;
435 //Hide connection panel.
436 UI.toggleConnectPanel();
437 return false;
438 },
439
440 sendCtrlAltDel: function() {
441 UI.rfb.sendCtrlAltDel();
442 },
443
444 setMouseButton: function(num) {
445 var b, blist = [0, 1,2,4], button;
446
447 if (typeof num === 'undefined') {
448 // Disable mouse buttons
449 num = -1;
450 }
451 if (UI.rfb) {
452 UI.rfb.get_mouse().set_touchButton(num);
453 }
454
455 for (b = 0; b < blist.length; b++) {
456 button = $D('noVNC_mouse_button' + blist[b]);
457 if (blist[b] === num) {
458 button.style.display = "";
459 } else {
460 button.style.display = "none";
461 /*
462 button.style.backgroundColor = "black";
463 button.style.color = "lightgray";
464 button.style.backgroundColor = "";
465 button.style.color = "";
466 */
467 }
468 }
469 },
470
471 updateState: function(rfb, state, oldstate, msg) {
472 var s, sb, c, d, cad, vd, klass;
473 UI.rfb_state = state;
474 switch (state) {
475 case 'failed':
476 case 'fatal':
477 klass = "noVNC_status_error";
478 break;
479 case 'normal':
480 klass = "noVNC_status_normal";
481 break;
482 case 'disconnected':
483 $D('noVNC_logo').style.display = "block";
484 // Fall through
485 case 'loaded':
486 klass = "noVNC_status_normal";
487 break;
488 case 'password':
489 UI.toggleConnectPanel();
490
491 $D('noVNC_connect_button').value = "Send Password";
492 $D('noVNC_connect_button').onclick = UI.setPassword;
493 $D('noVNC_password').focus();
494
495 klass = "noVNC_status_warn";
496 break;
497 default:
498 klass = "noVNC_status_warn";
499 break;
500 }
501
502 if (typeof(msg) !== 'undefined') {
503 $D('noVNC-control-bar').setAttribute("class", klass);
504 $D('noVNC_status').innerHTML = msg;
505 }
506
507 UI.updateVisualState();
508 },
509
510 // Disable/enable controls depending on connection state
511 updateVisualState: function() {
512 var connected = UI.rfb_state === 'normal' ? true : false;
513
514 //Util.Debug(">> updateVisualState");
515 $D('noVNC_encrypt').disabled = connected;
516 $D('noVNC_true_color').disabled = connected;
517 if (UI.rfb && UI.rfb.get_display() &&
518 UI.rfb.get_display().get_cursor_uri()) {
519 $D('noVNC_cursor').disabled = connected;
520 } else {
521 UI.updateSetting('cursor', false);
522 $D('noVNC_cursor').disabled = true;
523 }
524 $D('noVNC_shared').disabled = connected;
525 $D('noVNC_view_only').disabled = connected;
526 $D('noVNC_connectTimeout').disabled = connected;
527 $D('noVNC_path').disabled = connected;
528 $D('noVNC_repeaterID').disabled = connected;
529
530 if (connected) {
531 UI.setViewClip();
532 UI.setMouseButton(1);
533 $D('clipboardButton').style.display = "inline";
534 $D('showKeyboard').style.display = "inline";
535 $D('sendCtrlAltDelButton').style.display = "inline";
536 } else {
537 UI.setMouseButton();
538 $D('clipboardButton').style.display = "none";
539 $D('showKeyboard').style.display = "none";
540 $D('sendCtrlAltDelButton').style.display = "none";
541 }
542 // State change disables viewport dragging.
543 // It is enabled (toggled) by direct click on the button
544 UI.setViewDrag(false);
545
546 switch (UI.rfb_state) {
547 case 'fatal':
548 case 'failed':
549 case 'loaded':
550 case 'disconnected':
551 $D('connectButton').style.display = "";
552 $D('disconnectButton').style.display = "none";
553 break;
554 default:
555 $D('connectButton').style.display = "none";
556 $D('disconnectButton').style.display = "";
557 break;
558 }
559
560 //Util.Debug("<< updateVisualState");
561 },
562
563
564 // Display the desktop name in the document title
565 updateDocumentTitle: function(rfb, name) {
566 document.title = name + " - noVNC";
567 },
568
569
570 clipReceive: function(rfb, text) {
571 Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
572 $D('noVNC_clipboard_text').value = text;
573 Util.Debug("<< UI.clipReceive");
574 },
575
576
577 connect: function() {
578 var host, port, password, path;
579
580 UI.closeSettingsMenu();
581 UI.toggleConnectPanel();
582
583 host = $D('noVNC_host').value;
584 port = $D('noVNC_port').value;
585 password = $D('noVNC_password').value;
586 path = $D('noVNC_path').value;
587 if ((!host) || (!port)) {
588 throw("Must set host and port");
589 }
590
591 UI.rfb.set_encrypt(UI.getSetting('encrypt'));
592 UI.rfb.set_true_color(UI.getSetting('true_color'));
593 UI.rfb.set_local_cursor(UI.getSetting('cursor'));
594 UI.rfb.set_shared(UI.getSetting('shared'));
595 UI.rfb.set_view_only(UI.getSetting('view_only'));
596 UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout'));
597 UI.rfb.set_repeaterID(UI.getSetting('repeaterID'));
598
599 UI.rfb.connect(host, port, password, path);
600
601 //Close dialog.
602 setTimeout(UI.setBarPosition, 100);
603 $D('noVNC_logo').style.display = "none";
604 },
605
606 disconnect: function() {
607 UI.closeSettingsMenu();
608 UI.rfb.disconnect();
609
610 $D('noVNC_logo').style.display = "block";
611 UI.connSettingsOpen = false;
612 UI.toggleConnectPanel();
613 },
614
615 displayBlur: function() {
616 UI.rfb.get_keyboard().set_focused(false);
617 UI.rfb.get_mouse().set_focused(false);
618 },
619
620 displayFocus: function() {
621 UI.rfb.get_keyboard().set_focused(true);
622 UI.rfb.get_mouse().set_focused(true);
623 },
624
625 clipClear: function() {
626 $D('noVNC_clipboard_text').value = "";
627 UI.rfb.clipboardPasteFrom("");
628 },
629
630 clipSend: function() {
631 var text = $D('noVNC_clipboard_text').value;
632 Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "...");
633 UI.rfb.clipboardPasteFrom(text);
634 Util.Debug("<< UI.clipSend");
635 },
636
637
638 // Enable/disable and configure viewport clipping
639 setViewClip: function(clip) {
640 var display, cur_clip, pos, new_w, new_h;
641
642 if (UI.rfb) {
643 display = UI.rfb.get_display();
644 } else {
645 return;
646 }
647
648 cur_clip = display.get_viewport();
649
650 if (typeof(clip) !== 'boolean') {
651 // Use current setting
652 clip = UI.getSetting('clip');
653 }
654
655 if (clip && !cur_clip) {
656 // Turn clipping on
657 UI.updateSetting('clip', true);
658 } else if (!clip && cur_clip) {
659 // Turn clipping off
660 UI.updateSetting('clip', false);
661 display.set_viewport(false);
662 $D('noVNC_canvas').style.position = 'static';
663 display.viewportChange();
664 }
665 if (UI.getSetting('clip')) {
666 // If clipping, update clipping settings
667 $D('noVNC_canvas').style.position = 'absolute';
668 pos = Util.getPosition($D('noVNC_canvas'));
669 new_w = window.innerWidth - pos.x;
670 new_h = window.innerHeight - pos.y;
671 display.set_viewport(true);
672 display.viewportChange(0, 0, new_w, new_h);
673 }
674 },
675
676 // Toggle/set/unset the viewport drag/move button
677 setViewDrag: function(drag) {
678 var vmb = $D('noVNC_view_drag_button');
679 if (!UI.rfb) { return; }
680
681 if (UI.rfb_state === 'normal' &&
682 UI.rfb.get_display().get_viewport()) {
683 vmb.style.display = "inline";
684 } else {
685 vmb.style.display = "none";
686 }
687
688 if (typeof(drag) === "undefined" ||
689 typeof(drag) === "object") {
690 // If not specified, then toggle
691 drag = !UI.rfb.get_viewportDrag();
692 }
693 if (drag) {
694 vmb.className = "noVNC_status_button_selected";
695 UI.rfb.set_viewportDrag(true);
696 } else {
697 vmb.className = "noVNC_status_button";
698 UI.rfb.set_viewportDrag(false);
699 }
700 },
701
702 // On touch devices, show the OS keyboard
703 showKeyboard: function() {
704 if(UI.keyboardVisible === false) {
705 $D('keyboardinput').focus();
706 UI.keyboardVisible = true;
707 $D('showKeyboard').className = "noVNC_status_button_selected";
708 } else if(UI.keyboardVisible === true) {
709 $D('keyboardinput').blur();
710 $D('showKeyboard').className = "noVNC_status_button";
711 UI.keyboardVisible = false;
712 }
713 },
714
715 keyInputBlur: function() {
716 $D('showKeyboard').className = "noVNC_status_button";
717 //Weird bug in iOS if you change keyboardVisible
718 //here it does not actually occur so next time
719 //you click keyboard icon it doesnt work.
720 setTimeout(function() { UI.setKeyboard(); },100);
721 },
722
723 setKeyboard: function() {
724 UI.keyboardVisible = false;
725 },
726
727 // iOS < Version 5 does not support position fixed. Javascript workaround:
728 setOnscroll: function() {
729 window.onscroll = function() {
730 UI.setBarPosition();
731 };
732 },
733
734 setResize: function () {
735 window.onResize = function() {
736 UI.setBarPosition();
737 };
738 },
739
740 //Helper to add options to dropdown.
741 addOption: function(selectbox,text,value )
742 {
743 var optn = document.createElement("OPTION");
744 optn.text = text;
745 optn.value = value;
746 selectbox.options.add(optn);
747 },
748
749 setBarPosition: function() {
750 $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px';
751 $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
752
753 var vncwidth = $D('noVNC_screen').style.offsetWidth;
754 $D('noVNC-control-bar').style.width = vncwidth + 'px';
755 }
756
757 };
758
759
760
761