Added internal websocket and oztex

This commit is contained in:
Deon George 2019-01-16 14:07:59 +11:00
parent 87835dfd74
commit 25f3b37f8d
No known key found for this signature in database
GPG Key ID: 7670E8DC27415254
13 changed files with 2027 additions and 19 deletions

View File

@ -1,7 +1,7 @@
---
title: Chinwag BBS
comments: false
date: 2018-08-31 16:00:24
date: 2018-08-31
thumbnail: /images/chinwag.png
category:
- BBS
@ -12,26 +12,28 @@ Chinwag is a BBS running on a Raspberry Pi under Docker.
If you would like to explore BBS, Echomail and Netmail without having to setup a BBS for yourself, you are welcome to connect to mine.
Just press the *Connect* button below, and create an account. The first time you login you'll have limited abilities, but send me a note and I'll upgrade you so that you can use the Echomail and Netmail areas.
<div id="fTelnetContainer_chinwag_leenooks_net_10023" class="fTelnetContainer"></div>
<div id="fTelnetContainer" class="fTelnetContainer"></div>
<script>document.write('<script src="//embed-v2.ftelnet.ca/js/ftelnet-loader.norip.xfer.js?v=' + (new Date()).getTime() + '"><\/script>');</script>
<script>
var Options_chinwag_leenooks_net_10023 = new fTelnetOptions();
Options_chinwag_leenooks_net_10023.BareLFtoCRLF = false;
Options_chinwag_leenooks_net_10023.BitsPerSecond = 57600;
Options_chinwag_leenooks_net_10023.ConnectionType = 'tcp';
Options_chinwag_leenooks_net_10023.Emulation = 'ansi-bbs';
Options_chinwag_leenooks_net_10023.Enter = '\r';
Options_chinwag_leenooks_net_10023.Font = 'CP437';
Options_chinwag_leenooks_net_10023.ForceWss = false;
Options_chinwag_leenooks_net_10023.Hostname = 'chinwag.leenooks.net';
Options_chinwag_leenooks_net_10023.LocalEcho = false;
Options_chinwag_leenooks_net_10023.Port = 10023;
Options_chinwag_leenooks_net_10023.ProxyHostname = 'proxy-au.ftelnet.ca';
Options_chinwag_leenooks_net_10023.ProxyPort = 8410;
Options_chinwag_leenooks_net_10023.ScreenColumns = 80;
Options_chinwag_leenooks_net_10023.ScreenRows = 25;
Options_chinwag_leenooks_net_10023.SplashScreen = 'G1swbRtbNEMbWzMybS5+fi4gICAufn4uG1s3QxtbMzFt3BtbMTs0MW2xsbGxsRtbNDBtICAbWzQxbbGxG1s0MG0gIBtbNDFtsbEbWzQwbSAgG1s0MW2xsRtbNDBtICAbWzQxbbGxG1s0MG3cICAbWzQxbbGxG1s0MG0gIBtbNDFtsbEbWzQwbSAgIBtbNDFtsbEbWzQwbSAg3BtbNDFtsbGxsRtbNDBt3CAgICDcG1s0MW2xsbEbWzQwbSAgICAbWzM3bSANChtbM0MbWzA7MzJtJy4gXCAnICcgLyAuJxtbNkMbWzE7MzE7NDFtsrIbWzQwbSAgG1s0MW2yshtbNDBtICAbWzQxbbKyG1s0MG0gIBtbNDFtsrIbWzQwbSAgG1s0MW2yshtbNDBtICAbWzQxbbKyG1s0MG3fG1s0MW2yG1s0MG3cG1s0MW2yshtbNDBtICAbWzQxbbKyG1s0MG0gICAbWzQxbbKyG1s0MG0gIBtbNDFtsrIbWzQwbSAgG1s0MW2yshtbNDBtICDcG1s0MW2yG1s0MG3fIBtbNDFtsrIbWzQwbRtbMzdtDQobWzRDG1swOzMxbS5+IC5+fn4uLn4uG1s3QxtbMW3f3xtbNkPf3yAg398gIN/fICDf3xtbMzBt2dkbWzMxbd/f3yAg398gIBtbMzBt2RtbMzFt398gIN/fIBtbMzBt2RtbMzFt398gIN/fG1szMG3AwBtbMzFt398bWzM3bQ0KG1szQxtbMDszMW06IC5+Lid+Jy5+LiA6G1s2QxtbMTszNzs0N22yshtbNDBtG1s2QxtbNDdtsrIbWzQwbd/fG1s0N22yshtbNDBtICAbWzQ3bbKyG1s0MG0gIBtbNDdtsrIbWzQwbSAgIBtbNDdtsrIbWzQwbSAgG1s0N22yshtbNDBtIBtbNDdtshtbNDBtIBtbNDdtsrIbWzQwbSAgG1s0N22yshtbNDBt398bWzQ3bbKyG1s0MG0gIBtbNDdtshtbNDBt3SDfG1s0N22yshtbNDBtDQobWzJDG1swOzMxbX4gKCAgICkgKCAgICkgfhtbNUMbWzE7Mzc7NDdtsbEbWzQwbSAgG1s0N22xsRtbNDBtICAbWzQ3bbGxG1s0MG0gIBtbNDdtsbEbWzQwbSAgG1s0N22xsRtbNDBtICAbWzQ3bbGxG1s0MG0gICAbWzQ3bbGxG1s0MG0gIBtbNDdtsbEbWzQwbSAbWzQ3bbEbWzQwbSAbWzQ3bbGxG1s0MG0gIBtbNDdtsbEbWzQwbSAgG1s0N22xsRtbNDBtICDfG1s0N22xG1s0MG3cIBtbNDdtsbEbWzQwbQ0KG1sxQxtbMDszMW0oIDogJ34nLn4uJ34nIDogKSAgICAbWzE7Mzdt3xtbNDdtsLCwsLAbWzQwbSAgG1s0N22wsBtbNDBtICAbWzQ3bbCwG1s0MG0gIBtbNDdtsLAbWzQwbSAgG1s0N22wsBtbNDBtICAgG1s0N22wsBtbNDBtICDfG1s0N22wsBtbNDBt3xtbNDdtsLAbWzQwbd8gIBtbNDdtsLAbWzQwbSAgG1s0N22wsBtbNDBtICAgIN8bWzQ3bbCwsBtbNDBtDQobWzJDG1swOzMxbX4gLn4gKCAgICkgfi4gfhtbNjFDG1swbQ0KG1szQxtbMzFtKCAgOiAnficgOiAgKRtbNkNXZWxvbWUhG1s0NUMgDQobWzRDJ34gLn5+fi4gficbWzdDQ2hpbndhZyBpcyBydW5uaW5nIG9uIGEgUmFzcGJlcnJ5IFBJIGluIERvY2tlciEbWzVDIA0KG1s4Qyd+Jw0KG1s3QxtbMTszMG1fLS1ffFwbWzlDU3lzdGVtICAgIDogWxtbMzdtQ2hpbndhZyAgIBtbMzBtXRtbNkNOb2RlICA6IFsbWzM3bSAgICAgICAxG1szMG1dDQobWzZDLxtbNkNcG1s4Q015c3RpYyBCQlM6IFsbWzM3bTEuMTIgQTM5ICAbWzMwbV0bWzZDRGF0ZSAgOiBbG1szN20xOC8wOC8xOBtbMzBtXQ0KG1s2Q1xfLl9fLhtbMzdtKhtbMzBtLxtbOENTeXNvcBtbNUM6IFsbWzM3bWRlb24gICAgICAbWzMwbV0bWzZDVGltZSAgOiBbG1szN20gIDAxOjAwYRtbMzBtXQ0KG1sxMkNWDQo=';
var fTelnet_chinwag_leenooks_net_10023 = new fTelnetClient('fTelnetContainer_chinwag_leenooks_net_10023', Options_chinwag_leenooks_net_10023);
var Options = new fTelnetOptions();
Options.BareLFtoCRLF = false;
Options.BitsPerSecond = 57600;
Options.ConnectionType = 'telnet';
Options.Emulation = 'ansi-bbs';
Options.Enter = '\r';
Options.Font = 'CP437';
Options.ForceWss = true;
Options.Hostname = 'chinwag.leenooks.net';
Options.LocalEcho = false;
Options.Port = 443;
Options.ProxyHostname = '';
Options.ProxyPort = 80;
Options.ProxyPortSecure = 443;
Options.ScreenColumns = 80;
Options.ScreenRows = 25;
Options.WebSocketUrlPath = '/ws/chinwag/23';
Options.SplashScreen = 'G1swbRtbNEMbWzMybS5+fi4gICAufn4uG1s3QxtbMzFt3BtbMTs0MW2xsbGxsRtbNDBtICAbWzQxbbGxG1s0MG0gIBtbNDFtsbEbWzQwbSAgG1s0MW2xsRtbNDBtICAbWzQxbbGxG1s0MG3cICAbWzQxbbGxG1s0MG0gIBtbNDFtsbEbWzQwbSAgIBtbNDFtsbEbWzQwbSAg3BtbNDFtsbGxsRtbNDBt3CAgICDcG1s0MW2xsbEbWzQwbSAgICAbWzM3bSANChtbM0MbWzA7MzJtJy4gXCAnICcgLyAuJxtbNkMbWzE7MzE7NDFtsrIbWzQwbSAgG1s0MW2yshtbNDBtICAbWzQxbbKyG1s0MG0gIBtbNDFtsrIbWzQwbSAgG1s0MW2yshtbNDBtICAbWzQxbbKyG1s0MG3fG1s0MW2yG1s0MG3cG1s0MW2yshtbNDBtICAbWzQxbbKyG1s0MG0gICAbWzQxbbKyG1s0MG0gIBtbNDFtsrIbWzQwbSAgG1s0MW2yshtbNDBtICDcG1s0MW2yG1s0MG3fIBtbNDFtsrIbWzQwbRtbMzdtDQobWzRDG1swOzMxbS5+IC5+fn4uLn4uG1s3QxtbMW3f3xtbNkPf3yAg398gIN/fICDf3xtbMzBt2dkbWzMxbd/f3yAg398gIBtbMzBt2RtbMzFt398gIN/fIBtbMzBt2RtbMzFt398gIN/fG1szMG3AwBtbMzFt398bWzM3bQ0KG1szQxtbMDszMW06IC5+Lid+Jy5+LiA6G1s2QxtbMTszNzs0N22yshtbNDBtG1s2QxtbNDdtsrIbWzQwbd/fG1s0N22yshtbNDBtICAbWzQ3bbKyG1s0MG0gIBtbNDdtsrIbWzQwbSAgIBtbNDdtsrIbWzQwbSAgG1s0N22yshtbNDBtIBtbNDdtshtbNDBtIBtbNDdtsrIbWzQwbSAgG1s0N22yshtbNDBt398bWzQ3bbKyG1s0MG0gIBtbNDdtshtbNDBt3SDfG1s0N22yshtbNDBtDQobWzJDG1swOzMxbX4gKCAgICkgKCAgICkgfhtbNUMbWzE7Mzc7NDdtsbEbWzQwbSAgG1s0N22xsRtbNDBtICAbWzQ3bbGxG1s0MG0gIBtbNDdtsbEbWzQwbSAgG1s0N22xsRtbNDBtICAbWzQ3bbGxG1s0MG0gICAbWzQ3bbGxG1s0MG0gIBtbNDdtsbEbWzQwbSAbWzQ3bbEbWzQwbSAbWzQ3bbGxG1s0MG0gIBtbNDdtsbEbWzQwbSAgG1s0N22xsRtbNDBtICDfG1s0N22xG1s0MG3cIBtbNDdtsbEbWzQwbQ0KG1sxQxtbMDszMW0oIDogJ34nLn4uJ34nIDogKSAgICAbWzE7Mzdt3xtbNDdtsLCwsLAbWzQwbSAgG1s0N22wsBtbNDBtICAbWzQ3bbCwG1s0MG0gIBtbNDdtsLAbWzQwbSAgG1s0N22wsBtbNDBtICAgG1s0N22wsBtbNDBtICDfG1s0N22wsBtbNDBt3xtbNDdtsLAbWzQwbd8gIBtbNDdtsLAbWzQwbSAgG1s0N22wsBtbNDBtICAgIN8bWzQ3bbCwsBtbNDBtDQobWzJDG1swOzMxbX4gLn4gKCAgICkgfi4gfhtbNjFDG1swbQ0KG1szQxtbMzFtKCAgOiAnficgOiAgKRtbNkNXZWxvbWUhG1s0NUMgDQobWzRDJ34gLn5+fi4gficbWzdDQ2hpbndhZyBpcyBydW5uaW5nIG9uIGEgUmFzcGJlcnJ5IFBJIGluIERvY2tlciEbWzVDIA0KG1s4Qyd+Jw0KG1s3QxtbMTszMG1fLS1ffFwbWzlDU3lzdGVtICAgIDogWxtbMzdtQ2hpbndhZyAgIBtbMzBtXRtbNkNOb2RlICA6IFsbWzM3bSAgICAgICAxG1szMG1dDQobWzZDLxtbNkNcG1s4Q015c3RpYyBCQlM6IFsbWzM3bTEuMTIgQTM5ICAbWzMwbV0bWzZDRGF0ZSAgOiBbG1szN20xOC8wOC8xOBtbMzBtXQ0KG1s2Q1xfLl9fLhtbMzdtKhtbMzBtLxtbOENTeXNvcBtbNUM6IFsbWzM3bWRlb24gICAgICAbWzMwbV0bWzZDVGltZSAgOiBbG1szN20gIDAxOjAwYRtbMzBtXQ0KG1sxMkNWDQo=';
var fTelnet = new fTelnetClient('fTelnetContainer', Options);
</script>
There is some useful terminal emulation software available on the Net.

