Forráskód Böngészése

Merge branch 'ui-cleanup' of https://github.com/kanaka/noVNC

samhed 9 éve
szülő
commit
5fd3f88e50
7 módosított fájl, 704 hozzáadás és 638 törlés
  1. 0 0
      images/toggleextrakeys.png
  2. 32 31
      include/base.css
  3. 1 1
      include/black.css
  4. 1 1
      include/blue.css
  5. 2 0
      include/rfb.js
  6. 614 551
      include/ui.js
  7. 54 54
      vnc.html

+ 0 - 0
images/showextrakeys.png → images/toggleextrakeys.png


+ 32 - 31
include/base.css

@@ -1,7 +1,7 @@
 /*
 /*
  * noVNC base CSS
  * noVNC base CSS
  * Copyright (C) 2012 Joel Martin
  * Copyright (C) 2012 Joel Martin
- * Copyright (C) 2013 Samuel Mannehed for Cendio AB
+ * Copyright (C) 2016 Samuel Mannehed for Cendio AB
  * noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
  * noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
  * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
  * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
  */
  */
@@ -30,18 +30,18 @@ html {
   padding-bottom:8px;
   padding-bottom:8px;
 }
 }
 
 
-#noVNC_host {
+#noVNC_setting_host {
   width:150px;
   width:150px;
 }
 }
-#noVNC_port {
+#noVNC_setting_port {
   width: 80px;
   width: 80px;
 }
 }
-#noVNC_password {
+#noVNC_setting_password {
   width: 150px;
   width: 150px;
 }
 }
-#noVNC_encrypt {
+#noVNC_setting_encrypt {
 }
 }
-#noVNC_path {
+#noVNC_setting_path {
   width: 100px;
   width: 100px;
 }
 }
 #noVNC_connect_button {
 #noVNC_connect_button {
@@ -56,10 +56,10 @@ html {
 #noVNC_view_drag_button {
 #noVNC_view_drag_button {
   display: none;
   display: none;
 }
 }
-#sendCtrlAltDelButton {
+#noVNC_sendCtrlAltDel_button {
   display: none;
   display: none;
 }
 }
-#fullscreenButton {
+#noVNC_fullscreen_button {
   display: none;
   display: none;
 }
 }
 #noVNC_xvp_buttons {
 #noVNC_xvp_buttons {
@@ -77,13 +77,13 @@ html {
   position: relative;
   position: relative;
 }
 }
 
 
-.noVNC-buttons-left {
+.noVNC_buttons_left {
   float: left;
   float: left;
   z-index: 1;
   z-index: 1;
   position: relative;
   position: relative;
 }
 }
 
 
-.noVNC-buttons-right {
+.noVNC_buttons_right {
   float:right;
   float:right;
   right: 0px;
   right: 0px;
   z-index: 2;
   z-index: 2;
@@ -109,13 +109,11 @@ html {
   padding: 0px;
   padding: 0px;
 }
 }
 
 
-#noVNC_apply {
+#noVNC_settings_apply {
   float:right;
   float:right;
 }
 }
 
 
-/* Do not set width/height for VNC_screen or VNC_canvas or incorrect
- * scaling will occur. Canvas resizes to remote VNC settings */
-#noVNC_screen {
+#noVNC_container {
   display: table;
   display: table;
   width:100%;
   width:100%;
   height:100%;
   height:100%;
@@ -124,7 +122,7 @@ html {
   /*border-top-left-radius: 800px 600px;*/
   /*border-top-left-radius: 800px 600px;*/
 }
 }
 
 
-#noVNC_container {
+#noVNC_screen {
   display: none;
   display: none;
   position: absolute;
   position: absolute;
   margin: 0px;
   margin: 0px;
@@ -137,6 +135,9 @@ html {
   height: auto;
   height: auto;
 }
 }
 
 
+/* Do not set width/height for VNC_canvas or incorrect
+ * scaling will occur. Canvas size depends on remote VNC
+ * settings and noVNC settings. */
 #noVNC_canvas {
 #noVNC_canvas {
   position: absolute;
   position: absolute;
   left: 0;
   left: 0;
@@ -232,7 +233,7 @@ html {
   right:85px;
   right:85px;
 }
 }
 
 
-#keyboardinput {
+#noVNC_keyboardinput {
   width:1px;
   width:1px;
   height:1px;
   height:1px;
   background-color:#fff;
   background-color:#fff;
@@ -277,7 +278,7 @@ html {
 }
 }
 
 
 /* Control bar */
 /* Control bar */
-#noVNC-control-bar {
+#noVNC_control_bar {
   position:fixed;
   position:fixed;
   
   
   display:block;
   display:block;
@@ -426,11 +427,11 @@ html {
   font-size: 180px;
   font-size: 180px;
 }
 }
 
 
-.noVNC-buttons-left {
+.noVNC_buttons_left {
   padding-left: 10px;
   padding-left: 10px;
 }
 }
 
 
-.noVNC-buttons-right {
+.noVNC_buttons_right {
   padding-right: 10px;
   padding-right: 10px;
 }
 }
 
 
@@ -441,11 +442,11 @@ html {
   margin-left: 0px;
   margin-left: 0px;
 }
 }
 
 
-#showExtraKeysButton { display: none; }
-#toggleCtrlButton { display: inline; }
-#toggleAltButton {  display: inline; }
-#sendTabButton { display: inline; }
-#sendEscButton { display: inline; }
+#noVNC_toggleExtraKeys_button { display: none; }
+#noVNC_toggleCtrl_button { display: inline; }
+#noVNC_toggleAlt_button {  display: inline; }
+#noVNC_sendTab_button { display: inline; }
+#noVNC_sendEsc_button { display: inline; }
 
 
 /* left-align the status text on lower resolutions */
 /* left-align the status text on lower resolutions */
 @media screen and (max-width: 800px){
 @media screen and (max-width: 800px){
@@ -468,35 +469,35 @@ html {
   .noVNC_status_button {
   .noVNC_status_button {
     font-size: 10px;
     font-size: 10px;
   }
   }
-  .noVNC-buttons-left {
+  .noVNC_buttons_left {
     padding-left: 0px;
     padding-left: 0px;
   }
   }
-  .noVNC-buttons-right {
+  .noVNC_buttons_right {
     padding-right: 0px;
     padding-right: 0px;
   }
   }
   /* collapse the extra keys on lower resolutions */
   /* collapse the extra keys on lower resolutions */
-  #showExtraKeysButton {
+  #noVNC_toggleExtraKeys_button {
     display: inline;
     display: inline;
   }
   }
-  #toggleCtrlButton {
+  #noVNC_toggleCtrl_button {
     display: none;
     display: none;
     position: absolute;
     position: absolute;
     top: 30px;
     top: 30px;
     left: 0px;
     left: 0px;
   }
   }
-  #toggleAltButton {
+  #noVNC_toggleAlt_button {
     display: none;
     display: none;
     position: absolute;
     position: absolute;
     top: 65px;
     top: 65px;
     left: 0px;
     left: 0px;
   }
   }
-  #sendTabButton {
+  #noVNC_sendTab_button {
     display: none;
     display: none;
     position: absolute;
     position: absolute;
     top: 100px;
     top: 100px;
     left: 0px;
     left: 0px;
   }
   }
-  #sendEscButton {
+  #noVNC_sendEsc_button {
     display: none;
     display: none;
     position: absolute;
     position: absolute;
     top: 135px;
     top: 135px;

+ 1 - 1
include/black.css

@@ -6,7 +6,7 @@
  * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
  * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
  */
  */
 
 
-#keyboardinput {
+#noVNC_keyboardinput {
   background-color:#000;
   background-color:#000;
 }
 }
 
 

+ 1 - 1
include/blue.css

@@ -58,7 +58,7 @@
   color:#fff;
   color:#fff;
 }
 }
 
 
-#keyboardinput {
+#noVNC_keyboardinput {
   background-color:#04073d;
   background-color:#04073d;
 }
 }
 
 

+ 2 - 0
include/rfb.js

@@ -311,6 +311,8 @@ var RFB;
             this._sock.flush();
             this._sock.flush();
         },
         },
 
 
