Set autocorrect and autocapitalize off for username/password.
[guacamole.git] / src / main / webapp / index.xhtml
index eaebf3a..9e4ed55 100644 (file)
 
     <head>
         <link rel="icon" type="image/png" href="images/guacamole-logo-64.png"/>
-        <link rel="stylesheet" type="text/css" href="styles/guacamole.css"/>
-        <link rel="stylesheet" type="text/css" href="styles/keyboard.css"/>
-        <title>Guacamole</title>
+        <link rel="apple-touch-icon" type="image/png" href="images/guacamole-logo-64.png"/>
+        <link rel="stylesheet" type="text/css" href="styles/login.css"/>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi"/>
+        <title>Guacamole ${project.version}</title>
     </head>
 
     <body>
 
-        <div id="login-ui">
+        <div id="login-ui" style="display: none">
             <div id="login-dialog-middle">
 
                 <div id="login-dialog">
                     </form>
                 </div>
 
-                <div id="version-dialog">
-                    Guacamole ${project.version}
-                </div>
+            </div>
+        </div>
+
+        <!-- Connection list UI -->
+        <div id="connection-list-ui" style="display: none">
 
+            <div id="logout-panel">
+                <button id="logout">Logout</button>
             </div>
+            
+            <h1>
+                <img class="logo" src="images/guacamole-logo-64.png" alt=""/>
+                Available Connections
+            </h1>
+            
+            <table class="connections">
+                <thead>
+                    <tr>
+                        <th class="protocol"> </th>
+                        <th class="name">Name</th>
+                    </tr>
+                </thead>
+                <tbody id="connections-tbody">
+                </tbody>
+            </table>
+
         </div>
 
-        <!-- Main UI - hidden until login succeeds -->
-        <div id="main-guacamole-ui" style="display: none">
+        <div id="version-dialog">
+            Guacamole ${project.version}
+        </div>
 
-            <!-- Menu -->
-            <div id="menu">
+        <script type="text/javascript" src="scripts/connections.js"></script>
 
-                <!-- Clipboard -->
-                <button id="showClipboard">Show Clipboard</button>
-                <div id="clipboardDiv">
-                    <h2>Clipboard</h2>
-                    <p>
-                    Text copied/cut within Guacamole will appear here. Changes to the text will affect the remote clipboard, and will be pastable within the remote desktop. Use the textbox below as an interface between the client and server clipboards.
-                    </p>
-                    <textarea rows="10" cols="40" id="clipboard"></textarea>
-                </div>
+        <!-- Init -->
+        <script type="text/javascript"> /* <![CDATA[ */
 
-                <button id="showKeyboard">Show Keyboard</button>
-                <button id="ctrlAltDelete">Ctrl-Alt-Delete</button>
+            // Constructs the URL for a client which connects to the connection
+            // with the given id.
+            function getClientURL(id) {
+                
+                // Construct URL for client with given id
+                return "client.xhtml?id=" + encodeURIComponent(id);
+                
+            }
 
-                <!-- Logo and status -->
-                <img id="status-logo" class="logo" src="images/guacamole-logo-24.png" alt="Guacamole" title="Guacamole ${project.version}"/>
-                <span id="state"></span>
+            // Resets the interface such that the login UI is displayed if
+            // the user is not authenticated (or authentication fails) and
+            // the connection list UI (or the client for the only available
+            // connection, if there is only one) is displayed if the user is
+            // authenticated.
+            function resetUI() {
 
-                <a href="agpl-3.0-standalone.html"><img id="license" src="images/agpl-logo.png" alt="AGPLv3"/></a>
-            </div>
+                // Get parameters from query string
+                var parameters = window.location.search.substring(1);
 
+                var configs;
+                try {
+                    configs = getConfigList(parameters);
+                }
+                catch (e) {
 
-            <!-- Display -->
-            <div id="display" class="guac-display guac-loading">
-                <!-- On-screen keyboard -->
-                <div id="keyboardContainer"></div>
-            </div>
+                    // Show login UI if unable to get configs
+                    loginUI.style.display = "";
+                    connectionListUI.style.display = "none";
 
+                    return;
 
-            <!-- Error Dialog-->
-            <div id="errorDialog" class="errorDialogOuter">
-                <div class="errorDialogMiddle">
-                    <div class="errorDialog">
-                        <p id="errorText"></p>
-                        <div class="buttons"><button id="reconnect">Reconnect</button></div>
-                    </div>
-                </div>
-            </div>
-        </div>
+                }
 
+                // If only one connection, redirect to that.
+                if (configs.length == 1) {
+                    window.location.href = getClientURL(configs[0].id);
+                    return;
+                }
 
-        <!-- Scripts -->
-        <script type="text/javascript" src="guacamole-common-js/keyboard.js"></script>
-        <script type="text/javascript" src="guacamole-common-js/mouse.js"></script>
-        <script type="text/javascript" src="guacamole-common-js/layer.js"></script>
-        <script type="text/javascript" src="guacamole-common-js/tunnel.js"></script>
-        <script type="text/javascript" src="guacamole-common-js/guacamole.js"></script>
-        <script type="text/javascript" src="guacamole-common-js/oskeyboard.js"></script>
+                // Remove all rows from connections list
+                var tbody = document.getElementById("connections-tbody");
+                tbody.innerHTML = "";
+                
+                // Add one row per connection
+                for (var i=0; i<configs.length; i++) {
 
-        <!-- Init -->
-        <script type="text/javascript"> /* <![CDATA[ */
+                    // Create row and cells
+                    var tr = document.createElement("tr");
+                    var protocol = document.createElement("td");
+                    var id = document.createElement("td");
+
+                    var protocolIcon = document.createElement("div");
+                    protocolIcon.className = "protocol icon " + configs[i].protocol;
+
+                    // Set CSS
+                    protocol.className = "protocol";
+                    id.className = "name";
+
+                    // Create link to client
+                    var clientLink = document.createElement("a");
+                    clientLink.setAttribute("href", getClientURL(configs[i].id));
+
+                    // Set cell contents
+                    protocol.appendChild(protocolIcon);
+                    //protocol.textContent   = configs[i].protocol;
+                    clientLink.textContent = configs[i].id;
+                    id.appendChild(clientLink);
+
+                    // Add cells
+                    tr.appendChild(protocol);
+                    tr.appendChild(id);
+
+                    // Add row
+                    tbody.appendChild(tr);
+
+                }
+
+                // If configs could be retrieved, display list
+                loginUI.style.display = "none";
+                connectionListUI.style.display = "";
+
+            }
 
             var loginForm = document.getElementById("login-form");
             var loginUI = document.getElementById("login-ui");
-            var display = document.getElementById("display");
+            var connectionListUI = document.getElementById("connection-list-ui");
+            var logout = document.getElementById("logout");
+            var username = document.getElementById("username");
+            var password = document.getElementById("password");
+
+            logout.onclick = function() {
+                window.location.href = "logout";
+            };
 
             loginForm.onsubmit = function() {
 
-                var username = document.getElementById("username");
-                var password = document.getElementById("password");
+                // Get parameters from query string
+                var parameters = window.location.search.substring(1);
 
+                // Get username and password from form
                 var data =
                        "username=" + encodeURIComponent(username.value)
                     + "&password=" + encodeURIComponent(password.value)
 
-                // Instantiate client
-                var guac = new Guacamole.Client(
-                    display,
-                    new Guacamole.HTTPTunnel("tunnel")
-                );
+                // Include query parameters in submission data
+                if (parameters) data += "&" + parameters;
 
                 try {
 
-                    // Connect client
-                    guac.connect(data);
+                    // Log in
+                    var xhr = new XMLHttpRequest();
+                    xhr.open("POST", "login", false);
+                    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+                    xhr.send(data);
+
+                    // Handle failures
+                    if (xhr.status != 200)
+                        throw new Error("Invalid login");
+
+                    resetUI();
 
                 }
                 catch (e) {
 
                 }
 
-                // On success, display UI
-                startGuacamole(guac);
+                // On success, hide loginUI, get and show connection list.
                 return false;
 
             }
 
-            // Shows guacamole interface and initiates connection to guacamole
-            function startGuacamole(guac) {
+            // Turn off autocorrect and autocapitalization on usename 
+            username.setAttribute("autocorrect", "off");
+            username.setAttribute("autocapitalize", "off");
 
-                loginUI.style.display = "none";
-                document.getElementById("main-guacamole-ui").style.display = "block";
-
-                var menu = document.getElementById("menu");
-                var logo = document.getElementById("status-logo");
-
-                var errorDialog = document.getElementById("errorDialog");
-                var errorDialogText = document.getElementById("errorText");
-
-                // Position display correctly
-                window.onresize = function() {
-                    display.style.top = menu.offsetHeight + "px";
-                };
-
-                window.onresize();
-
-                var state = document.getElementById("state");
-                guac.onstatechange = function(clientState) {
-
-                        switch (clientState) {
-                            case 0:
-                                state.textContent = "Idle."
-                                break;
-                            case 1:
-                                state.textContent = "Connecting...";
-                                break;
-                            case 2:
-                                state.textContent = "Connected, waiting for first update...";
-                                break;
-                            case 3:
-                                display.className = display.className.replace(/guac-loading/, '');
-                                menu.className = "connected";
-                                state.textContent = "Connected.";
-                                break;
-                            case 4:
-                                state.textContent = "Disconnecting...";
-                                break;
-                            case 5:
-                                state.textContent = "Disconnected.";
-                                break;
-                            default:
-                                state.textContent = "Unknown";
-                        }
-                };
-
-                // Cache error image (might not be available when error occurs)
-                var guacErrorImage = new Image();
-                guacErrorImage.src = "images/noguacamole-logo-24.png";
-
-                guac.onname = function(name) {
-                    document.title = name;
-                };
-
-                guac.onerror = function(error) {
-
-                    guac.disconnect();
-
-                    menu.className = "error";
-                    display.className += " guac-error";
-
-                    logo.src = guacErrorImage.src;
-                    errorDialogText.textContent = error;
-                    errorDialog.style.visibility = "visible";
-
-                    // Show error by desaturating display
-                    var layers = guac.getLayers();
-                    for (var i=0; i<layers.length; i++) {
-                        layers[i].filter(desaturateFilter);
-                    }
-
-                    // Filter for desaturation
-                    function desaturateFilter(data, width, height) {
-
-                        for (var i=0; i<data.length; i+=4) {
-
-                            // Get RGB values
-                            var r = data[i];
-                            var g = data[i+1];
-                            var b = data[i+2];
-
-                            // Desaturate
-                            var v = Math.max(r, g, b) / 2;
-                            data[i]   = v;
-                            data[i+1] = v;
-                            data[i+2] = v;
-
-                        }
-
-                    }
-
-                };
-
-                // Mouse
-                var mouse = new Guacamole.Mouse(display);
-                mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
-                    function(mouseState) {
-                        guac.sendMouseState(mouseState);
-                    };
-
-                // Keyboard
-                var keyboard = new Guacamole.Keyboard(document);
-
-                function disableKeyboard() {
-                    keyboard.onkeydown = null;
-                    keyboard.onkeyup = null;
-                }
-
-                function enableKeyboard() {
-                    keyboard.onkeydown = 
-                        function (keysym) {
-                            guac.sendKeyEvent(1, keysym);
-                        };
-
-                    keyboard.onkeyup = 
-                        function (keysym) {
-                            guac.sendKeyEvent(0, keysym);
-                        };
-                }
-
-                // Enable keyboard by default
-                enableKeyboard();
-
-                // Reconnect button
-                var reconnect = document.getElementById("reconnect");
-                reconnect.onclick = function() {
-                    window.location.reload();
-                };
-
-                // Disconnect on close
-                window.onunload = function() {
-                    guac.disconnect();
-                }
-
-                // Handle clipboard events
-                var clipboardElement = document.getElementById("clipboard");
-                clipboardElement.onchange = function() {
-
-                    var text = clipboardElement.value;
-                    guac.setClipboard(text);
-
-                };
-
-                // Ignore keypresses when clipboard is focused
-                clipboardElement.onfocus = function() {
-                    disableKeyboard();
-                };
-
-                // Capture keypresses when clipboard is not focused
-                clipboardElement.onblur = function() {
-                    enableKeyboard();
-                };
-
-                // Server copy handler
-                guac.onclipboard = function(data) {
-                    clipboardElement.value = data;
-                };
-
-
-                // Show/Hide clipboard
-                var clipboardDiv = document.getElementById("clipboardDiv");
-                var showClipboard = document.getElementById("showClipboard");
-                showClipboard.onclick = function() {
-
-                    var displayed = clipboardDiv.style.display;
-                    if (displayed != "block") {
-                        clipboardDiv.style.display = "block";
-                        showClipboard.innerHTML = "Hide Clipboard";
-                    }
-                    else {
-                        clipboardDiv.style.display = "none";
-                        showClipboard.innerHTML = "Show Clipboard";
-                        clipboardElement.onchange();
-                    }
-
-                };
-
-
-                // Show/Hide keyboard
-                var keyboardContainer = document.getElementById("keyboardContainer");
-                var showKeyboard = document.getElementById("showKeyboard");
-                showKeyboard.onclick = function() {
-
-                    var displayed = keyboardContainer.style.display;
-                    if (displayed != "block") {
-                        keyboardContainer.style.display = "block";
-                        showKeyboard.textContent = "Hide Keyboard";
-                    }
-                    else {
-                        keyboardContainer.style.display = "none";
-                        showKeyboard.textContent = "Show Keyboard";
-                    }
-
-                };
-
-                // On-screen keyboard
-                var osKeyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty.xml");
-                keyboardContainer.appendChild(osKeyboard);
-
-                osKeyboard.setKeyPressedHandler(
-                        function(keysym) {
-                            guac.sendKeyEvent(1, keysym);
-                        }
-                );
-
-                osKeyboard.setKeyReleasedHandler(
-                        function(keysym) {
-                            guac.sendKeyEvent(0, keysym);
-                        }
-                );
-
-                // Send Ctrl-Alt-Delete
-                var ctrlAltDelete = document.getElementById("ctrlAltDelete");
-
-                ctrlAltDelete.onclick = function() {
-
-                    var KEYSYM_CTRL   = 0xFF03;
-                    var KEYSYM_ALT    = 0xFFE9;
-                    var KEYSYM_DELETE = 0xFFFF;
-
-                    guac.sendKeyEvent(1, KEYSYM_CTRL);
-                    guac.sendKeyEvent(1, KEYSYM_ALT);
-                    guac.sendKeyEvent(1, KEYSYM_DELETE);
-                    guac.sendKeyEvent(0, KEYSYM_DELETE);
-                    guac.sendKeyEvent(0, KEYSYM_ALT);
-                    guac.sendKeyEvent(0, KEYSYM_CTRL);
-                }
-
-            }
+            resetUI();
 
             /* ]]> */ </script>