107
source/_posts/oztex.md Normal file
View File

@ -0,0 +1,107 @@
---
title: OzTex Videotex
comments: false
date: 2019-01-01
thumbnail: /images/oztex.png
category:
- BBS
- OzTex Videotex
---
OzTex is a re-invention of Videotex - which dominated many countries in the 80's and 90's. Its currently under development, providing two presentation experiences: the original Mode 7 Videotex and in a new fusion with ANSI. This post is about the Videotex impementation.
It is still being developed, so the current functionality is very limited. You can see it in action by pressing the **Connect** button below.
<small>**NOTE:** For some keyboards, the hash (#) key is the UK Pound (£) symbol. You should be able to use your **ENTER** key in place of **#**, otherwise you can try your **'** (apostrophe) key.</small>
<small>**TIP:** You can click inside the terminal to zoom full screen. Click outside to unzoom.</small>
{% raw %}
<link rel="stylesheet" href="viewdata/teletext.css" type="text/css">
<div class="viewdata clearer">
<form>
<input id='host' type='hidden'>
<input id='port' type='hidden'>
<input id='encrypt' type='hidden'>
<input id='url' type='hidden'>
<input id='connectButton' type='button' value='Connect' style='width:100px' onclick="connect();">&nbsp;
</form>
<table><tbody><tr><td class="teletext"><div class="teletext zoomTarget" id="terminal" data-targetsize="1" style="padding: 10px; background-color:black;"><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
</span><span style="color:#0000ff;background-color:#000000;">&nbsp;</span><span style="color:#0000ff;background-color:#0000ff;">&nbsp;&nbsp;</span><span style="color:#ffffff;background-color:#0000ff;">
</span><span style="color:#0000ff;background-color:#000000;">&nbsp;</span><span style="color:#0000ff;background-color:#0000ff;">&nbsp;&nbsp;</span><span style="color:#ffffff;background-color:#0000ff;">
</span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;
</span><span style="color:#0000ff;background-color:#000000;">&nbsp;</span><span style="color:#0000ff;background-color:#0000ff;">&nbsp;&nbsp;</span><span style="color:#ffffff;background-color:#0000ff;">&nbsp;A&nbsp;vBBS&nbsp;by</span><span style="color:#ffff00;background-color:#0000ff;">&nbsp;...deon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;Welcome&nbsp;to</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffff00;background-color:#000000;">&nbsp;OzTex</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;
</span><span style="color:#ff0000;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:#0000ff;background-color:#000000;"></span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;Press Connect to begin.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><span style="color:#ffffff;background-color:#000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
</div></td></tr></tbody></table>
<script src="viewdata/base64.js"></script>
<script src="viewdata/util.js"></script>
<script src="viewdata/websock.js"></script>
<script src="viewdata/webutil.js"></script>
<script src="viewdata/keysym.js"></script>
<script src="viewdata/vdata.js"></script>
<script src="viewdata/wsvdata.js"></script>
<script src="/libs/zoomooz/js/jquery.zoomooz.min.js"></script>
<script>
var telnet;
function connect() {
telnet.connect($D('host').value,
$D('port').value,
$D('encrypt').checked,
$D('url').value);
$D('connectButton').disabled = true;
$D('connectButton').value = "Connecting";
}
function disconnect() {
$D('connectButton').disabled = true;
$D('connectButton').value = "Disconnecting";
telnet.disconnect();
}
function connected() {
$D('connectButton').disabled = false;
$D('connectButton').value = "Disconnect";
$D('connectButton').onclick = disconnect;
}
function disconnected() {
$D('connectButton').disabled = false;
$D('connectButton').value = "Connect";
$D('connectButton').onclick = connect;
}
window.onload = function() {
console.log("onload");
var url = document.location.href;
$D('host').value = 'chinwag.leenooks.net';
$D('port').value = '443';
$D('url').value = '/ws/videotex/516';
telnet = Telnet('terminal', connected, disconnected);
}
</script>
</div>
{% endraw %}
If you would like to own some pages on this system, please let me know. Alternatively, if you have some old videotex frames from old systems like Prestel, Viatel, etc that you would like to bring back to life get in contact with me and we'll make it happen.
If you are creative, you can create some frames at http://edit.tf or http://zxnet.co.uk/teletext/editor. I use the http://edit.tf becuase it has some block copy/paste functions, great if you want to move things around. After using http://edit.tf I normally "Export" (E->zxnet Editor) to http://zxnet.co.uk/teletext/editor so that I can save the frame as _Binary dump of level 1 page data_. After saving the frame, its easy for me to import it into the system.
At the moment importing frames is a manual entry by me, but in time, I'll enable that in the system - as well as hopefully create an editor.
If you would like to help me build this, please get in contact.

Binary file not shown.

View File

@ -0,0 +1,144 @@
/*
Teletext stylesheet
Galax 2014-2015 http://galax.xyz
MODE7GX3.TTF font by Galax 2014 - based on ModeSeven, created in 1998 by Andrew Bulhak
*/
/* Hard reset */
/*
html,body,div,span,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,
address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,
sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,
tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,
footer,header,hgroup,menu,nav,output,section,summary,time,audio,video {
padding: 0;
margin: 0;
border: 0;
font-smooth: never;
-webkit-font-smoothing: none;
}
*/
/*
Teletext palette
000000 0 black
ff0000 1 red
00ff00 2 green
ffff00 3 yellow
0000ff 4 blue
ff00ff 5 magenta
00ffff 6 cyan
ffffff 7 white
*/
/*
a {
text-decoration: none;
}
*/
/* unvisited link */
/*
a:link {
color: #00ffff;
}
*/
/* visited link */
/*
a:visited {
color: #00ff00;
}
*/
/* mouse over link */
/*
a:hover {
color: #ffff00;
}
a.yellow:hover, .yellow a:hover {
color: #00ff00;
}
*/
/* selected link */
/*
a:active {
color: #ff0000;
}
a.yellow:active, .yellow a:active {
color: #ff0000;
}
a.red:active, .red a:active {
color: #ffff00;
}
*/
/* flashing class, it's like the 'blink' tag is back */
/*
.flashing {
animation: flashing 1.3s steps(5, start) infinite;
-webkit-animation: flashing 1.3s steps(5, start) infinite;
}
@keyframes flashing { to { visibility: hidden; } }
@-webkit-keyframes flashing { to { visibility: hidden; } }
*/
/* concealed text is initially hidden, reveal by modifying class */
/*
.conceal { opacity: 0; }
.colour0, .black, a.black, .black a {color: #000000;}
.colour1, .red, a.red, .red a {color: #ff0000;}
.colour2, .green, a.green, .green a {color: #00ff00;}
.colour3, .yellow, a.yellow, .yellow a {color: #ffff00;}
.colour4, .blue, a.blue, .blue a {color: #0000ff;}
.colour5, .magenta, a.magenta, .magenta a{color: #ff00ff;}
.colour6, .cyan, a.cyan, .cyan a {color: #00ffff;}
.colour7, .white, a.white, .white a {color: #ffffff;}
.colour0bg, .blackbg {background-color: #000000;}
.colour1bg, .redbg {background-color: #ff0000;}
.colour2bg, .greenbg {background-color: #00ff00;}
.colour3bg, .yellowbg {background-color: #ffff00;}
.colour4bg, .bluebg {background-color: #0000ff;}
.colour5bg, .magentabg {background-color: #ff00ff;}
.colour6bg, .cyanbg {background-color: #00ffff;}
.colour7bg, .whitebg {background-color: #ffffff;}
*/
@font-face {
font-family: Mode7;
src: url('MODE7GX3.TTF'), url('MODE7GX3.EOT'); /* .EOT is for IE */
}
div.viewdata > table {
margin-left: auto;
margin-right: auto;
width: 0%;
}
td.teletext {
font-family: Mode7, monospace, courier, fixed;
font-size: 20px;
font-smooth: never;
-webkit-font-smoothing : none;
color: #ffffff;
background: #000000;
line-height: 20px;
text-align: left;
white-space: pre;
display: block;
font-size: 20px;
font-smooth: never;
-webkit-font-smoothing : none;
}
/*
body {
border-width: 20px 20px 20px 20px; /* t r b l */
padding: 20px;
}
*/

View File

@ -0,0 +1,114 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
/*jslint white: false, bitwise: false, plusplus: false */
/*global console */
var Base64 = {
/* Convert data (an array of integers) to a Base64 string. */
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''),
base64Pad : '=',
encode: function (data) {
"use strict";
var result = '';
var toBase64Table = Base64.toBase64Table;
var base64Pad = Base64.base64Pad;
var length = data.length;
var i;
// Convert every three bytes to 4 ascii characters.
/* BEGIN LOOP */
for (i = 0; i < (length - 2); i += 3) {
result += toBase64Table[data[i] >> 2];
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
result += toBase64Table[data[i+2] & 0x3f];
}
/* END LOOP */
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
if (length%3) {
i = length - (length%3);
result += toBase64Table[data[i] >> 2];
if ((length%3) === 2) {
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
result += toBase64Table[(data[i+1] & 0x0f) << 2];
result += base64Pad;
} else {
result += toBase64Table[(data[i] & 0x03) << 4];
result += base64Pad + base64Pad;
}
}
return result;
},
/* Convert Base64 data to a string */
toBinaryTable : [
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
],
decode: function (data, offset) {
"use strict";
offset = typeof(offset) !== 'undefined' ? offset : 0;
var toBinaryTable = Base64.toBinaryTable;
var base64Pad = Base64.base64Pad;
var result, result_length, idx, i, c, padding;
var leftbits = 0; // number of bits decoded, but yet to be appended
var leftdata = 0; // bits decoded, but yet to be appended
var data_length = data.indexOf('=') - offset;
if (data_length < 0) { data_length = data.length - offset; }
/* Every four characters is 3 resulting numbers */
result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5);
result = new Array(result_length);
// Convert one by one.
/* BEGIN LOOP */
for (idx = 0, i = offset; i < data.length; i++) {
c = toBinaryTable[data.charCodeAt(i) & 0x7f];
padding = (data.charAt(i) === base64Pad);
// Skip illegal characters and whitespace
if (c === -1) {
console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
continue;
}
// Collect data into leftdata, update bitcount
leftdata = (leftdata << 6) | c;
leftbits += 6;
// If we have 8 or more bits, append 8 bits to the result
if (leftbits >= 8) {
leftbits -= 8;
// Append if not padding.
if (!padding) {
result[idx++] = (leftdata >> leftbits) & 0xff;
}
leftdata &= (1 << leftbits) - 1;
}
}
/* END LOOP */
// If there are any bits left, the base64 string was corrupted
if (leftbits) {
throw {name: 'Base64-Error',
message: 'Corrupted base64 string'};
}
return result;
}
}; /* End of Base64 namespace */

