Updated viewdata client to work with synchronet websocket, removed redundant code

This commit is contained in:
Deon George 2023-05-31 22:53:15 +10:00
parent a12bf01e9a
commit bd20fd715b
11 changed files with 910 additions and 1471 deletions

View File

@ -32,7 +32,7 @@ Just press the *Connect* button below, and create an account. The first time you
Options.ProxyPortSecure = 443;
Options.ScreenColumns = 80;
Options.ScreenRows = 25;
Options.WebSocketUrlPath = '/?Port=123';
Options.WebSocketUrlPath = '/?Port=123&Host=alterant';
Options.SplashScreen = 'G1swbRtbMzBt2xtbMTszN23aIL/Cv7Pav9q/2sK/wr8bWzBtIBtbMW3DLdq/G1swbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgsyAgICAgICDc3Nzc3Nzc3Nzc3Nzc3Nzc3NwNChtbMzBt2xtbMzdts7Ozw9mzsyCzs7Mgs8PZG1szMG3bG1szN22zILOzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICCzICAgICAgIN6z8PDw8PDw8PDw8PDw8PDwsw0KG1szMG3bG1sxbcDB2cHZwMDZwNnAINnB2RtbMG0gG1sxOzMwbcDZwNkbWzBtIBtbMTszMG36+vobWzBtICAgICAgICAgICAgICAgICAgICAgICAgICAgILMgICAgICAg3rMgICAgICAgIBtbMW3c3BtbMG0gICAbWzFtLhtbMG0gsw0KG1sxOzMwbSAgG1szN23c3MS/3NzaxNzcxL/c3MS/3NzEv9zcxL/c3MS/2sTc3MS/G1swbSAgICAgICAgICAgICAgICAgsyAgICAgICDesyAgIC4gICAbWzFt29vb2xtbMG0gICAgsw0KG1sxbSAgG1s0N22yG1szMG2wG1s0MG0gG1szN22zG1s0N22yG1szMG2wG1s0MG0gIBtbMzc7NDdtshtbMzBtsBtbNDBtICAbWzM3OzQ3bbIbWzMwbbAbWzQwbSAgG1szNzs0N22yG1szMG2wG1s0MG0gG1szN22zG1s0N22yG1szMG2wG1s0MG0gG1szN22zG1s0N22yG1szMG2wG1s0MG0gG1szN22zICAbWzQ3bbIbWzMwbbAbWzQwbSAgICAgICAgICAgICAgICAgICAbWzBtsyAgICAgICDesyAbWzFtLhtbMG0gICAgICAbWzFt398bWzBtICAgLiCzDQobWzE7MzBtICAbWzM3OzQ3bbEbWzMwbbAbWzM3OzQwbcS0G1s0N22xG1szMG2wG1s0MG0gIBtbMzc7NDdtsRtbMzBtsBtbNDBtICAbWzM3OzQ3bbEbWzMwbbAbWzM3OzQwbcQgG1s0N22xG1szMG2wG1szNzs0MG3E2RtbNDdtsRtbMzBtsBtbMzc7NDBtxLQbWzQ3bbEbWzMwbbAbWzQwbSAbWzM3bbMgIBtbNDdtsRtbMzBtsBtbNDBtICAgICAgICAgICAgICAgICAgIBtbMG2zICAgICAgIN6zICAgLiAgIBtbMW0uG1swbSAgIBtbMW0uG1swbSAgILMNChtbMTszMG0gIBtbMzc7NDdtsBtbMzBtsBtbNDBtIBtbMzdtsxtbNDdtsBtbMzBtsBtbNDBtIBtbMzdtsxtbNDdtsBtbMzBtsBtbNDBtICAbWzM3OzQ3bbAbWzMwbbAbWzQwbSAbWzM3bbMbWzQ3bbAbWzMwbbAbWzM3OzQwbcC/G1s0N22wG1szMG2wG1s0MG0gG1szN22zG1s0N22wG1szMG2wG1s0MG0gG1szN22zICAbWzQ3bbAbWzMwbbAbWzQwbSAgICAgICAgICAgICAgIBtbMzZt3NwbWzMyOzQ2bdwbWzM2bdzc3BtbMzJt3BtbMzY7NDBt3NwbWzBtICAg3rMgG1sxbS4bWzBtICAgIBtbMW0uG1swbSAgIBtbMW0uG1swbSAgICCzDQogICAgICDExMTZIBtbMTszMG0uG1swbSAgxMTE2SAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1szNm3f398bWzMybd8bWzM2bd8bWzE7Mzc7NDZt3NzcG1swOzM2bd8bWzMybd8bWzM2bd/f3xtbMzdtIN6zICAgG1sxbS4bWzBtICAgICAgLiAbWzFtLhtbMG0gILMNCiAgIBtbMTszMG3Cv7/a2r/av7/av8K/ICAgICAgG1swbdrEG1sxbdwg3L8g3L8g2sTcICAgICAgICAgICAgICAgICAgICAgICAgICAbWzBt3rMgICAgICAgLiAgICAgICCzDQogICAbWzE7MzBt2SDB2dnZ2dnZ2dnBtPr6+htbMG0gICDAxNwg28C/28C/wMTcICAgICAgICAgICAgICAgICAgICAgICAgICDfwMTE3BtbMW3cG1swbdzExMTExMTExMTE2Q0KICAgICAgICAgICAgICAbWzE7MzBtxNkgICAgICAbWzBt38QbWzE7MzBt3yDfG1szN23E2RtbMzBt3xtbMzdtxNnfxBtbMzBt3yAgICAgICAgICAbWzA7MzNt3LKy29uy29wbWzM3bSAgICAgICAgICAgG1sxOzM2bd4bWzMwOzQ3bbMbWzM3bd0bWzMwbbPdG1szN23b398bWzBt3NwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1szM23estuyG1sxOzMxOzQzbdwbWzQwbdsbWzQ3bSAbWzA7MzA7NDdt/htbMzc7NDBtICAgICAgICAgICAgG1sxOzM2bdsbWzMwOzQ3bbMbWzM3bd0bWzMwbbPdG1szN23dICAgICAbWzBt29wNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1szM23estsbWzE7MzE7NDNt3BtbNDBtstvb298bWzBtICAgICAgICAgICAbWzE7MzZt2xtbMzA7NDdtsxtbMG3bG1sxOzMwOzQ3bbPdG1szN23dICAbWzA7MzA7NDdt8PAbWzM3OzQwbduysg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1szM23fG1sxOzMxOzQzbdwbWzQwbbKy29vcG1swbSAgICAgICAgICAgIBtbMTszNm3bG1szMDs0N22zG1swbdsbWzE7MzA7NDdts90gIBtbMG3b27IbWzE7MzA7NDdt3BtbMG0NCiAgICAbWzE7MzZtVEVMTkVUOhtbMG0gG1sxbWFsdGVyYW50LmJicy5kZWdlLmF1G1swbSAgICAgICAgICAgICAgG1sxbdwbWzMxOzQ3bd/f3xtbMG0gICAgICAgICAgICAgIBtbMTszNm3eG1szMDs0N22zG1swbdsbWzE7MzA7NDdts90bWzBtshtbMTszMDs0N23c3BtbNDBtsrKy3xtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTszMG3cG1szNzs0N22yG1s0MG3bG1s0N23fG1s0MG3b29wgICAgG1swOzMwbdsbWzE7MzFt3BtbMDszMG3bG1sxOzMxbdzcG1swOzMwbdsgICAbWzM3bd/fG1sxOzMwOzQ3bdwbWzQwbdyysrKy3NwbWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzE7MzBt3BtbMzdt3BtbMzBtsrIbWzM3bdvbG1s0N23c3xtbMzFt3BtbNDBtsrLc3Nzb29/cG1swOzMwbdvb2yAbWzFtLRtbMG3bG1sxOzMwOzQ3bd0gICAgICAgG1swbbIbWzMxOzQ3bdwbWzM3OzQwbbINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFt3htbMzBt37IbWzM3OzQ3bbEbWzQwbdsbWzQ3bbGyG1s0MG3bIBtbMzFt39/f3yAbWzM3bdwbWzQ3bdzc3Nzc3BtbNDBt3BtbNDdt3Nzc3Nzc3Nzc3NzcG1s0MG3c3BtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzFt3iAg39sbWzQ0bd8bWzM0bbAgsbCwG1swOzM0bdvcICAgG1sxOzM3OzQ3bdsbWzBtICAgICAgICAgICAgICAgIBtbMTs0N23bG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIN4bWzFt3BtbMzA7NDdt39/f39/fG1s0MG3f3xtbMzQ7NDRtsbAgG1s0MG0gICAbWzM3OzQ3bd0bWzBtICAgICAgICAgICAgICAgIBtbMTs0N23dG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMW3bICAgG1szNDs0NG2wILEbWzQwbSAgIBtbMzc7NDdt3RtbMG0gICAgICAgICAgICAgICAgG1sxOzQ3bd0bWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ3bd0bWzQwbSAgIBtbMDszNDs0N23bG1sxOzMwOzQ0bdwbWzA7MzRt3yAgIBtbMTszNzs0N23dG1swbSAgICAgICAgICAgICAgICAbWzE7NDdt3RtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzMwbdwbWzM3bd8bWzBt3xtbMTszMDs0N23cG1swbd8bWzFt3xtbMzA7NDdt3BtbMzc7NDBt398bWzMwbdvbG1s0N23fG1s0MG3b29wbWzBt2xtbMW3c3NzcG1swbdzc3NzcG1sxbdwbWzBt3BtbMW3cG1swbdzcG1sxbdzcG1s0N23dG1swbQ0K';
var fTelnet = new fTelnetClient('fTelnetContainer', Options);
</script>

