bridge browser js execution via device /dev/browser/js
/ test (push) Successful in 5s Details

This commit is contained in:
Leon van Kammen 2024-08-26 12:02:35 +02:00
parent 68ee93f6e9
commit 3c8d84c46d
15 changed files with 161 additions and 17 deletions

View File

@ -44,9 +44,6 @@ AFRAME.registerComponent('isoterminal', {
background: #000c;
overflow:hidden;
}
body .winbox .wb-header{
background: linear-gradient(45deg, var(--xrsh-primary), var(--xrsh-third) )
}
.isoterminal div{ display:block; }
.isoterminal span{ display: inline }
@ -155,9 +152,13 @@ AFRAME.registerComponent('isoterminal', {
motd += "\033[0m"
const files = [
"com/isoterminal/mnt/gui",
"com/isoterminal/mnt/boot",
"com/isoterminal/mnt/edit",
"com/isoterminal/mnt/js",
"com/isoterminal/mnt/jsh",
"com/isoterminal/mnt/confirm",
"com/isoterminal/mnt/prompt",
"com/isoterminal/mnt/alert",
"com/isoterminal/mnt/profile",
"com/isoterminal/mnt/motd",
]
emulator.bus.register("emulator-started", async () => {
@ -212,7 +213,19 @@ AFRAME.registerComponent('isoterminal', {
//console.dir({line,new_line})
if( !ready && line.match(/^(\/ #|~%)/) ){
instance.dom.classList.remove('blink')
emulator.serial0_send("source /mnt/boot\n")
// set environment
let env = ['export BROWSER=1']
for ( let i in document.location ){
if( typeof document.location[i] == 'string' )
env.push( 'export '+String(i).toUpperCase()+'="'+document.location[i]+'"')
}
env.map( (e) => emulator.serial0_send(`echo '${e}' >> /mnt/profile\n`) )
let boot = `source /mnt/profile`
// exec hash as extra boot cmd
if( document.location.hash.length > 1 ){
boot += `&& cmd='${decodeURI(document.location.hash.substr(1))}' && $cmd`
}
emulator.serial0_send(boot+"\n")
instance.winbox.maximize()
emulator.serial_adapter.term.focus()
ready = true
@ -220,6 +233,24 @@ AFRAME.registerComponent('isoterminal', {
//emulator.serial0_send("mv /mnt/js . && chmod +x js\n")
}
});
// unix to js device
emulator.add_listener("9p-write-end", async (opts) => {
const decoder = new TextDecoder('utf-8');
if ( opts[0] == 'js' ){
const buf = await emulator.read_file("dev/browser/js")
const script = decoder.decode(buf)
try{
let res = (new Function(`return ${script}`))()
if( res && typeof res != 'string' ) res = JSON.stringify(res,null,2)
emulator.create_file( "dev/browser/js", this.toUint8Array( res || '' ) )
}catch(e){
console.dir(e)
emulator.create_file("dev/browser/js", this.toUint8Array( `[e] `+String(e.stack) ) )
}
}
})
});
@ -266,7 +297,7 @@ AFRAME.registerComponent('isoterminal', {
if( instance.dom.emulator && instance.dom.emulator.serial_adapter ){
setTimeout( () => {
this.autoResize(instance.dom.emulator.serial_adapter.term,instance,-5)
},1000) // wait for resize anim
},500) // wait for resize anim
}
}
instance.addEventListener('window.onresize', resize )

2
com/isoterminal/mnt/alert Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
jsh alert "$1"

View File

@ -1,5 +0,0 @@
chmod +x /mnt/gui /mnt/js
clear
cat /mnt/motd
export PATH=$PATH:/mnt
export PS1="\nxrsh $ \033[0m"

10
com/isoterminal/mnt/confirm Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
test -f /mnt/V86 && {
jsh confirm $1 $2
}
test -f /mnt/V86 || {
read -p "$(printf "\033[0m")[?] $1 [y/n] $(printf "\033[0m")" y
test $y = y && echo true && exit
echo false
}

View File

View File

@ -0,0 +1 @@
alert("hello")

View File

@ -1 +0,0 @@
hello

5
com/isoterminal/mnt/js Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
flock /dev/browser/js -c "echo '$*' > /dev/browser/js; cat /dev/browser/js"
# we use flock, an awesome way to make processes read/write the same file
# whilr preventing 1001 concurrency issues

17
com/isoterminal/mnt/jsh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
# usage: jsh <function> [arg1] [arg2] ...
#
# 'jsh prompt question answer' executes: js prompt('question','answer') )
to_js(){
printf "%s(" "$1"
shift
for arg in "$@"; do
printf '"%s",' "$arg"
done
printf ")\n"
}
func=$(to_js "$@")
func=${func/,)/)}
/mnt/js "$func"

15
com/isoterminal/mnt/motd Normal file
View File

@ -0,0 +1,15 @@
 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 . . ____ _____________ ________. ._. ._. . . . . . . . .
 . . _\ \/ /\______ \/ _____// | \. . . . . . . .
 . . _ \ / | _/\_____ \/ ~ \ . . . . . . .
 _ _ / \ | | \/ \ Y / _ _ _ _ _ _ _
 . . /___/\ \ |____|_ /_______ /\___|_ /. . . . . . . .
 . . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . .
 ▬ ▬ ▬ https://xrsh.isvery.ninja ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬ ▬
 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Open, local-first, hackable & selfcontained XR apps.
credits: all FOSS devs | @lvk@mastodon.online
copy.sh (v86) | @utopiah@mastodon.pirateparty.be

View File

@ -0,0 +1,29 @@
install_xrsh(){
chmod +x /mnt/confirm /mnt/prompt /mnt/alert /mnt/js*
setup_browser_dev(){
mkdir -p /mnt/dev/browser
touch /mnt/dev/browser/js
touch /mnt/dev/browser/html
ln -s /mnt/dev/browser /dev/browser
test -f /etc/profile && rm /etc/profile
ln -s /mnt/profile /etc/profile
}
setup_browser_dev
}
test -d /dev/browser || install_xrsh
test -f /mnt/V86 && {
mount -a
udhcpc 1>>/var/log/network.log 2>>/var/log/network.log &
echo 0 > /proc/sys/kernel/printk
}
resize
#clear
cat /mnt/motd
export PATH=$PATH:/mnt
export PS1="\nxrsh # \033[0m"

9
com/isoterminal/mnt/prompt Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
test -f /mnt/V86 && {
jsh prompt "$1" "$2"
}
test -f /mnt/V86 || {
read -p "$(printf "\033[0m")[?] $1: $(printf "\033[0m")" answer
echo "$answer"
}

26
com/isoterminal/mnt/test.awk Executable file
View File

@ -0,0 +1,26 @@
#!/bin/awk -f
BEGIN {
for (i = 1; i < ARGC; i++) {
options[i] = ARGV[i]
}
ARGC = 0
selected = 1
n = length(options)
while (1) {
printf "\r "
for (i = 1; i <= n; i++) {
if (i == selected)
printf "\033[44m%s\033[0m ", options[i]
else
printf "%s ", options[i]
}
if (c == 0) {
getline dir < "/dev/stdin"
print dir
if (dir == "up" && selected > 1) selected--
if (dir == "down" && selected < n) selected++
}
}
}

View File

@ -34,7 +34,8 @@ AFRAME.utils.require = function(arr_or_obj,opts){
if( AFRAME.required[id] ) return // already loaded before
AFRAME.required[id] = true
if( !document.body.querySelector(`script#${id}`) ){
if( !document.body.querySelector(`script#${id}`) &&
!document.body.querySelector(`link#${id}`) ){
let {type} = parseURI(package)
let p = new Promise( (resolve,reject) => {
switch(type){
@ -49,8 +50,9 @@ AFRAME.utils.require = function(arr_or_obj,opts){
link.id = id
link.href = package
link.rel = 'stylesheet'
link.onload = () => setTimeout( () => resolve(id), 50 )
link.onerror = (e) => reject(e)
document.body.appendChild(link)
resolve(id)
break;
}
})

View File

@ -14,7 +14,7 @@ AFRAME.registerComponent('window', {
dom: "com/dom.js",
html: "https://unpkg.com/aframe-htmlmesh@2.1.0/build/aframe-html.js", // html to AFRAME
winboxjs: "https://unpkg.com/winbox@0.2.82/dist/winbox.bundle.min.js", // deadsimple windows: https://nextapps-de.github.io/winbox
winboxcss: "https://unpkg.com/winbox@0.2.82/dist/css/winbox.min.css", //
//winboxcss: "https://unpkg.com/winbox@0.2.82/dist/css/winbox.min.css", // main theme
},
init: function(){
@ -52,6 +52,9 @@ AFRAME.registerComponent('window', {
this.el.emit('window.onclose',e)
if( e.halt ) return true
this.data.dom.style.display = 'none';
this.data.dom.parentElement.remove()
debugger
this.el.parentElement.remove( this.el )
return false
},
});