View File

@ -0,0 +1,98 @@
/*
* from noVNC: HTML5 VNC client
* Copyright (C) 2010 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*/
/* Translate DOM key down/up event to keysym value */
function getKeysym(e) {
var evt, keysym;
evt = (e ? e : window.event);
/* Remap modifier and special keys */
switch ( evt.keyCode ) {
case 8 : keysym = 0xFF08; break; // BACKSPACE
case 9 : keysym = 0xFF09; break; // TAB
case 13 : keysym = 0xFF0D; break; // ENTER
case 27 : keysym = 0xFF1B; break; // ESCAPE
case 45 : keysym = 0xFF63; break; // INSERT
case 46 : keysym = 0xFFFF; break; // DELETE
case 36 : keysym = 0xFF50; break; // HOME
case 35 : keysym = 0xFF57; break; // END
case 33 : keysym = 0xFF55; break; // PAGE_UP
case 34 : keysym = 0xFF56; break; // PAGE_DOWN
case 37 : keysym = 0xFF51; break; // LEFT
case 38 : keysym = 0xFF52; break; // UP
case 39 : keysym = 0xFF53; break; // RIGHT
case 40 : keysym = 0xFF54; break; // DOWN
case 112 : keysym = 0xFFBE; break; // F1
case 113 : keysym = 0xFFBF; break; // F2
case 114 : keysym = 0xFFC0; break; // F3
case 115 : keysym = 0xFFC1; break; // F4
case 116 : keysym = 0xFFC2; break; // F5
case 117 : keysym = 0xFFC3; break; // F6
case 118 : keysym = 0xFFC4; break; // F7
case 119 : keysym = 0xFFC5; break; // F8
case 120 : keysym = 0xFFC6; break; // F9
case 121 : keysym = 0xFFC7; break; // F10
case 122 : keysym = 0xFFC8; break; // F11
case 123 : keysym = 0xFFC9; break; // F12
case 16 : keysym = 0xFFE1; break; // SHIFT
case 17 : keysym = 0xFFE3; break; // CONTROL
//case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option)
case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command)
default : keysym = evt.keyCode; break;
}
/* Remap symbols */
switch (keysym) {
case 186 : keysym = 59; break; // ; (IE)
case 187 : keysym = 61; break; // = (IE)
case 188 : keysym = 44; break; // , (Mozilla, IE)
case 109 : // - (Mozilla)
if (Util.Engine.gecko) {
keysym = 45; }
break;
case 189 : keysym = 45; break; // - (IE)
case 190 : keysym = 46; break; // . (Mozilla, IE)
case 191 : keysym = 47; break; // / (Mozilla, IE)
case 192 : keysym = 96; break; // ` (Mozilla, IE)
case 219 : keysym = 91; break; // [ (Mozilla, IE)
case 220 : keysym = 92; break; // \ (Mozilla, IE)
case 221 : keysym = 93; break; // ] (Mozilla, IE)
case 222 : keysym = 39; break; // ' (Mozilla, IE)
}
/* Remap shifted and unshifted keys */
if (!!evt.shiftKey) {
switch (keysym) {
case 48 : keysym = 41 ; break; // ) (shifted 0)
case 49 : keysym = 33 ; break; // ! (shifted 1)
case 50 : keysym = 64 ; break; // @ (shifted 2)
case 51 : keysym = 35 ; break; // # (shifted 3)
case 52 : keysym = 36 ; break; // $ (shifted 4)
case 53 : keysym = 37 ; break; // % (shifted 5)
case 54 : keysym = 94 ; break; // ^ (shifted 6)
case 55 : keysym = 38 ; break; // & (shifted 7)
case 56 : keysym = 42 ; break; // * (shifted 8)
case 57 : keysym = 40 ; break; // ( (shifted 9)
case 59 : keysym = 58 ; break; // : (shifted `)
case 61 : keysym = 43 ; break; // + (shifted ;)
case 44 : keysym = 60 ; break; // < (shifted ,)
case 45 : keysym = 95 ; break; // _ (shifted -)
case 46 : keysym = 62 ; break; // > (shifted .)
case 47 : keysym = 63 ; break; // ? (shifted /)
case 96 : keysym = 126; break; // ~ (shifted `)
case 91 : keysym = 123; break; // { (shifted [)
case 92 : keysym = 124; break; // | (shifted \)
case 93 : keysym = 125; break; // } (shifted ])
case 39 : keysym = 34 ; break; // " (shifted ')
}
} else if ((keysym >= 65) && (keysym <=90)) {
/* Remap unshifted A-Z */
keysym += 32;
}
return keysym;
}

View File

