Commit ded9dfae authored by Joel Martin's avatar Joel Martin

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.
parent 3a2fafac
...@@ -78,3 +78,22 @@ Usage ...@@ -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.
#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;
}
...@@ -2,11 +2,16 @@ ...@@ -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>
/* /*
* HTML5 VNC client. To use, include this script and define a div with * HTML5 VNC client
* id of 'vnc'. For example: *
* <html><body> * Licensed under AGPL-3 (see LICENSE.AGPL-3)
* <script src='vnc.js'></script> *
* <div id='vnc'>Loading</div> * See README.md for usage and integration instructions.
* </body></html>
* *
* 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) { ...@@ -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 () { ...@@ -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) { ...@@ -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) { ...@@ -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 s = $('VNC_status');
var c = $('connectButton'); 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 () { ...@@ -1134,10 +1073,10 @@ init_vars: function () {
connect: function () { connect: function () {
console.log(">> connect"); console.log(">> connect");
RFB.host = $('host').value; RFB.host = $('VNC_host').value;
RFB.port = $('port').value; RFB.port = $('VNC_port').value;
RFB.password = $('password').value; RFB.password = $('VNC_password').value;
if ($('encrypt').checked) { if ($('VNC_encrypt').checked) {
RFB.scheme = "wss://"; RFB.scheme = "wss://";
} else { } else {
RFB.scheme = "ws://"; RFB.scheme = "ws://";
...@@ -1180,4 +1119,90 @@ disconnect: function () { ...@@ -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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment