Explorar o código

Styling/integration refactoring.

- Instead of onload override, move to RFB.load function that takes
  a parameter for the target DOM ID. This allows the user to have
  their own onload function.

- Add "VNC_" prefix to all element ID names. Only create DOM elements
  if they don't already exist on the page, otherwise use the existing
  elements.

- Move all styling to separate stylesheet.

- Use list model for control styling.
Joel Martin %!s(int64=15) %!d(string=hai) anos
pai
achega
ded9dfae10
Modificáronse 4 ficheiros con 177 adicións e 78 borrados
  1. 19 0
      README.md
  2. 50 0
      include/plain.css
  3. 6 1
      vnc.html
  4. 102 77
      vnc.js

+ 19 - 0
README.md

@@ -78,3 +78,22 @@ Usage
   password that the vnc server is using (if any). Hit the Connect
   password that the vnc server is using (if any). Hit the Connect
   button and enjoy!
   button and enjoy!
 
 
+
+Integration
+-----------
+
+The client is designed to be easily integrated with existing web
+structure and style.
+
+At a minimum you must include the script and call the RFB.load()
+function which takes a parameter that is the ID of the DOM element to
+fill. For example:
+
+    <body>
+        <div id='vnc'>Loading</div>
+    </body>
+    <script src='vnc.js'></script>
+    <script> windows.onload = RFB.load('vnc'); </script>
+
+
+The file include/plain.css has a list of stylable elements.

+ 50 - 0
include/plain.css

@@ -0,0 +1,50 @@
+#VNC_controls {
+    overflow: hidden;
+}
+#VNC_controls ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+#VNC_controls li {
+    float: left;
+    margin-right: 15px;
+}
+
+#VNC_host {
+    width: 100;
+}
+#VNC_port {
+    width: 50;
+}
+#VNC_password {
+    width: 80;
+}
+#VNC_encrypt {
+}
+#VNC_connect_button {
+    width: 100px;
+}
+
+#VNC_status {
+    margin-top: 15px;
+    text-align: center;
+    background: #eee;
+}
+
+/* Do not set width/height for VNC_screen or VNC_canvas or incorrect
+ * scaling will occur. Canvas resizes to remote VNC settings */
+#VNC_screen {
+    text-align: center;
+    display: table;
+}
+#VNC_canvas {
+    background: #eee;
+}
+
+#VNC_clipboard_clear_button {
+}
+#VNC_clipboard_text {
+    font-size: 9;
+}
+

+ 6 - 1
vnc.html

@@ -2,11 +2,16 @@
 
 
     <head>
     <head>
         <title>VNC Client</title>
         <title>VNC Client</title>
-        <script src="vnc.js"></script>
+        <link rel="stylesheet" href="include/plain.css">
     </head>
     </head>
 
 
     <body>
     <body>
         <div id='vnc'>Loading</div>
         <div id='vnc'>Loading</div>
     </body>
     </body>
 
 
+    <script src="vnc.js"></script>
+    <script>
+        window.onload = RFB.load('vnc');
+    </script>
+
 </html>
 </html>

+ 102 - 77
vnc.js

@@ -1,10 +1,9 @@
 /*
 /*
- * HTML5 VNC client. To use, include this script and define a div with
- * id of 'vnc'. For example:
- *     <html><body>
- *         <script src='vnc.js'></script>
- *         <div id='vnc'>Loading</div>
- *     </body></html>
+ * HTML5 VNC client
+ *
+ * Licensed under AGPL-3 (see LICENSE.AGPL-3)
+ *
+ * See README.md for usage and integration instructions.
  *
  *
  * This script defines the following globals:
  * This script defines the following globals:
  *     VNC_scripts, VNC_native_ws, FBU, RFB,
  *     VNC_scripts, VNC_native_ws, FBU, RFB,
@@ -38,66 +37,6 @@ if (window.WebSocket) {
 }
 }
 document.write(VNC_scripts);
 document.write(VNC_scripts);
 
 
-/* 
- * Load the controls
- */
-window.onload = function () {
-    console.log("onload");
-
-    /* Populate the 'vnc' div */
-    var html = "";
-    html += '<div id="controls">';
-    html += 'Host: <input id="host" style="width:100">&nbsp;';
-    html += 'Port: <input id="port" style="width:50">&nbsp;';
-    html += 'Password: <input id="password" type="password" style="width:80">&nbsp;';
-    html += 'Encrypt: <input id="encrypt" type="checkbox">&nbsp;';
-    html += '<input id="connectButton" type="button" value="Loading"';
-    html += 'style="width:100px" disabled>&nbsp;';
-    html += '</div>';
-    html += '<br>';
-    html += '<div id="status">Loading</div>';
-    html += '<canvas id="canvas" width="640" height="20"';
-    html += '    style="border-style: dotted; border-width: 1px;">';
-    html += '    Canvas not supported.';
-    html += '</canvas>';
-    html += '<br><br>';
-    html += 'VNC Clipboard:';
-    html += '<input id="clearButton" type="button" value="Clear"';
-    html += '    onclick="RFB.clipboardClear();"><br>';
-    html += '<textarea id="clipboard" style="font-size:9;" cols=80 rows=5';
-    html += '    onchange="RFB.clipboardPasteFrom();"';
-    html += '    onfocus="RFB.clipboardFocus=true;"';
-    html += '    onblur="RFB.clipboardFocus=false;"></textarea>';
-    $('vnc').innerHTML = html;
-
-    /* Load web-socket-js if no builtin WebSocket support */
-    if (VNC_native_ws) {
-        console.log("Using native WebSockets");
-        RFB.updateState('disconnected', 'Disconnected');
-    } else {
-        console.log("Using web-socket-js flash bridge");
-        if ((! Browser.Plugins.Flash) ||
-            (Browser.Plugins.Flash.version < 9)) {
-            RFB.updateState('failed', "WebSockets or Adobe Flash is required");
-        } else if (location.href.substr(0, 7) == "file://") {
-            RFB.updateState('failed', "'file://' URL is incompatible with Adobe Flash");
-        } else {
-            WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
-            RFB.use_seq = true;
-            RFB.updateState('disconnected', 'Disconnected');
-        }
-    }
-
-    /* Populate the controls if defaults are provided in the URL */
-    if (RFB.state == 'disconnected') {
-        var url = document.location.href;
-        $('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
-        $('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
-        $('password').value = (url.match(/password=([^&#]*)/) || ['',''])[1];
-        $('encrypt').checked = (url.match(/encrypt=([^&#]*)/) || ['',''])[1];
-    }
-}
-
 /*
 /*
  * Make arrays quack
  * Make arrays quack
  */
  */
@@ -372,7 +311,7 @@ init_msg: function () {
         var name_length   = RQ.shift32();
         var name_length   = RQ.shift32();
         RFB.fb_name = RQ.shiftStr(name_length);
         RFB.fb_name = RQ.shiftStr(name_length);
 
 
-        Canvas.init('canvas', RFB.fb_width, RFB.fb_height,
+        Canvas.init('VNC_canvas', RFB.fb_width, RFB.fb_height,
                 RFB.keyDown, RFB.keyUp,
                 RFB.keyDown, RFB.keyUp,
                 RFB.mouseDown, RFB.mouseUp, RFB.mouseMove);
                 RFB.mouseDown, RFB.mouseUp, RFB.mouseMove);
 
 
@@ -801,7 +740,7 @@ clientCutText: function (text) {
     arr.push8(0);  // padding
     arr.push8(0);  // padding
     arr.push32(text.length);
     arr.push32(text.length);
     arr.pushStr(text);
     arr.pushStr(text);
-    console.log("<< clientCutText");
+    console.log("<< clientCutText:" + arr);
     return arr;
     return arr;
 },
 },
 
 
@@ -1003,26 +942,26 @@ mouseMove: function(e) {
 
 
 clipboardCopyTo: function (text) {
 clipboardCopyTo: function (text) {
     console.log(">> clipboardCopyTo: " + text.substr(0,40) + "...");
     console.log(">> clipboardCopyTo: " + text.substr(0,40) + "...");
-    $('clipboard').value = text;
+    $('VNC_clipboard_text').value = text;
     console.log("<< clipboardCopyTo");
     console.log("<< clipboardCopyTo");
 },
 },
 
 
 clipboardPasteFrom: function () {
 clipboardPasteFrom: function () {
     if (RFB.state != "normal") return;
     if (RFB.state != "normal") return;
-    var text = $('clipboard').value;
+    var text = $('VNC_clipboard_text').value;
     console.log(">> clipboardPasteFrom: " + text.substr(0,40) + "...");
     console.log(">> clipboardPasteFrom: " + text.substr(0,40) + "...");
     RFB.send_array(RFB.clientCutText(text));
     RFB.send_array(RFB.clientCutText(text));
     console.log("<< clipboardPasteFrom");
     console.log("<< clipboardPasteFrom");
 },
 },
 
 
 clipboardClear: function () {
 clipboardClear: function () {
-    $('clipboard').value = '';
+    $('VNC_clipboard_text').value = '';
     RFB.clipboardPasteFrom();
     RFB.clipboardPasteFrom();
 },
 },
 
 
 updateState: function(state, statusMsg) {
 updateState: function(state, statusMsg) {
-    var s = $('status');
-    var c = $('connectButton');
+    var s = $('VNC_status');
+    var c = $('VNC_connect_button');
     var func = function(msg) { console.log(msg) };
     var func = function(msg) { console.log(msg) };
     switch (state) {
     switch (state) {
         case 'failed':
         case 'failed':
@@ -1134,10 +1073,10 @@ init_vars: function () {
 
 
 connect: function () {
 connect: function () {
     console.log(">> connect");
     console.log(">> connect");
-    RFB.host = $('host').value;
-    RFB.port = $('port').value;
-    RFB.password = $('password').value;
-    if ($('encrypt').checked) {
+    RFB.host = $('VNC_host').value;
+    RFB.port = $('VNC_port').value;
+    RFB.password = $('VNC_password').value;
+    if ($('VNC_encrypt').checked) {
         RFB.scheme = "wss://";
         RFB.scheme = "wss://";
     } else {
     } else {
         RFB.scheme = "ws://";
         RFB.scheme = "ws://";
@@ -1180,4 +1119,90 @@ disconnect: function () {
     console.log("<< disconnect");
     console.log("<< disconnect");
 },
 },
 
 
+/* 
+ * Load the controls
+ */
+load: function (target) {
+    console.log(">> RFB.load");
+
+    if (!target) { target = 'vnc' };
+
+    /* Populate the 'vnc' div */
+    var html = "";
+    if ($('VNC_controls') === null) {
+        html += '<div id="VNC_controls">';
+        html += '  <ul>';
+        html += '    <li>Host: <input id="VNC_host"></li>';
+        html += '    <li>Port: <input id="VNC_port"></li>';
+        html += '    <li>Password: <input id="VNC_password" type="password"></li>';
+        html += '    <li>Encrypt: <input id="VNC_encrypt" type="checkbox"></li>';
+        html += '    <li><input id="VNC_connect_button" type="button"';
+        html += '           value="Loading" disabled></li>';
+        html += '  </ul>';
+        html += '</div>';
+    }
+    if ($('VNC_screen') === null) {
+        html += '<div id="VNC_screen">';
+        html += '</div>';
+    }
+    if ($('VNC_clipboard') === null) {
+        html += '<br><br>';
+        html += '<div id="VNC_clipboard">';
+        html += '  VNC Clipboard:';
+        html += '  <input id="VNC_clipboard_clear_button" type="button" value="Clear">';
+        html += '  <br>';
+        html += '  <textarea id="VNC_clipboard_text" cols=80 rows=5>';
+        html += '      </textarea>';
+        html += '</div>';
+    }
+    $(target).innerHTML = html;
+
+    html = "";
+    if ($('VNC_status') === null) {
+        html += '<div id="VNC_status">Loading</div>';
+    }
+    if ($('VNC_canvas') === null) {
+        html += '<canvas id="VNC_canvas" width="640px" height="20px">';
+        html += '    Canvas not supported.';
+        html += '</canvas>';
+    }
+    $('VNC_screen').innerHTML += html;
+
+    /* Add handlers */
+    $('VNC_clipboard_clear_button').onclick = RFB.clipboardClear;
+    var clipt = $('VNC_clipboard_text')
+    clipt.onchange = RFB.clipboardPasteFrom;
+    clipt.onfocus = function () { RFB.clipboardFocus = true; };
+    clipt.onblur = function () { RFB.clipboardFocus = false; };
+
+    /* Load web-socket-js if no builtin WebSocket support */
+    if (VNC_native_ws) {
+        console.log("Using native WebSockets");
+        RFB.updateState('disconnected', 'Disconnected');
+    } else {
+        console.log("Using web-socket-js flash bridge");
+        if ((! Browser.Plugins.Flash) ||
+            (Browser.Plugins.Flash.version < 9)) {
+            RFB.updateState('failed', "WebSockets or Adobe Flash is required");
+        } else if (location.href.substr(0, 7) == "file://") {
+            RFB.updateState('failed', "'file://' URL is incompatible with Adobe Flash");
+        } else {
+            WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
+            RFB.use_seq = true;
+            RFB.updateState('disconnected', 'Disconnected');
+        }
+    }
+
+    /* Populate the controls if defaults are provided in the URL */
+    if (RFB.state == 'disconnected') {
+        var url = document.location.href;
+        $('VNC_host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
+        $('VNC_port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
+        $('VNC_password').value = (url.match(/password=([^&#]*)/) || ['',''])[1];
+        $('VNC_encrypt').checked = (url.match(/encrypt=([^&#]*)/) || ['',''])[1];
+    }
+
+    console.log("<< RFB.load");
+}
+
 }; /* End of RFB */
 }; /* End of RFB */