@ -0,0 +1,379 @@
/*
* from noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
"use strict";
/*jslint bitwise: false, white: false */
/*global window, console, document, navigator, ActiveXObject */
// Globals defined here
var Util = {};
/*
* Make arrays quack
*/
Array.prototype.push8 = function (num) {
this.push(num & 0xFF);
};
Array.prototype.push16 = function (num) {
this.push((num >> 8) & 0xFF,
(num ) & 0xFF );
};
Array.prototype.push32 = function (num) {
this.push((num >> 24) & 0xFF,
(num >> 16) & 0xFF,
(num >> 8) & 0xFF,
(num ) & 0xFF );
};
// IE does not support map (even in IE9)
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.map)
{
Array.prototype.map = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array(len);
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
res[i] = fun.call(thisp, this[i], i, this);
}
return res;
};
}
//
// requestAnimationFrame shim with setTimeout fallback
//
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
/*
* ------------------------------------------------------
* Namespaced in Util
* ------------------------------------------------------
*/
/*
* Logging/debug routines
*/
Util._log_level = 'warn';
Util.init_logging = function (level) {
if (typeof level === 'undefined') {
level = Util._log_level;
} else {
Util._log_level = level;
}
if (typeof window.console === "undefined") {
if (typeof window.opera !== "undefined") {
window.console = {
'log' : window.opera.postError,
'warn' : window.opera.postError,
'error': window.opera.postError };
} else {
window.console = {
'log' : function(m) {},
'warn' : function(m) {},
'error': function(m) {}};
}
}
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
switch (level) {
case 'debug': Util.Debug = function (msg) { console.log(msg); };
case 'info': Util.Info = function (msg) { console.log(msg); };
case 'warn': Util.Warn = function (msg) { console.warn(msg); };
case 'error': Util.Error = function (msg) { console.error(msg); };
case 'none':
break;
default:
throw("invalid logging type '" + level + "'");
}
};
Util.get_logging = function () {
return Util._log_level;
};
// Initialize logging level
Util.init_logging();
// Set configuration default for Crockford style function namespaces
Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) {
var getter, setter;
// Default getter function
getter = function (idx) {
if ((type in {'arr':1, 'array':1}) &&
(typeof idx !== 'undefined')) {
return cfg[v][idx];
} else {
return cfg[v];
}
};
// Default setter function
setter = function (val, idx) {
if (type in {'boolean':1, 'bool':1}) {
if ((!val) || (val in {'0':1, 'no':1, 'false':1})) {
val = false;
} else {
val = true;
}
} else if (type in {'integer':1, 'int':1}) {
val = parseInt(val, 10);
} else if (type === 'str') {
val = String(val);
} else if (type === 'func') {
if (!val) {
val = function () {};
}
}
if (typeof idx !== 'undefined') {
cfg[v][idx] = val;
} else {
cfg[v] = val;
}
};
// Set the description
api[v + '_description'] = desc;
// Set the getter function
if (typeof api['get_' + v] === 'undefined') {
api['get_' + v] = getter;
}
// Set the setter function with extra sanity checks
if (typeof api['set_' + v] === 'undefined') {
api['set_' + v] = function (val, idx) {
if (mode in {'RO':1, 'ro':1}) {
throw(v + " is read-only");
} else if ((mode in {'WO':1, 'wo':1}) &&
(typeof cfg[v] !== 'undefined')) {
throw(v + " can only be set once");
}
setter(val, idx);
};
}
// Set the default value
if (typeof defaults[v] !== 'undefined') {
defval = defaults[v];
} else if ((type in {'arr':1, 'array':1}) &&
(! (defval instanceof Array))) {
defval = [];
}
// Coerce existing setting to the right type
//Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]);
setter(defval);
};
// Set group of configuration defaults
Util.conf_defaults = function(cfg, api, defaults, arr) {
var i;
for (i = 0; i < arr.length; i++) {
Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1],
arr[i][2], arr[i][3], arr[i][4]);
}
};
/*
* Cross-browser routines
*/
// Dynamically load scripts without using document.write()
// Reference: http://unixpapa.com/js/dyna.html
//
// Handles the case where load_scripts is invoked from a script that
// itself is loaded via load_scripts. Once all scripts are loaded the
// window.onscriptsloaded handler is called (if set).
Util.get_include_uri = function() {
return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/";
}
Util._loading_scripts = [];
Util._pending_scripts = [];
Util.load_scripts = function(files) {
var head = document.getElementsByTagName('head')[0], script,
ls = Util._loading_scripts, ps = Util._pending_scripts;
for (var f=0; f<files.length; f++) {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = Util.get_include_uri() + files[f];
//console.log("loading script: " + script.src);
script.onload = script.onreadystatechange = function (e) {
while (ls.length > 0 && (ls[0].readyState === 'loaded' ||
ls[0].readyState === 'complete')) {
// For IE, append the script to trigger execution
var s = ls.shift();
//console.log("loaded script: " + s.src);
head.appendChild(s);
}
if (!this.readyState ||
(Util.Engine.presto && this.readyState === 'loaded') ||
this.readyState === 'complete') {
if (ps.indexOf(this) >= 0) {
this.onload = this.onreadystatechange = null;
//console.log("completed script: " + this.src);
ps.splice(ps.indexOf(this), 1);
// Call window.onscriptsload after last script loads
if (ps.length === 0 && window.onscriptsload) {
window.onscriptsload();
}
}
}
};
// In-order script execution tricks
if (Util.Engine.trident) {
// For IE wait until readyState is 'loaded' before
// appending it which will trigger execution
// http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
ls.push(script);
} else {
// For webkit and firefox set async=false and append now
// https://developer.mozilla.org/en-US/docs/HTML/Element/script
script.async = false;
head.appendChild(script);
}
ps.push(script);
}
}
// Get DOM element position on page
Util.getPosition = function (obj) {
var x = 0, y = 0;
if (obj.offsetParent) {
do {
x += obj.offsetLeft;
y += obj.offsetTop;
obj = obj.offsetParent;
} while (obj);
}
return {'x': x, 'y': y};
};
// Get mouse event position in DOM element
Util.getEventPosition = function (e, obj, scale) {
var evt, docX, docY, pos;
//if (!e) evt = window.event;
evt = (e ? e : window.event);
evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt);
if (evt.pageX || evt.pageY) {
docX = evt.pageX;
docY = evt.pageY;
} else if (evt.clientX || evt.clientY) {
docX = evt.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
docY = evt.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
pos = Util.getPosition(obj);
if (typeof scale === "undefined") {
scale = 1;
}
return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale};
};
// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
Util.addEvent = function (obj, evType, fn){
if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else if (obj.addEventListener){
obj.addEventListener(evType, fn, false);
return true;
} else {
throw("Handler could not be attached");
}
};
Util.removeEvent = function(obj, evType, fn){
if (obj.detachEvent){
var r = obj.detachEvent("on"+evType, fn);
return r;
} else if (obj.removeEventListener){
obj.removeEventListener(evType, fn, false);
return true;
} else {
throw("Handler could not be removed");
}
};
Util.stopEvent = function(e) {
if (e.stopPropagation) { e.stopPropagation(); }
else { e.cancelBubble = true; }
if (e.preventDefault) { e.preventDefault(); }
else { e.returnValue = false; }
};
// Set browser engine versions. Based on mootools.
Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)};
Util.Engine = {
// Version detection break in Opera 11.60 (errors on arguments.callee.caller reference)
//'presto': (function() {
// return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()),
'presto': (function() { return (!window.opera) ? false : true; }()),
'trident': (function() {
return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()),
'webkit': (function() {
try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()),
//'webkit': (function() {
// return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()),
'gecko': (function() {
return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }())
};
if (Util.Engine.webkit) {
// Extract actual webkit version if available
Util.Engine.webkit = (function(v) {
var re = new RegExp('WebKit/([0-9\.]*) ');
v = (navigator.userAgent.match(re) || ['', v])[1];
return parseFloat(v, 10);
})(Util.Engine.webkit);
}
Util.Flash = (function(){
var v, version;
try {
v = navigator.plugins['Shockwave Flash'].description;
} catch(err1) {
try {
v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
} catch(err2) {
v = '0 r0';
}
}
version = v.match(/\d+/g);
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
}());

View File

@ -0,0 +1,320 @@
// VD.js -- a viewdata terminal emulator
// constructor
function VD(wd, ht, scr_id)
{
var r;
var c;
var scr = document.getElementById(scr_id);
this.wd_ = wd;
this.ht_ = ht;
this.text_ = new Array(ht);
for (r = 0; r < ht; ++r) {
this.text_[r] = new Array(wd);
}
this.scr_ = scr;
this.cursor_vis_ = true;
this.getch_isr_ = undefined;
this.grab_events_ = false;
this.key_buf_ = [];
this.esc_state_ = 0;
this.col_ = 0;
this.row_ = 0;
// Internal debug setting.
this.clear();
//this.refresh();
}
VD.A_REVERSE = 2;
VD.A_BLINK = 4;
VD.browser_ie_ = (navigator.appName.indexOf("Microsoft") != -1);
VD.browser_opera_ = (navigator.appName.indexOf("Opera") != -1);
// class variables
VD.the_vt_ = undefined;
// object methods
VD.prototype.html_colours_ = function(at_fg, at_bg, at_mode)
{
var co0, co1;
if (at_mode & VD.A_REVERSE) {
co0 = 'ff';
co1 = '00';
} else {
co0 = '00';
co1 = 'ff';
}
return {
f: '#' + (at_fg & 1 ? co1 : co0) +
(at_fg & 2 ? co1 : co0) +
(at_fg & 4 ? co1 : co0),
b: '#' + (at_bg & 1 ? co1 : co0) +
(at_bg & 2 ? co1 : co0) +
(at_bg & 4 ? co1 : co0)
};
}
VD.prototype.clear = function()
{
this.row_ = this.col_ = 0;
for (r = 0; r < this.ht_; ++r) {
for (c = 0; c < this.wd_; ++c) {
this.text_[r][c] = ' ';
}
}
}
VD.prototype.curs_set = function(vis, grab, eventist)
{
if (vis !== undefined)
this.cursor_vis_ = (vis > 0);
}
VD.prototype.getch = function(isr)
{
// this.refresh();
this.getch_isr_ = isr;
setTimeout(VD.go_getch_, 0);
}
VD.go_getch_ = function VD_go_getch()
{
var vt = VD.the_vt_;
if (vt === undefined)
return;
var isr = vt.getch_isr_;
vt.getch_isr_ = undefined;
if (isr === undefined)
return;
var ch = vt.key_buf_.shift();
if (ch === undefined) {
vt.getch_isr_ = isr;
return;
}
isr(ch, vt);
}
VD.prototype.move = function(r, c)
{
if (r < 0)
r = 0;
else if (r >= this.ht_)
r = this.ht_ - 1;
if (c < 0)
c = 0;
else if (c >= this.wd_)
c = this.wd_ - 1;
this.row_ = r;
this.col_ = c;
}
VD.prototype.refresh = function()
{
var r, c, stuff = "", start_tag = "", end_tag = "", ch,
pair, cr, cc, ht, wd, cv, n_fg, n_bg, n_mode, n_type, a_fg=-1, a_bg=-1, a_mode=-1;
ht = this.ht_;
wd = this.wd_;
cr = this.row_;
cc = this.col_;
cv = this.cursor_vis_;
// var innerHTML = this.scr_.innerHTML;
if (cc >= wd)
cc = wd - 1;
for (r = 0; r < ht; ++r) {
if (r > 0) {
stuff += '\n';
}
n_fg = 7;
n_bg = 0;
n_mode = 0;
n_type = 0;
for (c = 0; c < wd; ++c) {
if (cv && r == cr && c == cc) {
// Draw the cursor here.
n_mode |= VD.A_REVERSE;
} else {
n_mode &= ~VD.A_REVERSE;
}
ch = this.text_[r][c];
//console.log('CH: %i (%s) [%i,%i]',ch.charCodeAt(0),ch,r,c);
if (ch.charCodeAt(0) >= 129 && ch.charCodeAt(0) <= 135) {
n_fg = ch.charCodeAt(0)-128;
n_type &= ~2;
n_type &= ~16;
}
if (ch.charCodeAt(0) >= 145 && ch.charCodeAt(0) <= 151) {
n_fg = ch.charCodeAt(0)-144;
n_type |= 2;
n_type &= ~16;
}
if (ch == '\x88')
n_mode |= VD.A_BLINK;
if (ch == '\x89')
n_mode &= ~VD.A_BLINK;
if (ch == '\x8c')
n_type &= ~8;
if (ch == '\x8d')
n_type |= 8;
if (ch == '\x98')
n_type |= 16;
if (ch == '\x99')
n_type &= ~1;
if (ch == '\x9a')
n_type |= 1;
if (ch == '\x9c')
n_bg = 0;
if (ch == '\x9d')
n_bg = n_fg;
if (ch == '\x9e')
n_type |= 32;
if (ch == '\x9f')
n_type &= ~32;
// If the attributes changed, make a new span.
if (n_mode != a_mode || n_fg != a_fg || n_bg != a_bg) {
stuff += end_tag;
pair = this.html_colours_(n_fg, n_bg, n_mode);
stuff += '<span style="color:' + pair.f + ';background-color:' + pair.b + ';">';
// + (n_mode & VD.A_BLINK ? ' class="blink"' : '') + '>';
end_tag = "</span>";
a_fg = n_fg;
a_bg = n_bg;
a_mode = n_mode;
}
if (ch.charCodeAt(0) >= 128)
ch = ' ';
if (n_type & 2) {
if ( ch.charCodeAt(0) >= 0x20 && ch.charCodeAt(0) <= 0x3f) {
ch = '&#x' + (ch.charCodeAt(0)+0xe1e0+((n_type & 1)*0xc0)).toString(16) +";";
} else if ( ch.charCodeAt(0) >= 0x60 && ch.charCodeAt(0) <= 0x7f) {
ch = '&#x' + (ch.charCodeAt(0)+0xe1c0+((n_type & 1)*0xc0)).toString(16) +";";
}
}
switch (ch) {
case '&':
stuff += '&amp;'; break;
case '<':
stuff += '&lt;'; break;
case '>':
stuff += '&gt;'; break;
case ' ':
// stuff += '&nbsp;'; break;
stuff += '\xa0'; break;
case '\x7e':
case '~':
stuff += '\xf7'; break;
case '\x7f':
stuff += "&#xe23f;"; break
case '_':
stuff += '#'; break
case '{':
stuff += '\xbc'; break
case '\\':
stuff += '\xbd'; break
case '}':
stuff += '\xbe'; break
case '#':
stuff += '\xa3'; break
default:
stuff += ch;
}
}
}
stuff += end_tag
//this.scr_.innerHTML = "<b>" + stuff + "</b>\n";
this.scr_.innerHTML = stuff + "\n";
}
VD.prototype.write = function(stuff)
{
var ch, i;
for (i = 0; i < stuff.length; ++i) {
ch = stuff.charCodeAt(i);
if (this.esc_state_ && ch > 31)
ch = (ch % 32) + 128;
this.esc_state_ = 0;
switch (ch) {
case 8:
if (this.col_ != 0) {
--this.col_;
} else {
this.col_ = this.wd_-1;
if (this.row_ == 0) {
this.row_ = this.ht_-1;
} else {
--this.row_;
}
}
break;
case 9:
if (this.col_ >= this.wd_) {
this.col_ = 0;
if (this.row_ == this.ht_-1) {
this.row_ = 0;
} else {
++this.row_;
}
} else {
++this.col_;
}
break;
case 10:
if (this.row_ >= this.ht_-1) {
this.row_ = 0;
} else {
++this.row_;
}
break;
case 11:
if (this.row_ == 0) {
this.row_ = this.ht_-1;
} else {
--this.row_;
}
break;
case 12:
this.clear();
this.move(0, 0);
break;
case 13:
this.col_ = 0;
break;
case 17:
this.curs_set(1);
break;
case 20:
this.curs_set(0);
break;
case 27:
this.esc_state_ = 1;
break;
case 30:
this.move(0, 0);
break;
default:
if (ch > 31) {
this.text_[this.row_][this.col_] = String.fromCharCode(ch);
if (this.col_ >= this.wd_-1) {
this.col_ = 0;
if (this.row_ >= this.ht_-1) {
this.row_ = 0;
} else {
++this.row_;
}
} else {
++this.col_;
}
}
}
}
this.refresh();
}

View File

@ -0,0 +1,424 @@
/*
* Websock: high-performance binary WebSockets
* Copyright (C) 2012 Joel Martin
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* Websock is similar to the standard WebSocket object but Websock
* enables communication with raw TCP sockets (i.e. the binary stream)
* via websockify. This is accomplished by base64 encoding the data
* stream between Websock and websockify.
*
* Websock has built-in receive queue buffering; the message event
* does not contain actual data but is simply a notification that
* there is new data available. Several rQ* methods are available to
* read binary data off of the receive queue.
*/
/*jslint browser: true, bitwise: false, plusplus: false */
/*global Util, Base64 */
// Load Flash WebSocket emulator if needed
// To force WebSocket emulator even when native WebSocket available
//window.WEB_SOCKET_FORCE_FLASH = true;
// To enable WebSocket emulator debug:
//window.WEB_SOCKET_DEBUG=1;
if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
Websock_native = true;
} else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
Websock_native = true;
window.WebSocket = window.MozWebSocket;
} else {
/* no builtin WebSocket so load web_socket.js */
Websock_native = false;
(function () {
window.WEB_SOCKET_SWF_LOCATION = Util.get_include_uri() +
"web-socket-js/WebSocketMain.swf";
if (Util.Engine.trident) {
Util.Debug("Forcing uncached load of WebSocketMain.swf");
window.WEB_SOCKET_SWF_LOCATION += "?" + Math.random();
}
Util.load_scripts(["web-socket-js/swfobject.js",
"web-socket-js/web_socket.js"]);
}());
}
function Websock() {
"use strict";
var api = {}, // Public API
websocket = null, // WebSocket object
mode = 'base64', // Current WebSocket mode: 'binary', 'base64'
rQ = [], // Receive queue
rQi = 0, // Receive queue index
rQmax = 10000, // Max receive queue size before compacting
sQ = [], // Send queue
eventHandlers = {
'message' : function() {},
'open' : function() {},
'close' : function() {},
'error' : function() {}
},
test_mode = false;
//
// Queue public functions
//
function get_sQ() {
return sQ;
}
function get_rQ() {
return rQ;
}
function get_rQi() {
return rQi;
}
function set_rQi(val) {
rQi = val;
}
function rQlen() {
return rQ.length - rQi;
}
function rQpeek8() {
return (rQ[rQi] );
}
function rQshift8() {
return (rQ[rQi++] );
}
function rQunshift8(num) {
if (rQi === 0) {
rQ.unshift(num);
} else {
rQi -= 1;
rQ[rQi] = num;
}
}
function rQshift16() {
return (rQ[rQi++] << 8) +
(rQ[rQi++] );
}
function rQshift32() {
return (rQ[rQi++] << 24) +
(rQ[rQi++] << 16) +
(rQ[rQi++] << 8) +
(rQ[rQi++] );
}
function rQshiftStr(len) {
if (typeof(len) === 'undefined') { len = rQlen(); }
var arr = rQ.slice(rQi, rQi + len);
rQi += len;
return String.fromCharCode.apply(null, arr);
}
function rQshiftBytes(len) {
if (typeof(len) === 'undefined') { len = rQlen(); }
rQi += len;
return rQ.slice(rQi-len, rQi);
}
function rQslice(start, end) {
if (end) {
return rQ.slice(rQi + start, rQi + end);
} else {
return rQ.slice(rQi + start);
}
}
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
// to be available in the receive queue. Return true if we need to
// wait (and possibly print a debug message), otherwise false.
function rQwait(msg, num, goback) {
var rQlen = rQ.length - rQi; // Skip rQlen() function call
if (rQlen < num) {
if (goback) {
if (rQi < goback) {
throw("rQwait cannot backup " + goback + " bytes");
}
rQi -= goback;
}
//Util.Debug(" waiting for " + (num-rQlen) +
// " " + msg + " byte(s)");
return true; // true means need more data
}
return false;
}
//
// Private utility routines
//
function encode_message() {
if (mode === 'binary') {
// Put in a binary arraybuffer
return (new Uint8Array(sQ)).buffer;
} else {
// base64 encode
return Base64.encode(sQ);
}
}
function decode_message(data) {
//Util.Debug(">> decode_message: " + data);
if (mode === 'binary') {
// push arraybuffer values onto the end
var u8 = new Uint8Array(data);
for (var i = 0; i < u8.length; i++) {
rQ.push(u8[i]);
}
} else {
// base64 decode and concat to the end
rQ = rQ.concat(Base64.decode(data, 0));
}
//Util.Debug(">> decode_message, rQ: " + rQ);
}
//
// Public Send functions
//
function flush() {
if (websocket.bufferedAmount !== 0) {
Util.Debug("bufferedAmount: " + websocket.bufferedAmount);
}
if (websocket.bufferedAmount < api.maxBufferedAmount) {
//Util.Debug("arr: " + arr);
//Util.Debug("sQ: " + sQ);
if (sQ.length > 0) {
websocket.send(encode_message(sQ));
sQ = [];
}
return true;
} else {
Util.Info("Delaying send, bufferedAmount: " +
websocket.bufferedAmount);
return false;
}
}
// overridable for testing
function send(arr) {
//Util.Debug(">> send_array: " + arr);
sQ = sQ.concat(arr);
return flush();
}
function send_string(str) {
//Util.Debug(">> send_string: " + str);
api.send(str.split('').map(
function (chr) { return chr.charCodeAt(0); } ) );
}
//
// Other public functions
function recv_message(e) {
//Util.Debug(">> recv_message: " + e.data.length);
try {
decode_message(e.data);
if (rQlen() > 0) {
eventHandlers.message();
// Compact the receive queue
if (rQ.length > rQmax) {
//Util.Debug("Compacting receive queue");
rQ = rQ.slice(rQi);
rQi = 0;
}
} else {
Util.Debug("Ignoring empty message");
}
} catch (exc) {
if (typeof exc.stack !== 'undefined') {
Util.Warn("recv_message, caught exception: " + exc.stack);
} else if (typeof exc.description !== 'undefined') {
Util.Warn("recv_message, caught exception: " + exc.description);
} else {
Util.Warn("recv_message, caught exception:" + exc);
}
if (typeof exc.name !== 'undefined') {
eventHandlers.error(exc.name + ": " + exc.message);
} else {
eventHandlers.error(exc);
}
}
//Util.Debug("<< recv_message");
}
// Set event handlers
function on(evt, handler) {
eventHandlers[evt] = handler;
}
function init(protocols, ws_schema) {
rQ = [];
rQi = 0;
sQ = [];
websocket = null;
var bt = false,
wsbt = false,
try_binary = false;
// Check for full typed array support
if (('Uint8Array' in window) &&
('set' in Uint8Array.prototype)) {
bt = true;
}
// Check for full binary type support in WebSocket
// Inspired by:
// https://github.com/Modernizr/Modernizr/issues/370
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets/binary.js
try {
if (bt && ('binaryType' in WebSocket.prototype ||
!!(new WebSocket(ws_schema + '://.').binaryType))) {
Util.Info("Detected binaryType support in WebSockets");
wsbt = true;
}
} catch (exc) {
// Just ignore failed test localhost connections
}
// Default protocols if not specified
if (typeof(protocols) === "undefined") {
if (wsbt) {
protocols = ['binary', 'base64'];
} else {
protocols = 'base64';
}
}
// If no binary support, make sure it was not requested
if (!wsbt) {
if (protocols === 'binary') {
throw("WebSocket binary sub-protocol requested but not supported");
}
if (typeof(protocols) === "object") {
var new_protocols = [];
for (var i = 0; i < protocols.length; i++) {
if (protocols[i] === 'binary') {
Util.Error("Skipping unsupported WebSocket binary sub-protocol");
} else {
new_protocols.push(protocols[i]);
}
}
if (new_protocols.length > 0) {
protocols = new_protocols;
} else {
throw("Only WebSocket binary sub-protocol was requested and not supported.");
}
}
}
return protocols;
}
function open(uri, protocols) {
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
protocols = init(protocols, ws_schema);
if (test_mode) {
websocket = {};
} else {
websocket = new WebSocket(uri, protocols);
if (protocols.indexOf('binary') >= 0) {
websocket.binaryType = 'arraybuffer';
}
}
websocket.onmessage = recv_message;
websocket.onopen = function() {
Util.Debug(">> WebSock.onopen");
if (websocket.protocol) {
mode = websocket.protocol;
Util.Info("Server chose sub-protocol: " + websocket.protocol);
} else {
mode = 'base64';
Util.Error("Server select no sub-protocol!: " + websocket.protocol);
}
eventHandlers.open();
Util.Debug("<< WebSock.onopen");
};
websocket.onclose = function(e) {
Util.Debug(">> WebSock.onclose");
eventHandlers.close(e);
Util.Debug("<< WebSock.onclose");
};
websocket.onerror = function(e) {
Util.Debug(">> WebSock.onerror: " + e);
eventHandlers.error(e);
Util.Debug("<< WebSock.onerror");
};
}
function close() {
if (websocket) {
if ((websocket.readyState === WebSocket.OPEN) ||
(websocket.readyState === WebSocket.CONNECTING)) {
Util.Info("Closing WebSocket connection");
websocket.close();
}
websocket.onmessage = function (e) { return; };
}
}
// Override internal functions for testing
// Takes a send function, returns reference to recv function
function testMode(override_send, data_mode) {
test_mode = true;
mode = data_mode;
api.send = override_send;
api.close = function () {};
return recv_message;
}
function constructor() {
// Configuration settings
api.maxBufferedAmount = 200;
// Direct access to send and receive queues
api.get_sQ = get_sQ;
api.get_rQ = get_rQ;
api.get_rQi = get_rQi;
api.set_rQi = set_rQi;
// Routines to read from the receive queue
api.rQlen = rQlen;
api.rQpeek8 = rQpeek8;
api.rQshift8 = rQshift8;
api.rQunshift8 = rQunshift8;
api.rQshift16 = rQshift16;
api.rQshift32 = rQshift32;
api.rQshiftStr = rQshiftStr;
api.rQshiftBytes = rQshiftBytes;
api.rQslice = rQslice;
api.rQwait = rQwait;
api.flush = flush;
api.send = send;
api.send_string = send_string;
api.on = on;
api.init = init;
api.open = open;
api.close = close;
api.testMode = testMode;
return api;
}
return constructor();
}