+        // Requests a change of remote desktop size. This message is an extension
+        // and may only be sent if we have received an ExtendedDesktopSize message
         requestDesktopSize: function (width, height) {
         requestDesktopSize: function (width, height) {
             if (this._rfb_state !== "normal") { return; }
             if (this._rfb_state !== "normal") { return; }
 
 

+ 614 - 551
include/ui.js

@@ -1,7 +1,7 @@
 /*
 /*
  * noVNC: HTML5 VNC client
  * noVNC: HTML5 VNC client
  * Copyright (C) 2012 Joel Martin
  * Copyright (C) 2012 Joel Martin
- * Copyright (C) 2015 Samuel Mannehed for Cendio AB
+ * Copyright (C) 2016 Samuel Mannehed for Cendio AB
  * Licensed under MPL 2.0 (see LICENSE.txt)
  * Licensed under MPL 2.0 (see LICENSE.txt)
  *
  *
  * See README.md for usage and integration instructions.
  * See README.md for usage and integration instructions.
@@ -47,7 +47,7 @@ var UI;
 
 
         // Setup rfb object, load settings from browser storage, then call
         // Setup rfb object, load settings from browser storage, then call
         // UI.init to setup the UI/menus
         // UI.init to setup the UI/menus
-        load: function (callback) {
+        load: function(callback) {
             WebUtil.initSettings(UI.start, callback);
             WebUtil.initSettings(UI.start, callback);
         },
         },
 
 
@@ -60,13 +60,13 @@ var UI;
             var sheets = WebUtil.getStylesheets();
             var sheets = WebUtil.getStylesheets();
             var i;
             var i;
             for (i = 0; i < sheets.length; i += 1) {
             for (i = 0; i < sheets.length; i += 1) {
-                UI.addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title);
+                UI.addOption($D('noVNC_setting_stylesheet'),sheets[i].title, sheets[i].title);
             }
             }
 
 
             // Logging selection dropdown
             // Logging selection dropdown
             var llevels = ['error', 'warn', 'info', 'debug'];
             var llevels = ['error', 'warn', 'info', 'debug'];
             for (i = 0; i < llevels.length; i += 1) {
             for (i = 0; i < llevels.length; i += 1) {
-                UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]);
+                UI.addOption($D('noVNC_setting_logging'),llevels[i], llevels[i]);
             }
             }
 
 
             // Settings with immediate effects
             // Settings with immediate effects
@@ -114,7 +114,7 @@ var UI;
 
 
             UI.updateVisualState();
             UI.updateVisualState();
 
 
-            $D('noVNC_host').focus();
+            $D('noVNC_setting_host').focus();
 
 
             // Show mouse selector buttons on touch screen devices
             // Show mouse selector buttons on touch screen devices
             if (UI.isTouchDevice) {
             if (UI.isTouchDevice) {
@@ -132,7 +132,7 @@ var UI;
             UI.setBarPosition();
             UI.setBarPosition();
 
 
             Util.addEvent(window, 'resize', function () {
             Util.addEvent(window, 'resize', function () {
-                UI.onresize();
+                UI.applyResizeMode();
                 UI.setViewClip();
                 UI.setViewClip();
                 UI.updateViewDrag();
                 UI.updateViewDrag();
                 UI.setBarPosition();
                 UI.setBarPosition();
@@ -148,7 +148,7 @@ var UI;
                  document.documentElement.mozRequestFullScreen ||
                  document.documentElement.mozRequestFullScreen ||
                  document.documentElement.webkitRequestFullscreen ||
                  document.documentElement.webkitRequestFullscreen ||
                  document.body.msRequestFullscreen)) {
                  document.body.msRequestFullscreen)) {
-                $D('fullscreenButton').style.display = "inline";
+                $D('noVNC_fullscreen_button').style.display = "inline";
                 Util.addEvent(window, 'fullscreenchange', UI.updateFullscreenButton);
                 Util.addEvent(window, 'fullscreenchange', UI.updateFullscreenButton);
                 Util.addEvent(window, 'mozfullscreenchange', UI.updateFullscreenButton);
                 Util.addEvent(window, 'mozfullscreenchange', UI.updateFullscreenButton);
                 Util.addEvent(window, 'webkitfullscreenchange', UI.updateFullscreenButton);
                 Util.addEvent(window, 'webkitfullscreenchange', UI.updateFullscreenButton);
@@ -182,13 +182,13 @@ var UI;
             }
             }
         },
         },
 
 
-        initRFB: function () {
+        initRFB: function() {
             try {
             try {
                 UI.rfb = new RFB({'target': $D('noVNC_canvas'),
                 UI.rfb = new RFB({'target': $D('noVNC_canvas'),
                                   'onUpdateState': UI.updateState,
                                   'onUpdateState': UI.updateState,
-                                  'onXvpInit': UI.updateXvpVisualState,
-                                  'onClipboard': UI.clipReceive,
-                                  'onFBUComplete': UI.FBUComplete,
+                                  'onXvpInit': UI.updateXvpButton,
+                                  'onClipboard': UI.clipboardReceive,
+                                  'onFBUComplete': UI.initialResize,
                                   'onFBResize': UI.updateViewDrag,
                                   'onFBResize': UI.updateViewDrag,
                                   'onDesktopName': UI.updateDocumentTitle});
                                   'onDesktopName': UI.updateDocumentTitle});
                 return true;
                 return true;
@@ -205,109 +205,194 @@ var UI;
             $D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); };
             $D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); };
             $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
             $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
             $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
             $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
-            $D("showKeyboard").onclick = UI.showKeyboard;
-
-            $D("keyboardinput").oninput = UI.keyInput;
-            $D("keyboardinput").onblur = UI.keyInputBlur;
-            $D("keyboardinput").onsubmit = function () { return false; };
-
-            $D("showExtraKeysButton").onclick = UI.showExtraKeys;
-            $D("toggleCtrlButton").onclick = UI.toggleCtrl;
-            $D("toggleAltButton").onclick = UI.toggleAlt;
-            $D("sendTabButton").onclick = UI.sendTab;
-            $D("sendEscButton").onclick = UI.sendEsc;
-
-            $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel;
-            $D("xvpShutdownButton").onclick = UI.xvpShutdown;
-            $D("xvpRebootButton").onclick = UI.xvpReboot;
-            $D("xvpResetButton").onclick = UI.xvpReset;
-            $D("noVNC_status").onclick = UI.togglePopupStatus;
-            $D("noVNC_popup_status").onclick = UI.togglePopupStatus;
-            $D("xvpButton").onclick = UI.toggleXvpPanel;
-            $D("clipboardButton").onclick = UI.toggleClipboardPanel;
-            $D("fullscreenButton").onclick = UI.toggleFullscreen;
-            $D("settingsButton").onclick = UI.toggleSettingsPanel;
-            $D("connectButton").onclick = UI.toggleConnectPanel;
-            $D("disconnectButton").onclick = UI.disconnect;
-            $D("descriptionButton").onclick = UI.toggleConnectPanel;
+            $D("noVNC_keyboard_button").onclick = UI.showKeyboard;
+
+            $D("noVNC_keyboardinput").oninput = UI.keyInput;
+            $D("noVNC_keyboardinput").onblur = UI.hideKeyboard;
+            $D("noVNC_keyboardinput").onsubmit = function () { return false; };
+
+            $D("noVNC_toggleExtraKeys_button").onclick = UI.toggleExtraKeys;
+            $D("noVNC_toggleCtrl_button").onclick = UI.toggleCtrl;
+            $D("noVNC_toggleAlt_button").onclick = UI.toggleAlt;
+            $D("noVNC_sendTab_button").onclick = UI.sendTab;
+            $D("noVNC_sendEsc_button").onclick = UI.sendEsc;
+
+            $D("noVNC_sendCtrlAltDel_button").onclick = UI.sendCtrlAltDel;
+            $D("noVNC_xvpShutdown_button").onclick = function() { UI.rfb.xvpShutdown(); },
+            $D("noVNC_xvpReboot_button").onclick = function() { UI.rfb.xvpReboot(); },
+            $D("noVNC_xvpReset_button").onclick = function() { UI.rfb.xvpReset(); },
+            $D("noVNC_status").onclick = UI.popupStatus;
+            $D("noVNC_popup_status").onclick = UI.closePopup;
+            $D("noVNC_toggleXvp_button").onclick = UI.toggleXvpPanel;
+            $D("noVNC_clipboard_button").onclick = UI.toggleClipboardPanel;
+            $D("noVNC_fullscreen_button").onclick = UI.toggleFullscreen;
+            $D("noVNC_settings_button").onclick = UI.toggleSettingsPanel;
+            $D("noVNC_connectPanel_button").onclick = UI.toggleConnectPanel;
+            $D("noVNC_disconnect_button").onclick = UI.disconnect;
+            $D("noVNC_description_button").onclick = UI.toggleConnectPanel;
 
 
             $D("noVNC_clipboard_text").onfocus = UI.displayBlur;
             $D("noVNC_clipboard_text").onfocus = UI.displayBlur;
             $D("noVNC_clipboard_text").onblur = UI.displayFocus;
             $D("noVNC_clipboard_text").onblur = UI.displayFocus;
-            $D("noVNC_clipboard_text").onchange = UI.clipSend;
-            $D("noVNC_clipboard_clear_button").onclick = UI.clipClear;
+            $D("noVNC_clipboard_text").onchange = UI.clipboardSend;
+            $D("noVNC_clipboard_clear_button").onclick = UI.clipboardClear;
 
 
             $D("noVNC_settings_menu").onmouseover = UI.displayBlur;
             $D("noVNC_settings_menu").onmouseover = UI.displayBlur;
             $D("noVNC_settings_menu").onmouseover = UI.displayFocus;
             $D("noVNC_settings_menu").onmouseover = UI.displayFocus;
-            $D("noVNC_apply").onclick = UI.settingsApply;
+            $D("noVNC_settings_apply").onclick = UI.settingsApply;
 
 
             $D("noVNC_connect_button").onclick = UI.connect;
             $D("noVNC_connect_button").onclick = UI.connect;
 
 
-            $D("noVNC_resize").onchange = UI.enableDisableViewClip;
+            $D("noVNC_setting_resize").onchange = UI.enableDisableViewClip;
         },
         },
 
 
-        onresize: function (callback) {
-            if (!UI.rfb) return;
+/* ------^-------
+ *     /INIT
+ * ==============
+ *     VISUAL
+ * ------v------*/
 
 
-            var size = UI.getCanvasLimit();
+        updateState: function(rfb, state, oldstate, msg) {
+            UI.rfb_state = state;
+            var klass;
+            switch (state) {
+                case 'failed':
+                case 'fatal':
+                    klass = "noVNC_status_error";
+                    break;
+                case 'normal':
+                    klass = "noVNC_status_normal";
+                    break;
+                case 'disconnected':
+                    $D('noVNC_logo').style.display = "block";
+                    $D('noVNC_screen').style.display = "none";
+                    /* falls through */
+                case 'loaded':
+                    klass = "noVNC_status_normal";
+                    break;
+                case 'password':
+                    UI.toggleConnectPanel();
 
 
-            if (size && UI.rfb_state === 'normal' && UI.rfb.get_display()) {
-                var display = UI.rfb.get_display();
-                var scaleType = UI.getSetting('resize');
-                if (scaleType === 'remote') {
-                    // use remote resizing
+                    $D('noVNC_connect_button').value = "Send Password";
+                    $D('noVNC_connect_button').onclick = UI.setPassword;
+                    $D('noVNC_setting_password').focus();
 
 
-                    // When the local window has been resized, wait until the size remains
-                    // the same for 0.5 seconds before sending the request for changing
-                    // the resolution of the session
-                    clearTimeout(UI.resizeTimeout);
-                    UI.resizeTimeout = setTimeout(function(){
-                        display.set_maxWidth(size.w);
-                        display.set_maxHeight(size.h);
-                        Util.Debug('Attempting requestDesktopSize(' +
-                                   size.w + ', ' + size.h + ')');
-                        UI.rfb.requestDesktopSize(size.w, size.h);
-                    }, 500);
-                } else if (scaleType === 'scale' || scaleType === 'downscale') {
-                    // use local scaling
+                    klass = "noVNC_status_warn";
+                    break;
+                default:
+                    klass = "noVNC_status_warn";
+                    break;
+            }
 
 
-                    var downscaleOnly = scaleType === 'downscale';
-                    var scaleRatio = display.autoscale(size.w, size.h, downscaleOnly);
-                    UI.rfb.get_mouse().set_scale(scaleRatio);
-                    Util.Debug('Scaling by ' + UI.rfb.get_mouse().get_scale());
-                }
+            if (typeof(msg) !== 'undefined') {
+                $D('noVNC_control_bar').setAttribute("class", klass);
+                $D('noVNC_status').innerHTML = msg;
             }
             }
+
+            UI.updateVisualState();
         },
         },
 
 
-        getCanvasLimit: function () {
-            var container = $D('noVNC_container');
+        // Disable/enable controls depending on connection state
+        updateVisualState: function() {
+            var connected = UI.rfb && UI.rfb_state === 'normal';
 
 
-            // Hide the scrollbars until the size is calculated
-            container.style.overflow = "hidden";
+            //Util.Debug(">> updateVisualState");
+            $D('noVNC_setting_encrypt').disabled = connected;
+            $D('noVNC_setting_true_color').disabled = connected;
+            if (Util.browserSupportsCursorURIs()) {
+                $D('noVNC_setting_cursor').disabled = connected;
+            } else {
+                UI.updateSetting('cursor', !UI.isTouchDevice);
+                $D('noVNC_setting_cursor').disabled = true;
+            }
 
 
-            var pos = Util.getPosition(container);
-            var w = pos.width;
-            var h = pos.height;
+            UI.enableDisableViewClip();
+            $D('noVNC_setting_resize').disabled = connected;
+            $D('noVNC_setting_shared').disabled = connected;
+            $D('noVNC_setting_view_only').disabled = connected;
+            $D('noVNC_setting_path').disabled = connected;
+            $D('noVNC_setting_repeaterID').disabled = connected;
 
 
-            container.style.overflow = "visible";
+            if (connected) {
+                UI.setViewClip();
+                UI.setMouseButton(1);
+                $D('noVNC_clipboard_button').style.display = "inline";
+                $D('noVNC_keyboard_button').style.display = "inline";
+                $D('noVNC_extra_keys').style.display = "";
+                $D('noVNC_sendCtrlAltDel_button').style.display = "inline";
+            } else {
+                UI.setMouseButton();
+                $D('noVNC_clipboard_button').style.display = "none";
+                $D('noVNC_keyboard_button').style.display = "none";
+                $D('noVNC_extra_keys').style.display = "none";
+                $D('noVNC_sendCtrlAltDel_button').style.display = "none";
+                UI.updateXvpButton(0);
+            }
 
 
-            if (isNaN(w) || isNaN(h)) {
-                return false;
+            // State change disables viewport dragging.
+            // It is enabled (toggled) by direct click on the button
+            UI.updateViewDrag(false);
+
+            switch (UI.rfb_state) {
+                case 'fatal':
+                case 'failed':
+                case 'disconnected':
+                    $D('noVNC_connectPanel_button').style.display = "";
+                    $D('noVNC_disconnect_button').style.display = "none";
+                    UI.connSettingsOpen = false;
+                    UI.toggleConnectPanel();
+                    break;
+                case 'loaded':
+                    $D('noVNC_connectPanel_button').style.display = "";
+                    $D('noVNC_disconnect_button').style.display = "none";
+                    break;
+                default:
+                    $D('noVNC_connectPanel_button').style.display = "none";
+                    $D('noVNC_disconnect_button').style.display = "";
+                    break;
+            }
+
+            //Util.Debug("<< updateVisualState");
+        },
+
+        popupStatus: function(text) {
+            var psp = $D('noVNC_popup_status');
+
+            clearTimeout(UI.popupStatusTimeout);
+
+            if (typeof text === 'string') {
+                psp.innerHTML = text;
             } else {
             } else {
-                return {w: w, h: h};
+                psp.innerHTML = $D('noVNC_status').innerHTML;
             }
             }
+            psp.style.display = "block";
+            psp.style.left = window.innerWidth/2 -
+                parseInt(window.getComputedStyle(psp).width)/2 -30 + "px";
+
+            // Show the popup for a maximum of 1.5 seconds
+            UI.popupStatusTimeout = setTimeout(function() {
+                UI.closePopup();
+            }, 1500);
         },
         },
 
 
-        // Read form control compatible setting from cookie
-        getSetting: function(name) {
-            var ctrl = $D('noVNC_' + name);
-            var val = WebUtil.readSetting(name);
-            if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') {
-                if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) {
-                    val = false;
-                } else {
-                    val = true;
-                }
+        closePopup: function() {
+            clearTimeout(UI.popupStatusTimeout);
+            $D('noVNC_popup_status').style.display = "none";
+        },
+
+/* ------^-------
+ *    /VISUAL
+ * ==============
+ *    SETTINGS
+ * ------v------*/
+
+        // Initial page load read/initialization of settings
+        initSetting: function(name, defVal) {
+            // Check Query string followed by cookie
+            var val = WebUtil.getConfigVar(name);
+            if (val === null) {
+                val = WebUtil.readSetting(name, defVal);
             }
             }
+            UI.updateSetting(name, val);
             return val;
             return val;
         },
         },
 
 