View File

@ -27,7 +27,7 @@ If you are interested in taking a look at what I have so far, just press the *Co
Options.Enter = '#';
Options.Font = 'CP437';
Options.ForceWss = false;
Options.Hostname = 'alterant.bbs.dege.au';
Options.Hostname = 'ansitex.bbs.dege.au';
Options.Port = (WSS ? 11235 : 1123);
Options.LocalEcho = false;
Options.ProxyHostname = '';
@ -35,7 +35,7 @@ If you are interested in taking a look at what I have so far, just press the *Co
Options.ProxyPortSecure = 443;
Options.ScreenColumns = 80;
Options.ScreenRows = 25;
Options.WebSocketUrlPath = '/?Port=23';
Options.WebSocketUrlPath = '/?Port=23&Host=ansitex';
Options.SplashScreen = 'G1swOzQwOzM3bSAbWzFt2sTEvyAg2sS/INrExMTExMTEvyDaxMTEvxtbMG0bWzVDG1sxbdrExMTExMTEvyDaxMTExMTExL8g2sTExMTExMS/INrExMTExMTEvw0KG1swOzMxbc0bWzE7MzdtsxtbMzBt+RtbMzdtILMbWzMxbc3NG1szN22zG1szMG35G1szN22zG1szMW3NG1szN22zG1szMG35G1szN20gINXNuBtbMzBt+RtbMzdtsxtbMzFtzRtbMzdtsxtbMzBt+RtbMzdtICCzG1szMW3Nzc3NzRtbMzdtsxtbMzBt+RtbMzdtICDVzbgbWzMwbfkbWzM3bbMbWzMxbc0bWzM3bbMbWzMwbfkbWzM3bSAg1c24G1szMG35G1szN22zG1szMW3NG1szN22zG1szMG35G1szN20g1bjVuBtbMzFt+htbMzdtsxtbMzFtzRtbMzdtsxtbMzBt+RtbMzdtICDVzbgbWzMwbfkbWzM3bbMbWzA7MzFtzQ0KG1sxOzQxbbAbWzQwOzM3bbMgILMbWzMxbbIbWzQxbdsbWzQwOzM3bbMgsxtbNDFtIBtbNDBtsyAgIMC/wMTZG1s0MTszMW2wG1s0MDszN22zICAgsxtbNDE7MzFt2xtbNDBtsrKyG1s0MTszN20gG1s0MG2zICAgsxtbMzFtshtbMzdtwMTZG1s0MTszMW2wG1s0MDszN22zICAgsxtbNDE7MzFt2xtbNDA7MzdtsyCzG1s0MW0gG1s0MG2zICCz1L6zILMbWzQxbSAbWzQwbbMgICDAv8DE2RtbNDE7MzFtsBtbMG0NChtbMTs0MTszMW2xG1s0MDszN22zICCz1bizILMbWzQxOzMxbbAbWzQwOzM3bbMgICDa2drEvxtbNDE7MzFtsRtbNDA7MzdtsyAgILMbWzQxOzMxbbIbWzQwOzM3bdrEvxtbNDE7MzFtsBtbNDA7MzdtsyAgILMbWzMxbbAbWzM3bdrEvxtbNDE7MzFtsRtbNDA7MzdtsyAgILMbWzQxOzMxbbIbWzQwOzM3bbMgsxtbNDE7MzFtsBtbNDA7MzdtsyAgsxtbMzFtsrEbWzM3bbMgsxtbNDE7MzFtsBtbNDA7MzdtsyAgINrZ2sS/G1s0MTszMW2xG1swbQ0KG1sxOzQxOzMxbbIbWzQwOzM3bbMgIMDZwNkgsxtbNDE7MzFtsRtbNDA7MzdtsyAgILMbWzQxOzMxbbAbWzQwOzM3bbMgsxtbNDE7MzFtshtbNDA7MzdtsyAgIMDE2SCzG1s0MTszMW2xG1s0MDszN22zICAgsxtbNDE7MzFtsBtbNDA7MzdtsyCzG1s0MTszMW2yG1s0MDszN22zICAgwMTZILMbWzQxOzMxbbEbWzQwOzM3bbMgILMbWzMxbbEbWzQxbbAbWzQwOzM3bbMgsxtbNDE7MzFtsRtbNDA7MzdtsyAgILMbWzQxOzMxbbAbWzQwOzM3bbMgsxtbNDE7MzFtshtbMG0NChtbMzFtzRtbMTszN22zG1szMG35G1swbRtbNUMbWzE7MzBt+RtbMzdtsxtbMzFtzRtbMzdtsxtbMzBt+RtbMzdtICDUzb4bWzMwbfkbWzM3bbMbWzMxbc0bWzM3bbMbWzMwbfkbWzBtG1s1QxtbMTszMG35G1szN22zG1szMW3NG1szN22zG1szMG35G1szN20gINTNvhtbMzBt+RtbMzdtsxtbMzFtzRtbMzdtsxtbMzBt+RtbMG0bWzVDG1sxOzMwbfkbWzM3bbMbWzMxbc0bWzM3bbMbWzMwbfkbWzM3bSCzG1szMW3NzRtbMzdtsxtbMzBt+RtbMzdtsxtbMzFtzRtbMzdtsxtbMzBt+RtbMzdtICDUzb4bWzMwbfkbWzM3bbMbWzA7MzFtzQ0KG1szN20gG1sxbdTNzc3Nzc3NviDUzc3Nzc3Nzb4g1M3Nzc3Nzc2+INTNzc3Nzc3NviDUzc3Nzc3Nzb4g1M3NviAg1M2+INTNzc3Nzc3Nvg0KG1s0MW0gIEEgdkJCUyBieSAuLi4uZGVvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMG0NCiAbWzFtWW91IGhhdmUgY29ubmVjdGVkIHRvIBtbMDszMW1WQkJTG1sxOzM3bS4NCg0KIFRoaXMgaXMgYSBwdWJsaWMgYWNjZXNzG1swOzM0bSBBTlNJdGV4G1sxOzM3bSBCQlMuDQoNChtbMG0gG1sxbVdoaWxlIHRoaXMgc3lzdGVtIGlzIGN1cnJlbnRseSB1bmRlciBkZXZlbG9wbWVudCwgeW91IGFyZSB3ZWxjb21lIHRvIHVzZSBpdA0KG1swbSAbWzFtYW5kIG1ha2UgcmVjb21tZW5kYXRpb25zLg0KDQobWzBtIBtbMW1JZiB5b3Ugd291bGQgbGlrZSB0byBob3N0IHlvdXIgb3duIHBhZ2VzIG9uIHRoaXMgc3lzdGVtLCBwbGVhc2UgbGV0IBtbMDszMW1kZW9uDQobWzM3bSAbWzFta25vdy4NCg0KG1swOzMxbSBVc2VyOiAbWzE7MzdtLi4uLi4uLi4uLi4uG1swbSAgIFtOZXcgQWNjb3VudHMgdXNlG1sxbSAbWzMzbU5FVyMbWzBtXQ0KG1szMW0gUGFzczogG1sxOzM3bS4uLi4uLi4uLi4uLhtbPzI1bA0K';
var fTelnet = new fTelnetClient('fTelnetContainer', Options);
</script>