View File

@ -0,0 +1,216 @@
/*
* from noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
"use strict";
/*jslint bitwise: false, white: false */
/*global Util, window, document */
// Globals defined here
var WebUtil = {}, $D;
/*
* Simple DOM selector by ID
*/
if (!window.$D) {
window.$D = function (id) {
if (document.getElementById) {
return document.getElementById(id);
} else if (document.all) {
return document.all[id];
} else if (document.layers) {
return document.layers[id];
}
return undefined;
};
}
/*
* ------------------------------------------------------
* Namespaced in WebUtil
* ------------------------------------------------------
*/
// init log level reading the logging HTTP param
WebUtil.init_logging = function(level) {
if (typeof level !== "undefined") {
Util._log_level = level;
} else {
Util._log_level = (document.location.href.match(
/logging=([A-Za-z0-9\._\-]*)/) ||
['', Util._log_level])[1];
}
Util.init_logging();
};
WebUtil.dirObj = function (obj, depth, parent) {
var i, msg = "", val = "";
if (! depth) { depth=2; }
if (! parent) { parent= ""; }
// Print the properties of the passed-in object
for (i in obj) {
if ((depth > 1) && (typeof obj[i] === "object")) {
// Recurse attributes that are objects
msg += WebUtil.dirObj(obj[i], depth-1, parent + "." + i);
} else {
//val = new String(obj[i]).replace("\n", " ");
if (typeof(obj[i]) === "undefined") {
val = "undefined";
} else {
val = obj[i].toString().replace("\n", " ");
}
if (val.length > 30) {
val = val.substr(0,30) + "...";
}
msg += parent + "." + i + ": " + val + "\n";
}
}
return msg;
};
// Read a query string variable
WebUtil.getQueryVar = function(name, defVal) {
var re = new RegExp('[?][^#]*' + name + '=([^&#]*)'),
match = document.location.href.match(re);
if (typeof defVal === 'undefined') { defVal = null; }
if (match) {
return decodeURIComponent(match[1]);
} else {
return defVal;
}
};
/*
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
*/
// No days means only for this browser session
WebUtil.createCookie = function(name,value,days) {
var date, expires;
if (days) {
date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires="+date.toGMTString();
}
else {
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
};
WebUtil.readCookie = function(name, defaultValue) {
var i, c, nameEQ = name + "=", ca = document.cookie.split(';');
for(i=0; i < ca.length; i += 1) {
c = ca[i];
while (c.charAt(0) === ' ') { c = c.substring(1,c.length); }
if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length,c.length); }
}
return (typeof defaultValue !== 'undefined') ? defaultValue : null;
};
WebUtil.eraseCookie = function(name) {
WebUtil.createCookie(name,"",-1);
};
/*
* Setting handling.
*/
WebUtil.initSettings = function(callback) {
var callbackArgs = Array.prototype.slice.call(arguments, 1);
if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.get(function (cfg) {
WebUtil.settings = cfg;
console.log(WebUtil.settings);
if (callback) {
callback.apply(this, callbackArgs);
}
});
} else {
// No-op
if (callback) {
callback.apply(this, callbackArgs);
}
}
};
// No days means only for this browser session
WebUtil.writeSetting = function(name, value) {
if (window.chrome && window.chrome.storage) {
//console.log("writeSetting:", name, value);
if (WebUtil.settings[name] !== value) {
WebUtil.settings[name] = value;
window.chrome.storage.sync.set(WebUtil.settings);
}
} else {
localStorage.setItem(name, value);
}
};
WebUtil.readSetting = function(name, defaultValue) {
var value;
if (window.chrome && window.chrome.storage) {
value = WebUtil.settings[name];
} else {
value = localStorage.getItem(name);
}
if (typeof value === "undefined") {
value = null;
}
if (value === null && typeof defaultValue !== undefined) {
return defaultValue;
} else {
return value;
}
};
WebUtil.eraseSetting = function(name) {
if (window.chrome && window.chrome.storage) {
window.chrome.storage.sync.remove(name);
delete WebUtil.settings[name];
} else {
localStorage.removeItem(name);
}
};
/*
* Alternate stylesheet selection
*/
WebUtil.getStylesheets = function() { var i, links, sheets = [];
links = document.getElementsByTagName("link");
for (i = 0; i < links.length; i += 1) {
if (links[i].title &&
links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) {
sheets.push(links[i]);
}
}
return sheets;
};
// No sheet means try and use value from cookie, null sheet used to
// clear all alternates.
WebUtil.selectStylesheet = function(sheet) {
var i, link, sheets = WebUtil.getStylesheets();
if (typeof sheet === 'undefined') {
sheet = 'default';
}
for (i=0; i < sheets.length; i += 1) {
link = sheets[i];
if (link.title === sheet) {
Util.Debug("Using stylesheet " + sheet);
link.disabled = false;
} else {
//Util.Debug("Skipping stylesheet " + link.title);
link.disabled = true;
}
}
return sheet;
};