@@ -323,7 +408,7 @@ var UI;
             // Update the settings control
             // Update the settings control
             value = UI.getSetting(name);
             value = UI.getSetting(name);
 
 
-            var ctrl = $D('noVNC_' + name);
+            var ctrl = $D('noVNC_setting_' + name);
             if (ctrl.type === 'checkbox') {
             if (ctrl.type === 'checkbox') {
                 ctrl.checked = value;
                 ctrl.checked = value;
 
 
@@ -346,7 +431,7 @@ var UI;
 
 
         // Save control setting to cookie
         // Save control setting to cookie
         saveSetting: function(name) {
         saveSetting: function(name) {
-            var val, ctrl = $D('noVNC_' + name);
+            var val, ctrl = $D('noVNC_setting_' + name);
             if (ctrl.type === 'checkbox') {
             if (ctrl.type === 'checkbox') {
                 val = ctrl.checked;
                 val = ctrl.checked;
             } else if (typeof ctrl.options !== 'undefined') {
             } else if (typeof ctrl.options !== 'undefined') {
@@ -359,181 +444,83 @@ var UI;
             return val;
             return val;
         },
         },
 
 
-        // Initial page load read/initialization of settings
-        initSetting: function(name, defVal) {
-            // Check Query string followed by cookie
-            var val = WebUtil.getConfigVar(name);
-            if (val === null) {
-                val = WebUtil.readSetting(name, defVal);
-            }
-            UI.updateSetting(name, val);
-            return val;
-        },
-
         // Force a setting to be a certain value
         // Force a setting to be a certain value
         forceSetting: function(name, val) {
         forceSetting: function(name, val) {
             UI.updateSetting(name, val);
             UI.updateSetting(name, val);
             return val;
             return val;
         },
         },
 
 
-
-        // Show the popup status
-        togglePopupStatus: function(text) {
-            var psp = $D('noVNC_popup_status');
-
-            var closePopup = function() { psp.style.display = "none"; };
-
-            if (window.getComputedStyle(psp).display === 'none') {
-                if (typeof text === 'string') {
-                    psp.innerHTML = text;
+        // Read form control compatible setting from cookie
+        getSetting: function(name) {
+            var ctrl = $D('noVNC_setting_' + name);
+            var val = WebUtil.readSetting(name);
+            if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') {
+                if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) {
+                    val = false;
                 } else {
                 } else {
-                    psp.innerHTML = $D('noVNC_status').innerHTML;
+                    val = true;
                 }
                 }
-                psp.style.display = "block";
-                psp.style.left = window.innerWidth/2 -
-                    parseInt(window.getComputedStyle(psp).width)/2 -30 + "px";
-
-                // Show the popup for a maximum of 1.5 seconds
-                UI.popupStatusTimeout = setTimeout(function() { closePopup(); }, 1500);
-            } else {
-                clearTimeout(UI.popupStatusTimeout);
-                closePopup();
             }
             }
+            return val;
         },
         },
 
 
-        // Show the XVP panel
-        toggleXvpPanel: function() {
-            // Close the description panel
-            $D('noVNC_description').style.display = "none";
-            // Close settings if open
-            if (UI.settingsOpen === true) {
-                UI.settingsApply();
-                UI.closeSettingsMenu();
-            }
-            // Close connection settings if open
-            if (UI.connSettingsOpen === true) {
-                UI.toggleConnectPanel();
-            }
-            // Close clipboard panel if open
-            if (UI.clipboardOpen === true) {
-                UI.toggleClipboardPanel();
-            }
-            // Toggle XVP panel
-            if (UI.xvpOpen === true) {
-                $D('noVNC_xvp').style.display = "none";
-                $D('xvpButton').className = "noVNC_status_button";
-                UI.xvpOpen = false;
-            } else {
-                $D('noVNC_xvp').style.display = "block";
-                $D('xvpButton').className = "noVNC_status_button_selected";
-                UI.xvpOpen = true;
+        // Save/apply settings when 'Apply' button is pressed
+        settingsApply: function() {
+            //Util.Debug(">> settingsApply");
+            UI.saveSetting('encrypt');
+            UI.saveSetting('true_color');
+            if (Util.browserSupportsCursorURIs()) {
+                UI.saveSetting('cursor');
             }
             }
-        },
 
 
-        // Show the clipboard panel
-        toggleClipboardPanel: function() {
-            // Close the description panel
-            $D('noVNC_description').style.display = "none";
-            // Close settings if open
-            if (UI.settingsOpen === true) {
-                UI.settingsApply();
-                UI.closeSettingsMenu();
-            }
-            // Close connection settings if open
-            if (UI.connSettingsOpen === true) {
-                UI.toggleConnectPanel();
-            }
-            // Close XVP panel if open
-            if (UI.xvpOpen === true) {
-                UI.toggleXvpPanel();
-            }
-            // Toggle Clipboard Panel
-            if (UI.clipboardOpen === true) {
-                $D('noVNC_clipboard').style.display = "none";
-                $D('clipboardButton').className = "noVNC_status_button";
-                UI.clipboardOpen = false;
-            } else {
-                $D('noVNC_clipboard').style.display = "block";
-                $D('clipboardButton').className = "noVNC_status_button_selected";
-                UI.clipboardOpen = true;
-            }
-        },
+            UI.saveSetting('resize');
 
 
-        // Toggle fullscreen mode
-        toggleFullscreen: function() {
-            if (document.fullscreenElement || // alternative standard method
-                document.mozFullScreenElement || // currently working methods
-                document.webkitFullscreenElement ||
-                document.msFullscreenElement) {
-                if (document.exitFullscreen) {
-                    document.exitFullscreen();
-                } else if (document.mozCancelFullScreen) {
-                    document.mozCancelFullScreen();
-                } else if (document.webkitExitFullscreen) {
-                    document.webkitExitFullscreen();
-                } else if (document.msExitFullscreen) {
-                    document.msExitFullscreen();
-                }
-            } else {
-                if (document.documentElement.requestFullscreen) {
-                    document.documentElement.requestFullscreen();
-                } else if (document.documentElement.mozRequestFullScreen) {
-                    document.documentElement.mozRequestFullScreen();
-                } else if (document.documentElement.webkitRequestFullscreen) {
-                    document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
-                } else if (document.body.msRequestFullscreen) {
-                    document.body.msRequestFullscreen();
-                }
+            if (UI.getSetting('resize') === 'downscale' || UI.getSetting('resize') === 'scale') {
+                UI.forceSetting('clip', false);
             }
             }
-            UI.enableDisableViewClip();
-            UI.updateFullscreenButton();
-        },
 
 
-        updateFullscreenButton: function() {
-            if (document.fullscreenElement || // alternative standard method
-                document.mozFullScreenElement || // currently working methods
-                document.webkitFullscreenElement ||
-                document.msFullscreenElement ) {
-                $D('fullscreenButton').className = "noVNC_status_button_selected";
-            } else {
-                $D('fullscreenButton').className = "noVNC_status_button";
-            }
+            UI.saveSetting('clip');
+            UI.saveSetting('shared');
+            UI.saveSetting('view_only');
+            UI.saveSetting('path');
+            UI.saveSetting('repeaterID');
+            UI.saveSetting('stylesheet');
+            UI.saveSetting('logging');
+
+            // Settings with immediate (non-connected related) effect
+            WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
+            WebUtil.init_logging(UI.getSetting('logging'));
+            UI.setViewClip();
+            UI.updateViewDrag();
+            //Util.Debug("<< settingsApply");
         },
         },
 
 
-        // Show the connection settings panel/menu
-        toggleConnectPanel: function() {
+        // Open menu
+        openSettingsMenu: function() {
             // Close the description panel
             // Close the description panel
             $D('noVNC_description').style.display = "none";
             $D('noVNC_description').style.display = "none";
-            // Close connection settings if open
-            if (UI.settingsOpen === true) {
-                UI.settingsApply();
-                UI.closeSettingsMenu();
-                $D('connectButton').className = "noVNC_status_button";
-            }
             // Close clipboard panel if open
             // Close clipboard panel if open
             if (UI.clipboardOpen === true) {
             if (UI.clipboardOpen === true) {
                 UI.toggleClipboardPanel();
                 UI.toggleClipboardPanel();
             }
             }
+            // Close connection settings if open
+            if (UI.connSettingsOpen === true) {
+                UI.toggleConnectPanel();
+            }
             // Close XVP panel if open
             // Close XVP panel if open
             if (UI.xvpOpen === true) {
             if (UI.xvpOpen === true) {
                 UI.toggleXvpPanel();
                 UI.toggleXvpPanel();
             }
             }
+            $D('noVNC_settings').style.display = "block";
+            $D('noVNC_settings_button').className = "noVNC_status_button_selected";
+            UI.settingsOpen = true;
+        },
 
 
-            // Toggle Connection Panel
-            if (UI.connSettingsOpen === true) {
-                $D('noVNC_controls').style.display = "none";
-                $D('connectButton').className = "noVNC_status_button";
-                UI.connSettingsOpen = false;
-                UI.saveSetting('host');
-                UI.saveSetting('port');
-                UI.saveSetting('token');
-                //UI.saveSetting('password');
-            } else {
-                $D('noVNC_controls').style.display = "block";
-                $D('connectButton').className = "noVNC_status_button_selected";
-                UI.connSettingsOpen = true;
-                $D('noVNC_host').focus();
-            }
+        // Close menu (without applying settings)
+        closeSettingsMenu: function() {
+            $D('noVNC_settings').style.display = "none";
+            $D('noVNC_settings_button').className = "noVNC_status_button";
+            UI.settingsOpen = false;
         },
         },
 
 
         // Toggle the settings menu:
         // Toggle the settings menu:
@@ -552,7 +539,7 @@ var UI;
                     UI.updateSetting('cursor');
                     UI.updateSetting('cursor');
                 } else {
                 } else {
                     UI.updateSetting('cursor', !UI.isTouchDevice);
                     UI.updateSetting('cursor', !UI.isTouchDevice);
-                    $D('noVNC_cursor').disabled = true;
+                    $D('noVNC_setting_cursor').disabled = true;
                 }
                 }
                 UI.updateSetting('clip');
                 UI.updateSetting('clip');
                 UI.updateSetting('resize');
                 UI.updateSetting('resize');