View File

@ -26,12 +26,10 @@ If you have a Viewdata/Videotex emulation software, you can connect directly to
<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;"></div></td></tr></tbody></table>
<script src="/js/viewdata/base64.js"></script>
<script src="/js/viewdata/util.js"></script>
<script src="/js/viewdata/websock.js"></script>
<script src="/js/viewdata/webutil.js"></script>
<script src="/js/viewdata/keysym.js"></script>
<script src="/js/viewdata/log.js"></script>
<script src="/js/viewdata/vdata.js"></script>
<script src="/js/viewdata/websock.js"></script>
<script src="/js/viewdata/wsvdata.js"></script>
<script src="/libs/zoomooz/js/jquery.zoomooz.min.js"></script>
<script>
@ -65,12 +63,11 @@ var telnet;
}
window.onload = function() {
console.log("onload");
var url = document.location.href;
$D('host').value = 'alterant.bbs.dege.au';
$D('port').value = '443';
$D('encrypt').checked = true;
$D('url').value = '/ws/videotex/516';
$D('host').value = 'ansitex.bbs.dege.au';
$D('port').value = (location.protocol.toLowerCase() == 'https:') ? 11235 : 1123;
$D('encrypt').checked = (location.protocol.toLowerCase() == 'https:');
$D('url').value = '?Port=516&Host=ansitex';
telnet = Telnet('terminal', connected, disconnected,
'#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECAis2Evmwp8WE1hdvr_o2bfWjaoECBAgQIECBAgQIECBAgQICP_WS_6ii_4T_l2ujegePUixqgQIECBAgQIECBAgQIECBAgIr1xJeqKLF5NeX68PXDj19cGqBAgQIECBAgQIECBAgQIECBBW05Mu_pl8IECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIEFfLsx79uVYg87-qDRh7ZUGPfu3ZcfTLkQdN6BAgQIECBAgAwQU4HTCSQ_TL4QYUEKFTQdNGHog080GLDzy5EG_cg6aMqBAxcuGCfmgracmXf0y-EHPLy7aceVcgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQRMvDLuyad2dBv3IO-jTj0IMe_ru6cvKDzv6oNmntlQadyBB00ZUFbTky7-mXwg55eXbTjyoO-Hmgx4dmzLkQVtOHpl2IECiDVUrEFDll59MuxAoqy1KxBN07tPTLsQKI1JSsQIECBAgQVMuzTk37kCiHBUrEEnFl5dMvhAop0FKxBl6Y0CBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIEFTegx7927Lj6IOm9B00ZUHPzz6ZdqxBl09NGXkg4csvPmgQQ586dFh1FiDfyQdeeVB539eSDtpy98mHphQdMvLbp3YdiBBj37t2XH0QdN4LDu56emXwuxYua7Jlz5V2Hq6asWyBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=Tm0');

View File

@ -77,14 +77,12 @@ a.red:active, .red a:active {
*/
/* 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 */
/*

View File

@ -1,114 +0,0 @@
/* 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,64 @@
/*
* 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 Log = {};
/*
* ------------------------------------------------------
* Namespaced in Util
* ------------------------------------------------------
*/
/*
* Logging/debug routines
*/
Log._log_level = 'none';
Log.init_logging = function (level) {
if (typeof level === 'undefined') {
level = Log._log_level;
} else {
Log._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) {}};
}
}
Log.Debug = Log.Info = Log.Warn = Log.Error = function (msg) {};
switch (level) {
case 'debug': Log.Debug = function (msg) { console.log(msg); };
case 'info': Log.Info = function (msg) { console.log(msg); };
case 'warn': Log.Warn = function (msg) { console.warn(msg); };
case 'error': Log.Error = function (msg) { console.error(msg); };
case 'none':
break;
default:
throw("invalid logging type '" + level + "'");
}
};
Log.get_logging = function () {
return Log._log_level;
};
// Initialize logging level
Log.init_logging();

