diff --git a/com/isoterminal/feat/boot.js b/com/isoterminal/feat/boot.js
index 340ee69..da92c63 100644
--- a/com/isoterminal/feat/boot.js
+++ b/com/isoterminal/feat/boot.js
@@ -45,7 +45,18 @@ if( typeof window.PromiseWorker != 'undefined' ){ // if xrsh v86 is able to run
{
key: "1",
title: (opts) => `boot [31m${String(opts.iso || "").replace(/.*\//,'')}[0m Linux ❤️ `,
- init: function(){ this.bootISO() },
+ init: function(){
+
+ // hack to notify href clicks
+ Term.prototype.href = (a) => {
+ if( a.href ){
+ this.exec(`source /etc/profile.sh; hook href "${a.href}"`)
+ }
+ return false
+ }
+
+ this.bootISO()
+ },
keyHandler: function(ch){ this.send(ch) } // send to v86 webworker
}
)
diff --git a/com/isoterminal/feat/remotekeyboard.js b/com/isoterminal/feat/remotekeyboard.js
index 3b5edf7..1fb92fc 100644
--- a/com/isoterminal/feat/remotekeyboard.js
+++ b/com/isoterminal/feat/remotekeyboard.js
@@ -1,34 +1,87 @@
ISOTerminal.prototype.enableRemoteKeyboard = function(opts){
+ let service = {
+ ready: false,
+ reset: (service) => {
+ service.ip = localStorage.getItem("keyboardIP") || ""
+ service.ip = service.ip.trim()
+ service.state = "need-ip"
+ service.attempts = 0
+ },
+ init: function init( mainmenu ){
+ this.emit('status',"")
+ this.emit('enable-console',{stdout:true})
+ service.reset(service)
+ setTimeout( () => {
+ const clearScreen = "[1;1H[2J\r"
+ this.send(clearScreen);
+ this.send(`\n\rfor instructions\n\rsee ${document.location.origin}/index.html#Remote%20keyboard\n\n\r`)
+ this.send("enter 'm' for mainmenu\n\n\r")
+ this.send("[36mkeyboard ip-adress> [0m")
+ // autofill ip
+ if( service.ip ){
+ for( let i = 0; i < service.ip.length; i++ ) this.send(service.ip.charAt(i))
+ }
+ }, 100 )
+ },
+ server: (term) => {
+ try{
+ service.addr = `ws://${service.ip}:9090/`;
+ service.ws = new WebSocket(service.addr)
+ service.ws.addEventListener("open", () => {
+ if( service.state == 'listening' ){
+ this.send(`\n\rconnected to ${service.addr}! \\o/\n\r`)
+ this.bootMenu()
+ }
+ service.state = 'receiving'
+ })
+ service.ws.addEventListener("close", () => {
+ service.attempts += 1
+ if( service.attempts > 3 && service.state == 'listening'){
+ service.reset(service)
+ this.send(`\n\roops..I did not detect any connection :/\n\r`)
+ localStorage.setItem("keyboardIP","") // reset ip
+ this.bootMenu()
+ }else setTimeout( () => service.server(term), 1000 ) // retry connection
+ }) // retry on EOF
+ service.ws.onmessage = function(event) {
+ if( !event.data ) return
+ event.data.arrayBuffer().then( (buf) => {
+ const arr = new Uint8Array(buf)
+ let string = Array.from(arr, byte => String.fromCharCode(byte)).join('')
+ term.term.handler(string)
+ service.state = 'receiving'
+ localStorage.setItem("keyboardIP",service.ip) // save ip for later
+ })
+ };
+ }catch(e){
+ console.error(e)
+ service.reset(service)
+ localStorage.setItem("keyboardIP","") // reset ip
+ this.bootMenu()
+ }
+ }
+ }
+
// initialize REPL
ISOTerminal.prototype.boot.menu.push(
{
key: "k",
title: (opts) => "connect a remote keyboard",
- init: function( mainmenu ){
- this.emit('status',"")
- this.emit('enable-console',{stdout:true})
- setTimeout( () => {
- this.send("[2J\n\r1. open a terminal on your laptop/desktop\n\r")
- this.send("2. run (or install) the keyboard forwarder:\n\n\r")
- this.send("\t[36m$[0m wget https://xrsh.isvery.ninja/xrsh\n\r")
- this.send("\t[36m$[0m chmod +x xrsh\n\r")
- this.send("\t[36m$[0m ./xrsh --keyboard\n\r\n\r")
- this.send("\t[36mNOTE:[0m windows-users need WSL\n\n\r")
- this.send("press a key to connect.. (or 'm' for mainmenu)\n\r")
- }, 100 )
- },
+ init: service.init,
keyHandler: function(ch){
this.send(ch)
- if( ch == 'm'){
- this.bootMenu()
- }else if( (ch == "\n" || ch == "\r") ){
- try{
- console.log("running websocket server")
+ if( service.state == 'need-ip'){
+ if( ch == 'm'){
this.send("\n\r")
- }catch(e){
- reset()
- throw e // re throw
+ this.bootMenu()
+ }else if( ch == '\n' || ch == '\r'){
+ this.send("\n\rwaiting for connection..")
+ service.server(this)
+ service.state = 'listening'
+ }else{
+ service.ip = ch == '\b' ? service.ip.substr(0,this.service.ip.length-1)
+ : service.ip + ch
}
}
}
diff --git a/com/isoterminal/feat/term.js b/com/isoterminal/feat/term.js
index ea6b84c..46b2ad5 100644
--- a/com/isoterminal/feat/term.js
+++ b/com/isoterminal/feat/term.js
@@ -40,13 +40,8 @@ ISOTerminal.prototype.TermInit = function(){
}
}( Term.prototype.keyDownHandler )
- Term.prototype.href = (a) => {
- if( a.href ){
- this.exec(`source /etc/profile.sh; hook href "${a.href}"`)
- }
- return false
- }
this.term = new Term( opts.termOpts )
+ Term.prototype.href = (a) => true
this.term.colors = [
/* normal */
"#000000",
@@ -93,7 +88,7 @@ ISOTerminal.prototype.TermInit = function(){
})
}
}else{
- this.term.write(ch)
+ this.term.write( ch )
}
if( !erase ) this.lastChar = ch
})
diff --git a/com/isoterminal/term.js b/com/isoterminal/term.js
index 4d5b7cc..3566a5f 100644
--- a/com/isoterminal/term.js
+++ b/com/isoterminal/term.js
@@ -294,7 +294,7 @@ Term.prototype.refresh = function(ymin, ymax)
function is_http_link_char(c)
{
- var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=`.";
+ var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=%`.";
return str.indexOf(String.fromCharCode(c)) >= 0;
}
@@ -353,7 +353,7 @@ Term.prototype.refresh = function(ymin, ymax)
outline += '';
last_attr = this.def_attr;
}
- outline += "";
+ outline += "";
}
}
if (i == cx) {
@@ -1049,9 +1049,8 @@ Term.prototype.interceptBrowserExit = function (ev)
Term.prototype.keyDownHandler = function (ev)
{
var str;
-
this.interceptBrowserExit(ev);
-
+
str="";
switch(ev.keyCode) {
case 8: /* backspace */