@@ -567,222 +554,47 @@ var UI;
             }
             }
         },
         },
 
 
-        // Open menu
-        openSettingsMenu: function() {
+/* ------^-------
+ *   /SETTINGS
+ * ==============
+ *      XVP
+ * ------v------*/
+
+        // Show the XVP panel
+        toggleXvpPanel: function() {
             // Close the description panel
             // Close the description panel
             $D('noVNC_description').style.display = "none";
             $D('noVNC_description').style.display = "none";
-            // Close clipboard panel if open
-            if (UI.clipboardOpen === true) {
-                UI.toggleClipboardPanel();
+            // Close settings if open
+            if (UI.settingsOpen === true) {
+                UI.settingsApply();
+                UI.closeSettingsMenu();
             }
             }
             // Close connection settings if open
             // Close connection settings if open
             if (UI.connSettingsOpen === true) {
             if (UI.connSettingsOpen === true) {
                 UI.toggleConnectPanel();
                 UI.toggleConnectPanel();
             }
             }
-            // Close XVP panel if open
-            if (UI.xvpOpen === true) {
-                UI.toggleXvpPanel();
-            }
-            $D('noVNC_settings').style.display = "block";
-            $D('settingsButton').className = "noVNC_status_button_selected";
-            UI.settingsOpen = true;
-        },
-
-        // Close menu (without applying settings)
-        closeSettingsMenu: function() {
-            $D('noVNC_settings').style.display = "none";
-            $D('settingsButton').className = "noVNC_status_button";
-            UI.settingsOpen = false;
-        },
-
-        // Save/apply settings when 'Apply' button is pressed
-        settingsApply: function() {
-            //Util.Debug(">> settingsApply");
-            UI.saveSetting('encrypt');
-            UI.saveSetting('true_color');
-            if (Util.browserSupportsCursorURIs()) {
-                UI.saveSetting('cursor');
-            }
-
-            UI.saveSetting('resize');
-
-            if (UI.getSetting('resize') === 'downscale' || UI.getSetting('resize') === 'scale') {
-                UI.forceSetting('clip', false);
-            }
-
-            UI.saveSetting('clip');
-            UI.saveSetting('shared');
-            UI.saveSetting('view_only');
-            UI.saveSetting('path');
-            UI.saveSetting('repeaterID');
-            UI.saveSetting('stylesheet');
-            UI.saveSetting('logging');
-
-            // Settings with immediate (non-connected related) effect
-            WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
-            WebUtil.init_logging(UI.getSetting('logging'));
-            UI.setViewClip();
-            UI.updateViewDrag();
-            //Util.Debug("<< settingsApply");
-        },
-
-
-
-        setPassword: function() {
-            UI.rfb.sendPassword($D('noVNC_password').value);
-            //Reset connect button.
-            $D('noVNC_connect_button').value = "Connect";
-            $D('noVNC_connect_button').onclick = UI.connect;
-            //Hide connection panel.
-            UI.toggleConnectPanel();
-            return false;
-        },
-
-        sendCtrlAltDel: function() {
-            UI.rfb.sendCtrlAltDel();
-        },
-
-        xvpShutdown: function() {
-            UI.rfb.xvpShutdown();
-        },
-
-        xvpReboot: function() {
-            UI.rfb.xvpReboot();
-        },
-
-        xvpReset: function() {
-            UI.rfb.xvpReset();
-        },
-
-        setMouseButton: function(num) {
-            if (typeof num === 'undefined') {
-                // Disable mouse buttons
-                num = -1;
-            }
-            if (UI.rfb) {
-                UI.rfb.get_mouse().set_touchButton(num);
-            }
-
-            var blist = [0, 1,2,4];
-            for (var b = 0; b < blist.length; b++) {
-                var button = $D('noVNC_mouse_button' + blist[b]);
-                if (blist[b] === num) {
-                    button.style.display = "";
-                } else {
-                    button.style.display = "none";
-                }
-            }
-        },
-
-        updateState: function(rfb, state, oldstate, msg) {
-            UI.rfb_state = state;
-            var klass;
-            switch (state) {
-                case 'failed':
-                case 'fatal':
-                    klass = "noVNC_status_error";
-                    break;
-                case 'normal':
-                    klass = "noVNC_status_normal";
-                    break;
-                case 'disconnected':
-                    $D('noVNC_logo').style.display = "block";
-                    $D('noVNC_container').style.display = "none";
-                    /* falls through */
-                case 'loaded':
-                    klass = "noVNC_status_normal";
-                    break;
-                case 'password':
-                    UI.toggleConnectPanel();
-
-                    $D('noVNC_connect_button').value = "Send Password";
-                    $D('noVNC_connect_button').onclick = UI.setPassword;
-                    $D('noVNC_password').focus();
-
-                    klass = "noVNC_status_warn";
-                    break;
-                default:
-                    klass = "noVNC_status_warn";
-                    break;
-            }
-
-            if (typeof(msg) !== 'undefined') {
-                $D('noVNC-control-bar').setAttribute("class", klass);
-                $D('noVNC_status').innerHTML = msg;
-            }
-
-            UI.updateVisualState();
-        },
-
-        // Disable/enable controls depending on connection state
-        updateVisualState: function() {
-            var connected = UI.rfb && UI.rfb_state === 'normal';
-
-            //Util.Debug(">> updateVisualState");
-            $D('noVNC_encrypt').disabled = connected;
-            $D('noVNC_true_color').disabled = connected;
-            if (Util.browserSupportsCursorURIs()) {
-                $D('noVNC_cursor').disabled = connected;
-            } else {
-                UI.updateSetting('cursor', !UI.isTouchDevice);
-                $D('noVNC_cursor').disabled = true;
-            }
-
-            UI.enableDisableViewClip();
-            $D('noVNC_resize').disabled = connected;
-            $D('noVNC_shared').disabled = connected;
-            $D('noVNC_view_only').disabled = connected;
-            $D('noVNC_path').disabled = connected;
-            $D('noVNC_repeaterID').disabled = connected;
-
-            if (connected) {
-                UI.setViewClip();
-                UI.setMouseButton(1);
-                $D('clipboardButton').style.display = "inline";
-                $D('showKeyboard').style.display = "inline";
-                $D('noVNC_extra_keys').style.display = "";
-                $D('sendCtrlAltDelButton').style.display = "inline";
-            } else {
-                UI.setMouseButton();
-                $D('clipboardButton').style.display = "none";
-                $D('showKeyboard').style.display = "none";
-                $D('noVNC_extra_keys').style.display = "none";
-                $D('sendCtrlAltDelButton').style.display = "none";
-                UI.updateXvpVisualState(0);
+            // Close clipboard panel if open
+            if (UI.clipboardOpen === true) {
+                UI.toggleClipboardPanel();
             }
             }
-
-            // State change disables viewport dragging.
-            // It is enabled (toggled) by direct click on the button
-            UI.updateViewDrag(false);
-
-            switch (UI.rfb_state) {
-                case 'fatal':
-                case 'failed':
-                case 'disconnected':
-                    $D('connectButton').style.display = "";
-                    $D('disconnectButton').style.display = "none";
-                    UI.connSettingsOpen = false;
-                    UI.toggleConnectPanel();
-                    break;
-                case 'loaded':
-                    $D('connectButton').style.display = "";
-                    $D('disconnectButton').style.display = "none";
-                    break;
-                default:
-                    $D('connectButton').style.display = "none";
-                    $D('disconnectButton').style.display = "";
-                    break;
+            // Toggle XVP panel
+            if (UI.xvpOpen === true) {
+                $D('noVNC_xvp').style.display = "none";
+                $D('noVNC_toggleXvp_button').className = "noVNC_status_button";
+                UI.xvpOpen = false;
+            } else {
+                $D('noVNC_xvp').style.display = "block";
+                $D('noVNC_toggleXvp_button').className = "noVNC_status_button_selected";
+                UI.xvpOpen = true;
             }
             }
-
-            //Util.Debug("<< updateVisualState");
         },
         },
 
 
         // Disable/enable XVP button
         // Disable/enable XVP button