View File

@ -1,379 +0,0 @@
/*
* 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

@ -6,12 +6,14 @@ function VD(wd, ht, scr_id, initscr)
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) {
for (r=0; r<ht; ++r) {
this.text_[r] = new Array(wd);
}
this.scr_ = scr;
this.cursor_vis_ = true;
this.reveal_ = 0;
@ -21,8 +23,9 @@ function VD(wd, ht, scr_id, initscr)
this.esc_state_ = 0;
this.col_ = 0;
this.row_ = 0;
// Internal debug setting.
if (typeof initscr !== "undefined") {
// Initial Screen
if (typeof initscr !== 'undefined') {
this.write("\x0c" + this.txthash(initscr) + "\x14\x1e");
} else {
this.write("\x0c\x11\x1e");
@ -32,28 +35,11 @@ function VD(wd, ht, scr_id, initscr)
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;
// var blinks = document.getElementsById('blink');
// var visibility = 'hidden';
// window.setInterval(function() {
// for (var i = blinks.length - 1; i >= 0; i--) {
// blinks[i].style.visibility = visibility;
// }
// visibility = (visibility === 'visible') ? 'hidden' : 'visible';
// }, 250);
// object methods
VD.prototype.html_colours_ = function(at_fg, at_bg, at_mode)
{
VD.prototype.html_colours_ = function(at_fg, at_bg, at_mode) {
var co0, co1;
if (at_mode & VD.A_REVERSE) {
co0 = 'ff';
@ -73,110 +59,111 @@ VD.prototype.html_colours_ = function(at_fg, at_bg, at_mode)
};
}
VD.prototype.txthash = function(hashstring) {
var currentcode = 0, stuff = '';
VD.prototype.txthash = function(hashstring)
{
var currentcode = 0, stuff = "";
if ( hashstring.indexOf(":") > -1 )
var hashstring = hashstring.split(":")[1];
if (hashstring.indexOf(':') > -1)
var hashstring = hashstring.split(':')[1];
hashstring = hashstring.substring(0, 1120);
hashstring = hashstring.substring(0,this.wd_*this.ht_);
for ( var p = 0; p < hashstring.length; p++ ) {
var pc = hashstring.charAt(p);
var pc_dec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
.indexOf(hashstring.charAt(p));
for (var p=0; p<hashstring.length; p++) {
var pc = hashstring.charAt(p);
var pc_dec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
.indexOf(hashstring.charAt(p));
// b is the bit in the 6-bit base-64 character.
for ( var b = 0; b < 6; b++ ) {
// The current bit posiiton in the character being
// written to.
var charbit = ( 6*p + b ) % 7;
// b is the bit in the 6-bit base-64 character.
for (var b=0; b<6; b++) {
// The current bit position in the character being
// written to.
var charbit = (6*p+b) % 7;
// The bit value (set or unset) of the bit we're
// reading from.
var b64bit = pc_dec & ( 1 << ( 5 - b ) );
if ( b64bit > 0 ) { b64bit = 1; }
// The bit value (set or unset) of the bit we're
// reading from.
var b64bit = pc_dec & (1 << (5-b));
if ( b64bit > 0 ) {
b64bit = 1;
}
// Update the current code.
currentcode |= b64bit << ( 6 - charbit );
// Update the current code.
currentcode |= b64bit << (6-charbit);
// If we've reached the end of this character cell
// and it's the last bit in the character we're
// writing to, set the character code or place the
// code.
if ( charbit == 6 ) {
if (currentcode < 32) {
stuff += '\x1b';
currentcode += 64;
}
stuff += String.fromCharCode(currentcode);
currentcode = 0;
// If we've reached the end of this character cell
// and it's the last bit in the character we're
// writing to, set the character code or place the
// code.
if (charbit === 6) {
if (currentcode < 32) {
stuff += '\x1b';
currentcode += 64;
}
stuff += String.fromCharCode(currentcode);
currentcode = 0;
}
}
}
return stuff;
}
VD.prototype.clear = function()
{
VD.prototype.clear = function() {
this.row_ = this.col_ = 0;
for (r = 0; r < this.ht_; ++r) {
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)
{
VD.prototype.curs_set = function(vis) {
if (vis !== undefined)
this.cursor_vis_ = (vis > 0);
}
VD.prototype.getch = function(isr)
{
// this.refresh();
VD.prototype.getch = function(isr) {
this.getch_isr_ = isr;
setTimeout(VD.go_getch_, 0);
}
VD.go_getch_ = function VD_go_getch()
{
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);
isr(ch,vt);
}
VD.prototype.move = function(r, c)
{
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()
{
VD.prototype.refresh = function() {
var r, c, stuff = "", start_tag = "", end_tag = "", ch, chtype,
pair, cr, cc, ht, wd, cv, n_fg, n_bg, n_mode, n_type, a_fg=-1, a_bg=-1, a_mode=-1, n_dblnextline=-2, n_heldchar, n_heldtype;
ht = this.ht_;
@ -184,21 +171,25 @@ VD.prototype.refresh = function()
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;
n_heldchar = 32;
n_heldtype = 0;
if (n_dblnextline+1 < r)
n_dblnextline = -2;
for (c = 0; c < wd; ++c) {
if (cv && r == cr && c == cc) {
// Draw the cursor here.
@ -218,6 +209,7 @@ VD.prototype.refresh = function()
// set-at
if (ctrlch == 0x89) // steady
n_mode &= ~VD.A_BLINK;
if (ctrlch == 0x8c) { // normal
if (n_type & 8) {
n_heldchar = 32;
@ -225,19 +217,24 @@ VD.prototype.refresh = function()
}
n_type &= ~8;
}
if (ctrlch == 0x98 && this.reveal_ == false) // conceal
n_type |= 16;
if (ctrlch == 0x99) // contig
n_type &= ~1;
if (ctrlch == 0x9a) // sep
n_type |= 1;
if (ctrlch == 0x9c) // black
n_bg = 0;
if (ctrlch == 0x9d) // newback
n_bg = n_fg;
if (ctrlch == 0x9e) // hold
n_type |= 32;
//
// If the attributes changed, make a new span.
if (n_mode != a_mode || n_fg != a_fg || n_bg != a_bg) {
@ -246,7 +243,7 @@ VD.prototype.refresh = function()
stuff += '<span style="color:' + pair.f + ';background-color:' + pair.b + ";" +'">'
end_tag = "</span>";
if (n_mode & VD.A_BLINK) {
stuff += '<span class="blink";>';
stuff += '<span class="flashing";>';
end_tag += "</span>";
}
a_fg = n_fg;
@ -260,11 +257,11 @@ VD.prototype.refresh = function()
if (n_type & 32) {
ch = n_heldchar;
chtype = n_heldtype;
} else {
} else {
ch = 32;
}
}
if (ch == 127) {
if (n_type & 2) {
ch = 0xe23f+((chtype & 1)*0xc0);
@ -283,12 +280,12 @@ VD.prototype.refresh = function()
ch = ch+0xe1c0+((chtype & 1)*0xc0);
}
}
if (n_type & 16)
ch = 32;
n_heldtype = chtype;
switch (ch) {
case 32:
ch = 0xa0; break;
@ -305,17 +302,18 @@ VD.prototype.refresh = function()
case 0x23: // #
ch = 0xa3; break
}
if (n_type & 8) {
if (ch < 0x100) {
ch = ch+0xe000+((r==n_dblnextline+1)*0x100);
} else {
ch = ch+0x40+((r==n_dblnextline+1)*0x40)
}
} else if (r==n_dblnextline+1) {
ch = 0xa0;
}
stuff += "&#x" + ch.toString(16) + ";"
// set-after
@ -328,6 +326,7 @@ VD.prototype.refresh = function()
n_type &= ~2;
n_type &= ~16;
}
if (ctrlch >= 145 && ctrlch <= 151) {
if (n_type & 2 == 0) {
n_heldchar=32;
@ -337,8 +336,10 @@ VD.prototype.refresh = function()
n_type |= 2;
n_type &= ~16;
}
if (ctrlch == 0x88) // flash
n_mode |= VD.A_BLINK;
if (ctrlch == 0x8d) { // double
if (n_type & 8 == 0) {
n_heldchar = 32;
@ -348,90 +349,46 @@ VD.prototype.refresh = function()
if (n_dblnextline < 0)
n_dblnextline = r;
}
if (ctrlch == 0x9f) // release
n_type &= ~32;
//
}
}
stuff += end_tag
this.scr_.innerHTML = "<b>" + stuff + "</b>\n";
}
VD.prototype.write = function(stuff)
{
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;
case 8:
if (this.col_ != 0) {
--this.col_;
} else {
--this.row_;
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);
this.reveal_ = false;
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) {
break;
case 9:
if (this.col_ >= this.wd_) {
this.col_ = 0;
if (this.row_ >= this.ht_-1) {
if (this.row_ == this.ht_-1) {
this.row_ = 0;
} else {
++this.row_;
@ -439,8 +396,68 @@ VD.prototype.write = function(stuff)
} 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);
this.reveal_ = false;
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

@ -1,6 +1,7 @@
/*
* Websock: high-performance binary WebSockets
* Copyright (C) 2012 Joel Martin
* Modified 2023 Deon George
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* Websock is similar to the standard WebSocket object but Websock
@ -14,411 +15,419 @@
* 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";
'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
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() {}
},
eventHandlers = {
'message' : function() {},
'open' : function() {},
'close' : function() {},
'error' : function() {}
},
test_mode = false;
test_mode = false;
// Queue public functions
function get_sQ() {
return sQ;
}
function get_rQ() {
return rQ;
}
//
// 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();
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;
}
//Log.Debug(" waiting for " + (num-rQlen) +
// " " + msg + " byte(s)");
return true; // true means need more data
}
return false;
}
// Private utility routines
function encode_message() {
Log.Debug(">> encode_message")
if (mode === 'binary') {
// Put in a binary arraybuffer
return (new Uint8Array(sQ)).buffer;
} else if (mode === 'plain') {
return String.fromCharCode.apply(null,sQ);
} else {
// base64 encode
return Base64.encode(sQ);
}
}
function decode_message(data) {
Log.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 if (mode === 'plain') {
Log.Debug("mode plain")
rQ = rQ.concat(data.split('').map(function(i) { return i.charCodeAt(0);}));
} else {
// base64 decode and concat to the end
rQ = rQ.concat(Base64.decode(data, 0));
}
Log.Debug(">> decode_message, rQ: " + rQ);
}
// Public Send functions
function flush() {
if (websocket.bufferedAmount !== 0) {
Log.Debug('>> flush.bufferedAmount:'+websocket.bufferedAmount);
}
if (websocket.bufferedAmount < api.maxBufferedAmount) {
//Log.Debug("arr: " + arr);
//Log.Debug("sQ: " + sQ);
if (sQ.length > 0) {
websocket.send(encode_message(sQ));
sQ = [];
}
return true;
} else {
Log.Debug('>> flush.delayig send, bufferedAmount:'+websocket.bufferedAmount);
return false;
}
}
// overridable for testing
function send(arr) {
Log.Debug('>> send:'+arr);
sQ = sQ.concat(arr);
return flush();
}
function send_string(str) {
Log.Debug('>> send_string:'+str);
api.send(str.split('').map(function (chr) { return chr.charCodeAt(0); }));
}
// Other public functions
function recv_message(e) {
Log.Debug('>> recv_message:'+e.data.length);
try {
decode_message(e.data);
if (rQlen() > 0) {
eventHandlers.message();
// Compact the receive queue
if (rQ.length > rQmax) {
Log.Debug("Compacting receive queue");
rQ = rQ.slice(rQi);
rQi = 0;
}
} else {
Log.Debug('>> recv_message Ignoring empty message:');
}
} catch (exc) {
if (typeof exc.stack !== 'undefined') {
Log.Warn('>> recv_message caught exc.stack exception:');
} else if (typeof exc.description !== 'undefined') {
Log.Warn('>> recv_message caught exc.description exception:');
} else {
Log.Warn('>> recv_message caught exception:');
}
if (typeof exc.name !== 'undefined') {
eventHandlers.error(exc.name + ": " + exc.message);
} else {
eventHandlers.error(exc);
}
}
Log.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))) {
Log.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 = ['plain', 'binary', 'base64'];
} else {
protocols = ['plain','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') {
Log.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() {
Log.Debug(">> WebSock.onopen");
if (websocket.protocol) {
mode = websocket.protocol;
Log.Info("Server chose sub-protocol: " + websocket.protocol);
} else {
mode = 'base64';
Log.Error("Server select no sub-protocol!: " + websocket.protocol);
}
eventHandlers.open();
Log.Debug('<< WEBSOCKET.onopen:');
};
websocket.onclose = function(e) {
Log.Debug(">> WebSock.onclose");
eventHandlers.close(e);
Log.Debug("<< WebSock.onclose");
};
websocket.onerror = function(e) {
Log.Debug(">> WebSock.onerror: " + e);
eventHandlers.error(e);
Log.Debug("<< WebSock.onerror");
};
}
function close() {
if (websocket) {
if ((websocket.readyState === WebSocket.OPEN) ||
(websocket.readyState === WebSocket.CONNECTING)) {
Log.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

@ -1,216 +0,0 @@
/*
* 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

@ -1,207 +1,270 @@
if (! window.$D) {
window.$D = function (id) {
return document.getElementById(id);
};
}
function Telnet(target, connect_callback, disconnect_callback, initscr) {
var that = {}, // Public API interface
vd, ws, sQ = [];
var that = {}, // Public API interface
vd, ws, sQ = [];
termType = "Viewdata";
termType = "Viewdata";
Array.prototype.pushStr = function (str) {
var n = str.length;
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);
vd.write("\x1e\x11Connecting ...");
}
that.disconnect = function() {
if (ws) {
ws.close();
}
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, initscr);
/*
* 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;
case 0xffc0: // f3
vd.reveal_ ^= 1; vd.refresh(); break;
case 0xffc4: // f7
str = '\x1b'; 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
for (var i=0; i<n; i++) {
this.push(str.charCodeAt(i));
}
}
function do_send() {
Log.Debug('>> do_send');
if (sQ.length > 0) {
ws.send(sQ);
sQ = [];
}
}
function do_recv() {
Log.Debug('>> do_recv');
vd.write(ws.rQshiftStr(ws.rQlen()));
}
that.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");
}
};
that.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");
}
};
that.stopEvent = function(e) {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
};
that.connect = function(host, port, encrypt, url) {
Log.Debug('>> connect');
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);
//vd.write("\x1e\x11Connecting, hang tight...");
vd.write("\x0c"+vd.txthash('#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA0XboW7V61ete7Fuh1oWr1q3QoECBAgQIECBAgQIECBAgQIDRfqw6tWrVq16sOrDUgatWvVqwYMGCBAgQIECBAgQIECBAg')+' '.repeat(40));
}
that.disconnect = function() {
if (ws) {
ws.close();
}
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,initscr);
// 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;
that.addEvent(eventist, 'keydown', vd.key_down);
that.addEvent(eventist, 'keyup', vd.key_up);
} else {
that.removeEvent(eventist, 'keydown', vd.key_down);
that.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;
case 0xffc0: // f3
vd.reveal_ ^= 1;
vd.refresh();
break;
case 0xffc4: // f7
str = '\x1b'; break
}
}
if (str) {
vt.key_buf_.push(str);
setTimeout(VD.go_getch_,0);
}
that.stopEvent(e);
return false;
}
vd.key_up = function(e) {
var vt = VD.the_vt_;
if (vt === undefined)
return true;
that.stopEvent(e);
return false;
}
return that;
}
return constructor(); // Return the public API interface
}