View File

@ -0,0 +1,203 @@
function Telnet(target, connect_callback, disconnect_callback) {
var that = {}, // Public API interface
vd, ws, sQ = [];
termType = "Viewdata";
Array.prototype.pushStr = function (str) {
var n = str.length;
for (var i=0; i < n; i++) {
this.push(str.charCodeAt(i));
}
}
function do_send() {
if (sQ.length > 0) {
ws.send(sQ);
sQ = [];
}
}
function do_recv() {
vd.write(ws.rQshiftStr(ws.rQlen()));
}
that.connect = function(host, port, encrypt, url) {
var host = host,
port = port,
scheme = "ws://", uri;
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (ws) {
ws.close();
}
if (encrypt) {
scheme = "wss://";
}
uri = scheme + host + ":" + port + url;
ws.open(uri);
}
that.disconnect = function() {
if (ws) {
ws.close();
}
vd.curs_set(true, false);
disconnect_callback();
}
function constructor() {
/* Initialize Websock object */
ws = new Websock();
ws.on('message', do_recv);
ws.on('open', function(e) {
vd.curs_set(true, true);
connect_callback();
});
ws.on('close', function(e) {
that.disconnect();
});
ws.on('error', function(e) {
that.disconnect();
});
/* Initialize the terminal emulator/renderer */
vd = new VD(40, 24, target);
/*
* Override VD I/O routines
*/
// Set handler for sending characters
vd.getch(
function send_chr(chr, vt) {
var i;
for (i = 0; i < chr.length; i++) {
sQ.push(chr.charCodeAt(i));
}
do_send();
vd.getch(send_chr);
}
);
vd.curs_set = function(vis, grab, eventist)
{
if (vis !== undefined)
this.cursor_vis_ = (vis > 0);
if (eventist === undefined)
eventist = window;
if (grab === true || grab === false) {
if (grab === this.grab_events_)
return;
if (grab) {
this.grab_events_ = true;
VD.the_vt_ = this;
Util.addEvent(eventist, 'keydown', vd.key_down);
Util.addEvent(eventist, 'keyup', vd.key_up);
} else {
Util.removeEvent(eventist, 'keydown', vd.key_down);
Util.removeEvent(eventist, 'keyup', vd.key_up);
this.grab_events_ = false;
VD.the_vt_ = undefined;
}
}
}
vd.key_down = function(e) {
var vt = VD.the_vt_, keysym, ch, str = "";
if (vt === undefined)
return true;
keysym = getKeysym(e);
if (keysym < 128) {
if (e.ctrlKey) {
if (keysym == 64) {
// control 0
ch = 0;
} else if ((keysym >= 97) && (keysym <= 122)) {
// control codes 1-26
ch = keysym - 96;
} else if ((keysym >= 91) && (keysym <= 95)) {
// control codes 27-31
ch = keysym - 64;
}
} else {
ch = keysym;
switch (ch) {
case 34:
ch = 126; break;
case 126:
ch = 0x40; break;
case 64:
ch = 0x22; break;
case 39:
ch = 0x5f; break;
case 95:
ch = 0x23; break;
case 96:
ch = 0x27; break;
}
}
str = String.fromCharCode(ch);
} else {
switch (keysym) {
case 65505: // Shift, do not send directly
break;
case 65507: // Ctrl, do not send directly
break;
case 65293: // Carriage return, line feed
str = '_'; break;
case 65288: // Backspace
str = '\b'; break;
case 65307: // Escape
str = '\x1b'; break;
case 65361: // Left arrow
str = '\x08'; break;
case 65362: // Up arrow
str = '\x0b'; break;
case 65363: // Right arrow
str = '\x09'; break;
case 65364: // Down arrow
str = '\x0a'; break;
}
}
if (str) {
vt.key_buf_.push(str);
setTimeout(VD.go_getch_, 0);
}
Util.stopEvent(e);
return false;
}
vd.key_up = function(e) {
var vt = VD.the_vt_;
if (vt === undefined)
return true;
Util.stopEvent(e);
return false;
}
return that;
}
return constructor(); // Return the public API interface
}

BIN
source/images/oztex.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long