-        updateXvpVisualState: function(ver) {
+        updateXvpButton: function(ver) {
             if (ver >= 1) {
             if (ver >= 1) {
-                $D('xvpButton').style.display = 'inline';
+                $D('noVNC_toggleXvp_button').style.display = 'inline';
             } else {
             } else {
-                $D('xvpButton').style.display = 'none';
+                $D('noVNC_toggleXvp_button').style.display = 'none';
                 // Close XVP panel if open
                 // Close XVP panel if open
                 if (UI.xvpOpen === true) {
                 if (UI.xvpOpen === true) {
                     UI.toggleXvpPanel();
                     UI.toggleXvpPanel();
@@ -790,36 +602,110 @@ var UI;
             }
             }
         },
         },
 
 
-        // This resize can not be done until we know from the first Frame Buffer Update
-        // if it is supported or not.
-        // The resize is needed to make sure the server desktop size is updated to the
-        // corresponding size of the current local window when reconnecting to an
-        // existing session.
-        FBUComplete: function(rfb, fbu) {
-            UI.onresize();
-            UI.rfb.set_onFBUComplete(function() { });
-        },
+/* ------^-------
+ *     /XVP
+ * ==============
+ *   CLIPBOARD
+ * ------v------*/
 
 
-        // Display the desktop name in the document title
-        updateDocumentTitle: function(rfb, name) {
-            document.title = name + " - noVNC";
+        // Show the clipboard panel
+        toggleClipboardPanel: function() {
+            // Close the description panel
+            $D('noVNC_description').style.display = "none";
+            // Close settings if open
+            if (UI.settingsOpen === true) {
+                UI.settingsApply();
+                UI.closeSettingsMenu();
+            }
+            // Close connection settings if open
+            if (UI.connSettingsOpen === true) {
+                UI.toggleConnectPanel();
+            }
+            // Close XVP panel if open
+            if (UI.xvpOpen === true) {
+                UI.toggleXvpPanel();
+            }
+            // Toggle Clipboard Panel
+            if (UI.clipboardOpen === true) {
+                $D('noVNC_clipboard').style.display = "none";
+                $D('noVNC_clipboard_button').className = "noVNC_status_button";
+                UI.clipboardOpen = false;
+            } else {
+                $D('noVNC_clipboard').style.display = "block";
+                $D('noVNC_clipboard_button').className = "noVNC_status_button_selected";
+                UI.clipboardOpen = true;
+            }
         },
         },
 
 
-        clipReceive: function(rfb, text) {
-            Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
+        clipboardReceive: function(rfb, text) {
+            Util.Debug(">> UI.clipboardReceive: " + text.substr(0,40) + "...");
             $D('noVNC_clipboard_text').value = text;
             $D('noVNC_clipboard_text').value = text;
-            Util.Debug("<< UI.clipReceive");
+            Util.Debug("<< UI.clipboardReceive");
+        },
+
+        clipboardClear: function() {
+            $D('noVNC_clipboard_text').value = "";
+            UI.rfb.clipboardPasteFrom("");
+        },
+
+        clipboardSend: function() {
+            var text = $D('noVNC_clipboard_text').value;
+            Util.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "...");
+            UI.rfb.clipboardPasteFrom(text);
+            Util.Debug("<< UI.clipboardSend");
+        },
+
+/* ------^-------
+ *  /CLIPBOARD
+ * ==============
+ *  CONNECTION
+ * ------v------*/
+
+        // Show the connection settings panel/menu
+        toggleConnectPanel: function() {
+            // Close the description panel
+            $D('noVNC_description').style.display = "none";
+            // Close connection settings if open
+            if (UI.settingsOpen === true) {
+                UI.settingsApply();
+                UI.closeSettingsMenu();
+                $D('noVNC_connectPanel_button').className = "noVNC_status_button";
+            }
+            // Close clipboard panel if open
+            if (UI.clipboardOpen === true) {
+                UI.toggleClipboardPanel();
+            }
+            // Close XVP panel if open
+            if (UI.xvpOpen === true) {
+                UI.toggleXvpPanel();
+            }
+
+            // Toggle Connection Panel
+            if (UI.connSettingsOpen === true) {
+                $D('noVNC_controls').style.display = "none";
+                $D('noVNC_connectPanel_button').className = "noVNC_status_button";
+                UI.connSettingsOpen = false;
+                UI.saveSetting('host');
+                UI.saveSetting('port');
+                UI.saveSetting('token');
+                //UI.saveSetting('password');
+            } else {
+                $D('noVNC_controls').style.display = "block";
+                $D('noVNC_connectPanel_button').className = "noVNC_status_button_selected";
+                UI.connSettingsOpen = true;
+                $D('noVNC_setting_host').focus();
+            }
         },
         },
 
 
         connect: function() {
         connect: function() {
             UI.closeSettingsMenu();
             UI.closeSettingsMenu();
             UI.toggleConnectPanel();
             UI.toggleConnectPanel();
 
 
-            var host = $D('noVNC_host').value;
-            var port = $D('noVNC_port').value;
-            var password = $D('noVNC_password').value;
-            var token = $D('noVNC_token').value;
-            var path = $D('noVNC_path').value;
+            var host = $D('noVNC_setting_host').value;
+            var port = $D('noVNC_setting_port').value;
+            var password = $D('noVNC_setting_password').value;
+            var token = $D('noVNC_setting_token').value;
+            var path = $D('noVNC_setting_path').value;
 
 
             //if token is in path then ignore the new token variable
             //if token is in path then ignore the new token variable
             if (token) {
             if (token) {
@@ -842,9 +728,9 @@ var UI;
             UI.rfb.connect(host, port, password, path);
             UI.rfb.connect(host, port, password, path);
 
 
             //Close dialog.
             //Close dialog.
-            setTimeout(UI.setBarPosition, 100);
+            setTimeout(function () { UI.setBarPosition; } );
             $D('noVNC_logo').style.display = "none";
             $D('noVNC_logo').style.display = "none";
-            $D('noVNC_container').style.display = "inline";
+            $D('noVNC_screen').style.display = "inline";
         },
         },
 
 
         disconnect: function() {
         disconnect: function() {
@@ -852,40 +738,156 @@ var UI;
             UI.rfb.disconnect();
             UI.rfb.disconnect();
 
 
             // Restore the callback used for initial resize
             // Restore the callback used for initial resize
-            UI.rfb.set_onFBUComplete(UI.FBUComplete);
+            UI.rfb.set_onFBUComplete(UI.initialResize);
 
 
             $D('noVNC_logo').style.display = "block";
             $D('noVNC_logo').style.display = "block";
-            $D('noVNC_container').style.display = "none";
+            $D('noVNC_screen').style.display = "none";
 
 
             // Don't display the connection settings until we're actually disconnected
             // Don't display the connection settings until we're actually disconnected
         },
         },
 
 
-        displayBlur: function() {
-            if (!UI.rfb) return;
+        setPassword: function() {
+            UI.rfb.sendPassword($D('noVNC_setting_password').value);
+            //Reset connect button.
+            $D('noVNC_connect_button').value = "Connect";
+            $D('noVNC_connect_button').onclick = UI.connect;
+            //Hide connection panel.
+            UI.toggleConnectPanel();
+            return false;
+        },
 
 
-            UI.rfb.get_keyboard().set_focused(false);
-            UI.rfb.get_mouse().set_focused(false);
+/* ------^-------
+ *  /CONNECTION
+ * ==============
+ *   FULLSCREEN
+ * ------v------*/
+
+        toggleFullscreen: function() {
+            if (document.fullscreenElement || // alternative standard method
+                document.mozFullScreenElement || // currently working methods
+                document.webkitFullscreenElement ||
+                document.msFullscreenElement) {
+                if (document.exitFullscreen) {
+                    document.exitFullscreen();
+                } else if (document.mozCancelFullScreen) {
+                    document.mozCancelFullScreen();
+                } else if (document.webkitExitFullscreen) {
+                    document.webkitExitFullscreen();
+                } else if (document.msExitFullscreen) {
+                    document.msExitFullscreen();
+                }
+            } else {
+                if (document.documentElement.requestFullscreen) {
+                    document.documentElement.requestFullscreen();
+                } else if (document.documentElement.mozRequestFullScreen) {
+                    document.documentElement.mozRequestFullScreen();
+                } else if (document.documentElement.webkitRequestFullscreen) {
+                    document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+                } else if (document.body.msRequestFullscreen) {
+                    document.body.msRequestFullscreen();
+                }
+            }
+            UI.enableDisableViewClip();
+            UI.updateFullscreenButton();
         },
         },
 
 
-        displayFocus: function() {
+        updateFullscreenButton: function() {
+            if (document.fullscreenElement || // alternative standard method
+                document.mozFullScreenElement || // currently working methods
+                document.webkitFullscreenElement ||
+                document.msFullscreenElement ) {
+                $D('noVNC_fullscreen_button').className = "noVNC_status_button_selected";
+            } else {
+                $D('noVNC_fullscreen_button').className = "noVNC_status_button";
+            }
+        },
+
+/* ------^-------
+ *  /FULLSCREEN
+ * ==============
+ *     RESIZE
+ * ------v------*/
+
+        // Apply remote resizing or local scaling
+        applyResizeMode: function() {
             if (!UI.rfb) return;
             if (!UI.rfb) return;
 
 
-            UI.rfb.get_keyboard().set_focused(true);
-            UI.rfb.get_mouse().set_focused(true);
+            var screen = UI.screenSize();
+
+            if (screen && UI.rfb_state === 'normal' && UI.rfb.get_display()) {
+
+                var display = UI.rfb.get_display();
+                var resizeMode = UI.getSetting('resize');
+
+                if (resizeMode === 'remote') {
+
+                    // Request changing the resolution of the remote display to
+                    // the size of the local browser viewport.
+
+                    // In order to not send multiple requests before the browser-resize
+                    // is finished we wait 0.5 seconds before sending the request.
+                    clearTimeout(UI.resizeTimeout);
+                    UI.resizeTimeout = setTimeout(function(){
+
+                        // Limit the viewport to the size of the browser window
+                        display.set_maxWidth(screen.w);
+                        display.set_maxHeight(screen.h);
+
+                        Util.Debug('Attempting requestDesktopSize(' +
+                                   screen.w + ', ' + screen.h + ')');
+
+                        // Request a remote size covering the viewport
+                        UI.rfb.requestDesktopSize(screen.w, screen.h);
+                    }, 500);
+
+                } else if (resizeMode === 'scale' || resizeMode === 'downscale') {
+                    var downscaleOnly = resizeMode === 'downscale';
+                    var scaleRatio = display.autoscale(screen.w, screen.h, downscaleOnly);
+                    UI.rfb.get_mouse().set_scale(scaleRatio);
+                    Util.Debug('Scaling by ' + UI.rfb.get_mouse().get_scale());
+                }
+            }
         },
         },
 
 
-        clipClear: function() {
-            $D('noVNC_clipboard_text').value = "";
-            UI.rfb.clipboardPasteFrom("");
+        // The screen is always the same size as the available viewport
+        // in the browser window minus the height of the control bar
+        screenSize: function() {
+            var screen = $D('noVNC_screen');
+
+            // Hide the scrollbars until the size is calculated
+            screen.style.overflow = "hidden";
+
+            var pos = Util.getPosition(screen);
+            var w = pos.width;
+            var h = pos.height;
+
+            screen.style.overflow = "visible";
+
+            if (isNaN(w) || isNaN(h)) {
+                return false;
+            } else {
+                return {w: w, h: h};
+            }
         },
         },
 
 
-        clipSend: function() {
-            var text = $D('noVNC_clipboard_text').value;
-            Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "...");
-            UI.rfb.clipboardPasteFrom(text);
-            Util.Debug("<< UI.clipSend");
+        // Normally we only apply the current resize mode after a window resize
+        // event. This means that when a new connection is opened, there is no
+        // resize mode active.
+        // We have to wait until the first FBU because this is where the client
+        // will find the supported encodings of the server. Some calls later in
+        // the chain is dependant on knowing the server-capabilities.
+        initialResize: function(rfb, fbu) {
+            UI.applyResizeMode();
+            // After doing this once, we remove the callback.
+            UI.rfb.set_onFBUComplete(function() { });
         },
         },
 
 
+/* ------^-------
+ *    /RESIZE
+ * ==============
+ *    CLIPPING
+ * ------v------*/
+
         // Set and configure viewport clipping
         // Set and configure viewport clipping
         setViewClip: function(clip) {
         setViewClip: function(clip) {
             var display;
             var display;
@@ -919,19 +921,19 @@ var UI;
                 // If clipping, update clipping settings
                 // If clipping, update clipping settings
                 display.set_viewport(true);
                 display.set_viewport(true);
 
 
-                var size = UI.getCanvasLimit();
+                var size = UI.screenSize();
                 if (size) {
                 if (size) {
                     display.set_maxWidth(size.w);
                     display.set_maxWidth(size.w);
                     display.set_maxHeight(size.h);
                     display.set_maxHeight(size.h);
 
 
                     // Hide potential scrollbars that can skew the position
                     // Hide potential scrollbars that can skew the position
-                    $D('noVNC_container').style.overflow = "hidden";
+                    $D('noVNC_screen').style.overflow = "hidden";
 
 
                     // The x position marks the left margin of the canvas,
                     // The x position marks the left margin of the canvas,
                     // remove the margin from both sides to keep it centered
                     // remove the margin from both sides to keep it centered
                     var new_w = size.w - (2 * Util.getPosition($D('noVNC_canvas')).x);
                     var new_w = size.w - (2 * Util.getPosition($D('noVNC_canvas')).x);
 
 
-                    $D('noVNC_container').style.overflow = "visible";
+                    $D('noVNC_screen').style.overflow = "visible";
 
 
                     display.viewportChangeSize(new_w, size.h);
                     display.viewportChangeSize(new_w, size.h);
                 }
                 }
@@ -939,71 +941,75 @@ var UI;
         },
         },
 
 
         // Handle special cases where clipping is forced on/off or locked
         // Handle special cases where clipping is forced on/off or locked
-        enableDisableViewClip: function () {
-            var resizeElem = $D('noVNC_resize');
+        enableDisableViewClip: function() {
+            var resizeSetting = $D('noVNC_setting_resize');
             var connected = UI.rfb && UI.rfb_state === 'normal';
             var connected = UI.rfb && UI.rfb_state === 'normal';
 
 
             if (UI.isSafari) {
             if (UI.isSafari) {
                 // Safari auto-hides the scrollbars which makes them
                 // Safari auto-hides the scrollbars which makes them
                 // impossible to use in most cases
                 // impossible to use in most cases
                 UI.setViewClip(true);
                 UI.setViewClip(true);
-                $D('noVNC_clip').disabled = true;
-            } else if (resizeElem.value === 'downscale' || resizeElem.value === 'scale') {
+                $D('noVNC_setting_clip').disabled = true;
+            } else if (resizeSetting.value === 'downscale' || resizeSetting.value === 'scale') {
                 // Disable clipping if we are scaling
                 // Disable clipping if we are scaling
                 UI.setViewClip(false);
                 UI.setViewClip(false);
-                $D('noVNC_clip').disabled = true;
+                $D('noVNC_setting_clip').disabled = true;
             } else if (document.msFullscreenElement) {
             } else if (document.msFullscreenElement) {
                 // The browser is IE and we are in fullscreen mode.
                 // The browser is IE and we are in fullscreen mode.
                 // - We need to force clipping while in fullscreen since
                 // - We need to force clipping while in fullscreen since
                 //   scrollbars doesn't work.
                 //   scrollbars doesn't work.
-                UI.togglePopupStatus("Forcing clipping mode since scrollbars aren't supported by IE in fullscreen");
+                UI.popupStatus("Forcing clipping mode since scrollbars aren't supported by IE in fullscreen");
                 UI.rememberedClipSetting = UI.getSetting('clip');
                 UI.rememberedClipSetting = UI.getSetting('clip');
                 UI.setViewClip(true);
                 UI.setViewClip(true);
-                $D('noVNC_clip').disabled = true;
+                $D('noVNC_setting_clip').disabled = true;
             } else if (document.body.msRequestFullscreen && UI.rememberedClip !== null) {
             } else if (document.body.msRequestFullscreen && UI.rememberedClip !== null) {
                 // Restore view clip to what it was before fullscreen on IE
                 // Restore view clip to what it was before fullscreen on IE
                 UI.setViewClip(UI.rememberedClipSetting);
                 UI.setViewClip(UI.rememberedClipSetting);
-                $D('noVNC_clip').disabled = connected || UI.isTouchDevice;
+                $D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice;
             } else {
             } else {
-                $D('noVNC_clip').disabled = connected || UI.isTouchDevice;
+                $D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice;
                 if (UI.isTouchDevice) {
                 if (UI.isTouchDevice) {
                     UI.setViewClip(true);
                     UI.setViewClip(true);
                 }
                 }
             }
             }
         },
         },
 
 
-        // Update the viewport drag/move button
+/* ------^-------
+ *   /CLIPPING
+ * ==============
+ *    VIEWDRAG
+ * ------v------*/
+
+        // Update the viewport drag state
         updateViewDrag: function(drag) {
         updateViewDrag: function(drag) {
             if (!UI.rfb) return;
             if (!UI.rfb) return;
 
 
-            var vmb = $D('noVNC_view_drag_button');
+            var viewDragButton = $D('noVNC_view_drag_button');
 
 
-            // Check if viewport drag is possible
+            // Check if viewport drag is possible. It is only possible
+            // if the remote display is clipping the client display.
             if (UI.rfb_state === 'normal' &&
             if (UI.rfb_state === 'normal' &&
                 UI.rfb.get_display().get_viewport() &&
                 UI.rfb.get_display().get_viewport() &&
                 UI.rfb.get_display().clippingDisplay()) {
                 UI.rfb.get_display().clippingDisplay()) {
 
 
-                // Show and enable the drag button
-                vmb.style.display = "inline";
-                vmb.disabled = false;
+                viewDragButton.style.display = "inline";
+                viewDragButton.disabled = false;
 
 
             } else {
             } else {
-                // The VNC content is the same size as
-                // or smaller than the display
-
+                // The size of the remote display is the same or smaller
+                // than the client display. Make sure viewport drag isn't
+                // active when it can't be used.
                 if (UI.rfb.get_viewportDrag) {
                 if (UI.rfb.get_viewportDrag) {
-                    // Turn off viewport drag when it's
-                    // active since it can't be used here
-                    vmb.className = "noVNC_status_button";
+                    viewDragButton.className = "noVNC_status_button";
                     UI.rfb.set_viewportDrag(false);
                     UI.rfb.set_viewportDrag(false);
                 }
                 }
 
 
-                // Disable or hide the drag button
+                // The button is disabled instead of hidden on touch devices
                 if (UI.rfb_state === 'normal' && UI.isTouchDevice) {
                 if (UI.rfb_state === 'normal' && UI.isTouchDevice) {
-                    vmb.style.display = "inline";
-                    vmb.disabled = true;
+                    viewDragButton.style.display = "inline";
+                    viewDragButton.disabled = true;
                 } else {
                 } else {
-                    vmb.style.display = "none";
+                    viewDragButton.style.display = "none";
                 }
                 }
                 return;
                 return;
             }
             }
@@ -1011,10 +1017,10 @@ var UI;
             if (typeof(drag) !== "undefined" &&
             if (typeof(drag) !== "undefined" &&
                 typeof(drag) !== "object") {
                 typeof(drag) !== "object") {
                 if (drag) {
                 if (drag) {
-                    vmb.className = "noVNC_status_button_selected";
+                    viewDragButton.className = "noVNC_status_button_selected";
                     UI.rfb.set_viewportDrag(true);
                     UI.rfb.set_viewportDrag(true);
                 } else {
                 } else {
-                    vmb.className = "noVNC_status_button";
+                    viewDragButton.className = "noVNC_status_button";
                     UI.rfb.set_viewportDrag(false);
                     UI.rfb.set_viewportDrag(false);
                 }
                 }
             }
             }
@@ -1023,20 +1029,26 @@ var UI;
         toggleViewDrag: function() {
         toggleViewDrag: function() {
             if (!UI.rfb) return;
             if (!UI.rfb) return;
 
 
-            var vmb = $D('noVNC_view_drag_button');
+            var viewDragButton = $D('noVNC_view_drag_button');
             if (UI.rfb.get_viewportDrag()) {
             if (UI.rfb.get_viewportDrag()) {
-                vmb.className = "noVNC_status_button";
+                viewDragButton.className = "noVNC_status_button";
                 UI.rfb.set_viewportDrag(false);
                 UI.rfb.set_viewportDrag(false);
             } else {
             } else {
-                vmb.className = "noVNC_status_button_selected";
+                viewDragButton.className = "noVNC_status_button_selected";
                 UI.rfb.set_viewportDrag(true);
                 UI.rfb.set_viewportDrag(true);
             }
             }
         },
         },
 
 
+/* ------^-------
+ *   /VIEWDRAG
+ * ==============
+ *    KEYBOARD
+ * ------v------*/
+
         // On touch devices, show the OS keyboard
         // On touch devices, show the OS keyboard
         showKeyboard: function() {
         showKeyboard: function() {
-            var kbi = $D('keyboardinput');
-            var skb = $D('showKeyboard');
+            var kbi = $D('noVNC_keyboardinput');
+            var skb = $D('noVNC_keyboard_button');
             var l = kbi.value.length;
             var l = kbi.value.length;
             if(UI.keyboardVisible === false) {
             if(UI.keyboardVisible === false) {
                 kbi.focus();
                 kbi.focus();
@@ -1051,19 +1063,29 @@ var UI;
             }
             }
         },
         },
 
 
+        hideKeyboard: function() {
+            $D('noVNC_keyboard_button').className = "noVNC_status_button";
+            //Weird bug in iOS if you change keyboardVisible
+            //here it does not actually occur so next time
+            //you click keyboard icon it doesnt work.
+            UI.hideKeyboardTimeout = setTimeout(function() {
+                UI.keyboardVisible = false;
+            },100);
+        },
+
         keepKeyboard: function() {
         keepKeyboard: function() {
             clearTimeout(UI.hideKeyboardTimeout);
             clearTimeout(UI.hideKeyboardTimeout);
             if(UI.keyboardVisible === true) {
             if(UI.keyboardVisible === true) {
-                $D('keyboardinput').focus();
-                $D('showKeyboard').className = "noVNC_status_button_selected";
+                $D('noVNC_keyboardinput').focus();
+                $D('noVNC_keyboard_button').className = "noVNC_status_button_selected";
             } else if(UI.keyboardVisible === false) {
             } else if(UI.keyboardVisible === false) {
-                $D('keyboardinput').blur();
-                $D('showKeyboard').className = "noVNC_status_button";
+                $D('noVNC_keyboardinput').blur();
+                $D('noVNC_keyboard_button').className = "noVNC_status_button";
             }
             }
         },
         },
 
 
         keyboardinputReset: function() {
         keyboardinputReset: function() {
-            var kbi = $D('keyboardinput');
+            var kbi = $D('noVNC_keyboardinput');
             kbi.value = new Array(UI.defaultKeyboardinputLen).join("_");
             kbi.value = new Array(UI.defaultKeyboardinputLen).join("_");
             UI.lastKeyboardinput = kbi.value;
             UI.lastKeyboardinput = kbi.value;
         },
         },
@@ -1139,42 +1161,44 @@ var UI;
             }
             }
         },
         },
 
 
-        keyInputBlur: function() {
-            $D('showKeyboard').className = "noVNC_status_button";
-            //Weird bug in iOS if you change keyboardVisible
-            //here it does not actually occur so next time
-            //you click keyboard icon it doesnt work.
-            UI.hideKeyboardTimeout = setTimeout(function() { UI.setKeyboard(); },100);
-        },
-
-        showExtraKeys: function() {
+        toggleExtraKeys: function() {
             UI.keepKeyboard();
             UI.keepKeyboard();
             if(UI.extraKeysVisible === false) {
             if(UI.extraKeysVisible === false) {
-                $D('toggleCtrlButton').style.display = "inline";
-                $D('toggleAltButton').style.display = "inline";
-                $D('sendTabButton').style.display = "inline";
-                $D('sendEscButton').style.display = "inline";
-                $D('showExtraKeysButton').className = "noVNC_status_button_selected";
+                $D('noVNC_toggleCtrl_button').style.display = "inline";
+                $D('noVNC_toggleAlt_button').style.display = "inline";
+                $D('noVNC_sendTab_button').style.display = "inline";
+                $D('noVNC_sendEsc_button').style.display = "inline";
+                $D('noVNC_toggleExtraKeys_button').className = "noVNC_status_button_selected";
                 UI.extraKeysVisible = true;
                 UI.extraKeysVisible = true;
             } else if(UI.extraKeysVisible === true) {
             } else if(UI.extraKeysVisible === true) {
-                $D('toggleCtrlButton').style.display = "";
-                $D('toggleAltButton').style.display = "";
-                $D('sendTabButton').style.display = "";
-                $D('sendEscButton').style.display = "";
-                $D('showExtraKeysButton').className = "noVNC_status_button";
+                $D('noVNC_toggleCtrl_button').style.display = "";
+                $D('noVNC_toggleAlt_button').style.display = "";
+                $D('noVNC_sendTab_button').style.display = "";
+                $D('noVNC_sendEsc_button').style.display = "";
+                $D('noVNC_toggleExtraKeys_button').className = "noVNC_status_button";
                 UI.extraKeysVisible = false;
                 UI.extraKeysVisible = false;
             }
             }
         },
         },
 
 
+        sendEsc: function() {
+            UI.keepKeyboard();
+            UI.rfb.sendKey(XK_Escape);
+        },
+
+        sendTab: function() {
+            UI.keepKeyboard();
+            UI.rfb.sendKey(XK_Tab);
+        },
+
         toggleCtrl: function() {
         toggleCtrl: function() {
             UI.keepKeyboard();
             UI.keepKeyboard();
             if(UI.ctrlOn === false) {
             if(UI.ctrlOn === false) {
                 UI.rfb.sendKey(XK_Control_L, true);
                 UI.rfb.sendKey(XK_Control_L, true);
-                $D('toggleCtrlButton').className = "noVNC_status_button_selected";
+                $D('noVNC_toggleCtrl_button').className = "noVNC_status_button_selected";
                 UI.ctrlOn = true;
                 UI.ctrlOn = true;
             } else if(UI.ctrlOn === true) {
             } else if(UI.ctrlOn === true) {
                 UI.rfb.sendKey(XK_Control_L, false);
                 UI.rfb.sendKey(XK_Control_L, false);
-                $D('toggleCtrlButton').className = "noVNC_status_button";
+                $D('noVNC_toggleCtrl_button').className = "noVNC_status_button";
                 UI.ctrlOn = false;
                 UI.ctrlOn = false;
             }
             }
         },
         },
@@ -1183,27 +1207,62 @@ var UI;
             UI.keepKeyboard();
             UI.keepKeyboard();
             if(UI.altOn === false) {
             if(UI.altOn === false) {
                 UI.rfb.sendKey(XK_Alt_L, true);
                 UI.rfb.sendKey(XK_Alt_L, true);
-                $D('toggleAltButton').className = "noVNC_status_button_selected";
+                $D('noVNC_toggleAlt_button').className = "noVNC_status_button_selected";
                 UI.altOn = true;
                 UI.altOn = true;
             } else if(UI.altOn === true) {
             } else if(UI.altOn === true) {
                 UI.rfb.sendKey(XK_Alt_L, false);
                 UI.rfb.sendKey(XK_Alt_L, false);
-                $D('toggleAltButton').className = "noVNC_status_button";
+                $D('noVNC_toggleAlt_button').className = "noVNC_status_button";
                 UI.altOn = false;
                 UI.altOn = false;
             }
             }
         },
         },
 
 
-        sendTab: function() {
-            UI.keepKeyboard();
-            UI.rfb.sendKey(XK_Tab);
+        sendCtrlAltDel: function() {
+            UI.rfb.sendCtrlAltDel();
         },
         },
 
 
-        sendEsc: function() {
-            UI.keepKeyboard();
-            UI.rfb.sendKey(XK_Escape);
+/* ------^-------
+ *   /KEYBOARD
+ * ==============
+ *     MISC
+ * ------v------*/
+
+        setMouseButton: function(num) {
+            if (typeof num === 'undefined') {
+                // Disable mouse buttons
+                num = -1;
+            }
+            if (UI.rfb) {
+                UI.rfb.get_mouse().set_touchButton(num);
+            }
+
+            var blist = [0, 1,2,4];
+            for (var b = 0; b < blist.length; b++) {
+                var button = $D('noVNC_mouse_button' + blist[b]);
+                if (blist[b] === num) {
+                    button.style.display = "";
+                } else {
+                    button.style.display = "none";
+                }
+            }
+        },
+
+        displayBlur: function() {
+            if (!UI.rfb) return;
+
+            UI.rfb.get_keyboard().set_focused(false);
+            UI.rfb.get_mouse().set_focused(false);
+        },
+
+        displayFocus: function() {
+            if (!UI.rfb) return;
+
+            UI.rfb.get_keyboard().set_focused(true);
+            UI.rfb.get_mouse().set_focused(true);
         },
         },
 
 
-        setKeyboard: function() {
-            UI.keyboardVisible = false;
+        // Display the desktop name in the document title
+        updateDocumentTitle: function(rfb, name) {
+            document.title = name + " - noVNC";
         },
         },
 
 
         //Helper to add options to dropdown.
         //Helper to add options to dropdown.
@@ -1215,12 +1274,16 @@ var UI;
         },
         },
 
 
         setBarPosition: function() {
         setBarPosition: function() {
-            $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px';
+            $D('noVNC_control_bar').style.top = (window.pageYOffset) + 'px';
             $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
             $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
 
 
-            var vncwidth = $D('noVNC_screen').style.offsetWidth;
-            $D('noVNC-control-bar').style.width = vncwidth + 'px';
+            var vncwidth = $D('noVNC_container').style.offsetWidth;
+            $D('noVNC_control_bar').style.width = vncwidth + 'px';
         }
         }
 
 
+/* ------^-------
+ *    /MISC
+ * ==============
+ */
     };
     };
 })();
 })();

+ 54 - 54
vnc.html

@@ -5,7 +5,7 @@
     <!--
     <!--
     noVNC example: simple example using default UI
     noVNC example: simple example using default UI
     Copyright (C) 2012 Joel Martin
     Copyright (C) 2012 Joel Martin
-    Copyright (C) 2013 Samuel Mannehed for Cendio AB
+    Copyright (C) 2016 Samuel Mannehed for Cendio AB
     noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
     noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
     This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
     This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
 
 
@@ -16,20 +16,20 @@
     -->
     -->
     <title>noVNC</title>
     <title>noVNC</title>
 
 
-    <meta charset="utf-8">
+    <meta charset="utf-8" />
 
 
     <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
     <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
                 Remove this if you use the .htaccess -->
                 Remove this if you use the .htaccess -->
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
 
 
     <!-- Apple iOS Safari settings -->
     <!-- Apple iOS Safari settings -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
     <meta name="apple-mobile-web-app-capable" content="yes" />
     <meta name="apple-mobile-web-app-capable" content="yes" />
     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
     <!-- App Start Icon  -->
     <!-- App Start Icon  -->
     <link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
     <link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
     <!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
     <!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
-    <link rel="apple-touch-icon" href="images/screen_57x57.png">
+    <link rel="apple-touch-icon" href="images/screen_57x57.png" />
     <!--
     <!--
     <link rel="apple-touch-icon-precomposed" href="images/screen_57x57.png" />
     <link rel="apple-touch-icon-precomposed" href="images/screen_57x57.png" />
     -->
     -->
@@ -48,42 +48,42 @@
 </head>
 </head>
 
 
 <body>
 <body>
-    <div id="noVNC-control-bar" class="noVNC_status_normal">
+    <div id="noVNC_control_bar" class="noVNC_status_normal">
         <!--noVNC Mobile Device only Buttons-->
         <!--noVNC Mobile Device only Buttons-->
-        <div class="noVNC-buttons-left">
+        <div class="noVNC_buttons_left">
             <input type="image" alt="viewport drag" src="images/drag.png"
             <input type="image" alt="viewport drag" src="images/drag.png"
                 id="noVNC_view_drag_button" class="noVNC_status_button"
                 id="noVNC_view_drag_button" class="noVNC_status_button"
-                title="Move/Drag Viewport">
+                title="Move/Drag Viewport" />
             <div id="noVNC_mobile_buttons">
             <div id="noVNC_mobile_buttons">
                 <input type="image" alt="No mousebutton" src="images/mouse_none.png"
                 <input type="image" alt="No mousebutton" src="images/mouse_none.png"
-                    id="noVNC_mouse_button0" class="noVNC_status_button">
+                    id="noVNC_mouse_button0" class="noVNC_status_button" />
                 <input type="image" alt="Left mousebutton" src="images/mouse_left.png"
                 <input type="image" alt="Left mousebutton" src="images/mouse_left.png"
-                    id="noVNC_mouse_button1" class="noVNC_status_button">
+                    id="noVNC_mouse_button1" class="noVNC_status_button" />
                 <input type="image" alt="Middle mousebutton" src="images/mouse_middle.png"
                 <input type="image" alt="Middle mousebutton" src="images/mouse_middle.png"
-                    id="noVNC_mouse_button2" class="noVNC_status_button">
+                    id="noVNC_mouse_button2" class="noVNC_status_button" />
                 <input type="image" alt="Right mousebutton" src="images/mouse_right.png"
                 <input type="image" alt="Right mousebutton" src="images/mouse_right.png"
-                    id="noVNC_mouse_button4" class="noVNC_status_button">
+                    id="noVNC_mouse_button4" class="noVNC_status_button" />
                 <input type="image" alt="Keyboard" src="images/keyboard.png"
                 <input type="image" alt="Keyboard" src="images/keyboard.png"
-                    id="showKeyboard" class="noVNC_status_button"
-                    value="Keyboard" title="Show Keyboard"/>
+                    id="noVNC_keyboard_button" class="noVNC_status_button"
+                    value="Keyboard" title="Show Keyboard" />
                 <!-- Note that Google Chrome on Android doesn't respect any of these,
                 <!-- Note that Google Chrome on Android doesn't respect any of these,
                      html attributes which attempt to disable text suggestions on the
                      html attributes which attempt to disable text suggestions on the
                      on-screen keyboard. Let's hope Chrome implements the ime-mode
                      on-screen keyboard. Let's hope Chrome implements the ime-mode
                      style for example -->
                      style for example -->
-                <textarea id="keyboardinput" autocapitalize="off"
+                <textarea id="noVNC_keyboardinput" autocapitalize="off"
                     autocorrect="off" autocomplete="off" spellcheck="false"
                     autocorrect="off" autocomplete="off" spellcheck="false"
                     mozactionhint="Enter"></textarea>
                     mozactionhint="Enter"></textarea>
                 <div id="noVNC_extra_keys">
                 <div id="noVNC_extra_keys">
-                    <input type="image" alt="Extra keys" src="images/showextrakeys.png"
-                        id="showExtraKeysButton" class="noVNC_status_button">
+                    <input type="image" alt="Extra keys" src="images/toggleextrakeys.png"
+                        id="noVNC_toggleExtraKeys_button" class="noVNC_status_button" />
                     <input type="image" alt="Ctrl" src="images/ctrl.png"
                     <input type="image" alt="Ctrl" src="images/ctrl.png"
-                        id="toggleCtrlButton" class="noVNC_status_button">
+                        id="noVNC_toggleCtrl_button" class="noVNC_status_button" />
                     <input type="image" alt="Alt" src="images/alt.png"
                     <input type="image" alt="Alt" src="images/alt.png"
-                        id="toggleAltButton" class="noVNC_status_button">
+                        id="noVNC_toggleAlt_button" class="noVNC_status_button" />
                     <input type="image" alt="Tab" src="images/tab.png"
                     <input type="image" alt="Tab" src="images/tab.png"
-                        id="sendTabButton" class="noVNC_status_button">
+                        id="noVNC_sendTab_button" class="noVNC_status_button" />
                     <input type="image" alt="Esc" src="images/esc.png"
                     <input type="image" alt="Esc" src="images/esc.png"
-                        id="sendEscButton" class="noVNC_status_button">
+                        id="noVNC_sendEsc_button" class="noVNC_status_button" />
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
@@ -91,27 +91,27 @@
         <div id="noVNC_status"></div>
         <div id="noVNC_status"></div>
 
 
         <!--noVNC Buttons-->
         <!--noVNC Buttons-->
-        <div class="noVNC-buttons-right">
+        <div class="noVNC_buttons_right">
             <input type="image" alt="Ctrl+Alt+Del" src="images/ctrlaltdel.png"
             <input type="image" alt="Ctrl+Alt+Del" src="images/ctrlaltdel.png"
-                id="sendCtrlAltDelButton" class="noVNC_status_button"
+                id="noVNC_sendCtrlAltDel_button" class="noVNC_status_button"
                 title="Send Ctrl-Alt-Del" />
                 title="Send Ctrl-Alt-Del" />
             <input type="image" alt="Shutdown/Reboot" src="images/power.png"
             <input type="image" alt="Shutdown/Reboot" src="images/power.png"
-                id="xvpButton" class="noVNC_status_button"
+                id="noVNC_toggleXvp_button" class="noVNC_status_button"
                 title="Shutdown/Reboot..." />
                 title="Shutdown/Reboot..." />
             <input type="image" alt="Clipboard" src="images/clipboard.png"
             <input type="image" alt="Clipboard" src="images/clipboard.png"
-                id="clipboardButton" class="noVNC_status_button"
+                id="noVNC_clipboard_button" class="noVNC_status_button"
                 title="Clipboard" />
                 title="Clipboard" />
             <input type="image" alt="Fullscreen" src="images/fullscreen.png"
             <input type="image" alt="Fullscreen" src="images/fullscreen.png"
-                id="fullscreenButton" class="noVNC_status_button"
+                id="noVNC_fullscreen_button" class="noVNC_status_button"
                 title="Fullscreen" />
                 title="Fullscreen" />
             <input type="image" alt="Settings" src="images/settings.png"
             <input type="image" alt="Settings" src="images/settings.png"
-                id="settingsButton" class="noVNC_status_button"
+                id="noVNC_settings_button" class="noVNC_status_button"
                 title="Settings" />
                 title="Settings" />
             <input type="image" alt="Connect" src="images/connect.png"
             <input type="image" alt="Connect" src="images/connect.png"
-                id="connectButton" class="noVNC_status_button"
+                id="noVNC_connectPanel_button" class="noVNC_status_button"
                 title="Connect" />
                 title="Connect" />
             <input type="image" alt="Disconnect" src="images/disconnect.png"
             <input type="image" alt="Disconnect" src="images/disconnect.png"
-                id="disconnectButton" class="noVNC_status_button"
+                id="noVNC_disconnect_button" class="noVNC_status_button"
                 title="Disconnect" />
                 title="Disconnect" />
         </div>
         </div>
 
 
@@ -128,7 +128,7 @@
             and <a href="http://kanaka.github.com/noVNC">website</a>
             and <a href="http://kanaka.github.com/noVNC">website</a>
             for more information.
             for more information.
             <br />
             <br />
-            <input id="descriptionButton" type="button" value="Close">
+            <input id="noVNC_description_button" type="button" value="Close" />
         </div>
         </div>
 
 
         <!-- Popup Status -->
         <!-- Popup Status -->
@@ -141,15 +141,15 @@
             </textarea>
             </textarea>
             <br />
             <br />
             <input id="noVNC_clipboard_clear_button" type="button"
             <input id="noVNC_clipboard_clear_button" type="button"
-                value="Clear">
+                value="Clear" />
         </div>
         </div>
 
 
         <!-- XVP Shutdown/Reboot Panel -->
         <!-- XVP Shutdown/Reboot Panel -->
         <div id="noVNC_xvp" class="triangle-right top">
         <div id="noVNC_xvp" class="triangle-right top">
             <span id="noVNC_xvp_menu">
             <span id="noVNC_xvp_menu">
-                <input type="button" id="xvpShutdownButton" value="Shutdown" />
-                <input type="button" id="xvpRebootButton" value="Reboot" />
-                <input type="button" id="xvpResetButton" value="Reset" />
+                <input type="button" id="noVNC_xvpShutdown_button" value="Shutdown" />
+                <input type="button" id="noVNC_xvpReboot_button" value="Reboot" />
+                <input type="button" id="noVNC_xvpReset_button" value="Reset" />
             </span>
             </span>
         </div>
         </div>
 
 
@@ -157,38 +157,38 @@
         <div id="noVNC_settings" class="triangle-right top">
         <div id="noVNC_settings" class="triangle-right top">
             <span id="noVNC_settings_menu">
             <span id="noVNC_settings_menu">
                 <ul>
                 <ul>
-                    <li><input id="noVNC_encrypt" type="checkbox"> Encrypt</li>
-                    <li><input id="noVNC_true_color" type="checkbox" checked> True Color</li>
-                    <li><input id="noVNC_cursor" type="checkbox"> Local Cursor</li>
-                    <li><input id="noVNC_clip" type="checkbox"> Clip to Window</li>
-                    <li><input id="noVNC_shared" type="checkbox"> Shared Mode</li>
-                    <li><input id="noVNC_view_only" type="checkbox"> View Only</li>
+                    <li><input id="noVNC_setting_encrypt" type="checkbox" /> Encrypt</li>
+                    <li><input id="noVNC_setting_true_color" type="checkbox" checked /> True Color</li>
+                    <li><input id="noVNC_setting_cursor" type="checkbox" /> Local Cursor</li>
+                    <li><input id="noVNC_setting_clip" type="checkbox" /> Clip to Window</li>
+                    <li><input id="noVNC_setting_shared" type="checkbox" /> Shared Mode</li>
+                    <li><input id="noVNC_setting_view_only" type="checkbox" /> View Only</li>
                     <hr>
                     <hr>
-                    <li><input id="noVNC_path" type="input" value="websockify"> Path</li>
+                    <li><input id="noVNC_setting_path" type="input" value="websockify" /> Path</li>
                     <li><label>
                     <li><label>
-                        <select id="noVNC_resize" name="vncResize">
+                        <select id="noVNC_setting_resize" name="vncResize">
                             <option value="off">None</option>
                             <option value="off">None</option>
                             <option value="scale">Local Scaling</option>
                             <option value="scale">Local Scaling</option>
                             <option value="downscale">Local Downscaling</option>
                             <option value="downscale">Local Downscaling</option>
                             <option value="remote">Remote Resizing</option>
                             <option value="remote">Remote Resizing</option>
                         </select> Scaling Mode</label>
                         </select> Scaling Mode</label>
                     </li>
                     </li>
-                    <li><input id="noVNC_repeaterID" type="input" value=""> Repeater ID</li>
+                    <li><input id="noVNC_setting_repeaterID" type="input" value="" /> Repeater ID</li>
                     <hr>
                     <hr>
                     <!-- Stylesheet selection dropdown -->
                     <!-- Stylesheet selection dropdown -->
                     <li><label><strong>Style: </strong>
                     <li><label><strong>Style: </strong>
-                        <select id="noVNC_stylesheet" name="vncStyle">
+                        <select id="noVNC_setting_stylesheet" name="vncStyle">
                             <option value="default">default</option>
                             <option value="default">default</option>
                         </select></label>
                         </select></label>
                     </li>
                     </li>
 
 
                     <!-- Logging selection dropdown -->
                     <!-- Logging selection dropdown -->
                     <li><label><strong>Logging: </strong>
                     <li><label><strong>Logging: </strong>
-                        <select id="noVNC_logging" name="vncLogging">
+                        <select id="noVNC_setting_logging" name="vncLogging">
                         </select></label>
                         </select></label>
                     </li>
                     </li>
                     <hr>
                     <hr>
-                    <li><input type="button" id="noVNC_apply" value="Apply"></li>
+                    <li><input type="button" id="noVNC_settings_apply" value="Apply" /></li>
                 </ul>
                 </ul>
             </span>
             </span>
         </div>
         </div>
@@ -196,22 +196,22 @@
         <!-- Connection Panel -->
         <!-- Connection Panel -->
         <div id="noVNC_controls" class="triangle-right top">
         <div id="noVNC_controls" class="triangle-right top">
             <ul>
             <ul>
-                <li><label><strong>Host: </strong><input id="noVNC_host" /></label></li>
-                <li><label><strong>Port: </strong><input id="noVNC_port" /></label></li>
-                <li><label><strong>Password: </strong><input id="noVNC_password" type="password" /></label></li>
-                <li><label><strong>Token: </strong><input id="noVNC_token"/></label></li>
-                <li><input id="noVNC_connect_button" type="button" value="Connect"></li>
+                <li><label><strong>Host: </strong><input id="noVNC_setting_host" /></label></li>
+                <li><label><strong>Port: </strong><input id="noVNC_setting_port" /></label></li>
+                <li><label><strong>Password: </strong><input id="noVNC_setting_password" type="password" /></label></li>
+                <li><label><strong>Token: </strong><input id="noVNC_setting_token" /></label></li>
+                <li><input id="noVNC_connect_button" type="button" value="Connect" /></li>
             </ul>
             </ul>
         </div>
         </div>
 
 
-    </div> <!-- End of noVNC-control-bar -->
+    </div> <!-- End of noVNC_control_bar -->
 
 
 
 
-    <div id="noVNC_screen">
+    <div id="noVNC_container">
         <h1 id="noVNC_logo"><span>no</span><br />VNC</h1>
         <h1 id="noVNC_logo"><span>no</span><br />VNC</h1>
 
 
         <!-- HTML5 Canvas -->
         <!-- HTML5 Canvas -->
-        <div id="noVNC_container">
+        <div id="noVNC_screen">
             <canvas id="noVNC_canvas" width="0" height="0">
             <canvas id="noVNC_canvas" width="0" height="0">
                         Canvas not supported.
                         Canvas not supported.
             </canvas>
             </canvas>