finetuned autorestore and codemirror
/ test (push) Successful in 4s
Details
/ test (push) Successful in 4s
Details
This commit is contained in:
parent
f75f34d6a6
commit
8369dde488
|
@ -2,11 +2,17 @@ if( AFRAME.components.codemirror ) delete AFRAME.components.codemirror
|
||||||
|
|
||||||
AFRAME.registerComponent('codemirror', {
|
AFRAME.registerComponent('codemirror', {
|
||||||
schema: {
|
schema: {
|
||||||
foo: { type:"string"}
|
file: { type:"string"},
|
||||||
|
term: { type:"selector", default: "[isoterminal]" },
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function () {
|
init: function () {
|
||||||
this.el.object3D.visible = false
|
this.el.object3D.visible = false
|
||||||
|
if( !this.data.term || !this.data.term.components ) throw 'codemirror cannot get isoterminal'
|
||||||
|
if( this.data.file && this.data.file[0] != '/'){
|
||||||
|
this.data.file = "root/"+this.data.file
|
||||||
|
}
|
||||||
|
this.isoterminal = this.data.term.components.isoterminal.isoterminal
|
||||||
//this.el.innerHTML = ` `
|
//this.el.innerHTML = ` `
|
||||||
this.requireAll()
|
this.requireAll()
|
||||||
},
|
},
|
||||||
|
@ -17,10 +23,7 @@ AFRAME.registerComponent('codemirror', {
|
||||||
},
|
},
|
||||||
|
|
||||||
requires:{
|
requires:{
|
||||||
window: "com/window.js",
|
window: "com/window.js"
|
||||||
codemirror: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.js",
|
|
||||||
codemirrorcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css",
|
|
||||||
cmtheme: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/shadowfox.css"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
dom: {
|
dom: {
|
||||||
|
@ -49,28 +52,54 @@ AFRAME.registerComponent('codemirror', {
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createEditor: function(value){
|
||||||
|
this.el.setAttribute("window", `title: codemirror; uid: ${this.el.dom.id}; attach: #overlay; dom: #${this.el.dom.id};`)
|
||||||
|
this.editor = CodeMirror( this.el.dom, {
|
||||||
|
value,
|
||||||
|
mode: "htmlmixed",
|
||||||
|
lineNumbers: true,
|
||||||
|
styleActiveLine: true,
|
||||||
|
matchBrackets: true,
|
||||||
|
Tab: "indentMore",
|
||||||
|
defaultTab: function(cm) {
|
||||||
|
if (cm.somethingSelected()) cm.indentSelection("add");
|
||||||
|
else cm.replaceSelection(" ", "end");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.editor.setOption("theme", "shadowfox")
|
||||||
|
this.editor.updateFile = AFRAME.utils.throttleLeadingAndTrailing( (file,str) => {
|
||||||
|
this.updateFile(file,str),
|
||||||
|
2000
|
||||||
|
})
|
||||||
|
this.editor.on('change', (instance,changeObj) => {
|
||||||
|
this.editor.updateFile( this.data.file, instance.getValue() )
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout( () => {
|
||||||
|
this.el.setAttribute("html-as-texture-in-xr", `domid: #${this.el.dom.id}`) // only show aframe-html in xr
|
||||||
|
},1500)
|
||||||
|
},
|
||||||
|
|
||||||
|
updateFile: async function(file,str){
|
||||||
|
// we don't do via shellcmd: isoterminal.exec(`echo '${str}' > ${file}`,1)
|
||||||
|
// as it would require all kindof ugly stringescaping
|
||||||
|
console.log("updating "+file)
|
||||||
|
await this.isoterminal.emulator.fs9p.update_file( file, str)
|
||||||
|
},
|
||||||
|
|
||||||
events:{
|
events:{
|
||||||
|
|
||||||
// component events
|
// component events
|
||||||
DOMready: function(e){
|
DOMready: function(e){
|
||||||
console.log(`title: codemirror; uid: ${this.el.dom.id}; attach: #overlay; dom: #${this.el.dom.id};`)
|
this.isoterminal.emulator.read_file( this.data.file )
|
||||||
this.el.setAttribute("window", `title: codemirror; uid: ${this.el.dom.id}; attach: #overlay; dom: #${this.el.dom.id};`)
|
.then( this.isoterminal.convert.Uint8ArrayToString )
|
||||||
this.editor = CodeMirror( this.el.dom, {
|
.then( (str) => {
|
||||||
value: "function myScript(){return 100;}\n",
|
this.createEditor( str )
|
||||||
mode: "javascript",
|
})
|
||||||
lineNumbers: true,
|
.catch( (e) => {
|
||||||
styleActiveLine: true,
|
console.log("error opening "+this.data.file+", creating new one")
|
||||||
matchBrackets: true,
|
this.createEditor("")
|
||||||
Tab: "indentMore",
|
|
||||||
defaultTab: function(cm) {
|
|
||||||
if (cm.somethingSelected()) cm.indentSelection("add");
|
|
||||||
else cm.replaceSelection(" ", "end");
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
this.editor.setOption("theme", "shadowfox")
|
|
||||||
setTimeout( () => {
|
|
||||||
this.el.setAttribute("html-as-texture-in-xr", `domid: #${this.el.dom.id}`) // only show aframe-html in xr
|
|
||||||
},1500)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ if( typeof AFRAME != 'undefined '){
|
||||||
minimized: { type: 'boolean',"default":false},
|
minimized: { type: 'boolean',"default":false},
|
||||||
maximized: { type: 'boolean',"default":true},
|
maximized: { type: 'boolean',"default":true},
|
||||||
transparent: { type:'boolean', "default":false }, // need good gpu
|
transparent: { type:'boolean', "default":false }, // need good gpu
|
||||||
xterm: { type: 'boolean', "default":true }, // use xterm.js (slower)
|
xterm: { type: 'boolean', "default":true }, // use xterm.js? (=slower)
|
||||||
memory: { type: 'number', "default":48 } // VM memory (in MB)
|
memory: { type: 'number', "default":48 } // VM memory (in MB)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,17 @@ ISOTerminal.addEventListener('emulator-started', function(){
|
||||||
|
|
||||||
if(p.id === -1)
|
if(p.id === -1)
|
||||||
{
|
{
|
||||||
return Promise.resolve(null);
|
return emulator.create_file(file,data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const inode = this.GetInode(p.id);
|
const inode = this.GetInode(p.id);
|
||||||
const buf = typeof data == 'string' ? isoterminal.toUint8Array(data) : data
|
const buf = typeof data == 'string' ? isoterminal.convert.toUint8Array(data) : data
|
||||||
await this.Write(p.id,0, buf.length, buf )
|
await this.Write(p.id,0, buf.length, buf )
|
||||||
// update inode
|
// update inode
|
||||||
inode.size = buf.length
|
inode.size = buf.length
|
||||||
const now = Math.round(Date.now() / 1000);
|
const now = Math.round(Date.now() / 1000);
|
||||||
inode.atime = inode.mtime = now;
|
inode.atime = inode.mtime = now;
|
||||||
|
isoterminal.exec(`touch ${file}`) // update inode
|
||||||
return new Promise( (resolve,reject) => resolve(buf) )
|
return new Promise( (resolve,reject) => resolve(buf) )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,7 +33,7 @@ ISOTerminal.addEventListener('emulator-started', function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
const inode = this.GetInode(p.id);
|
const inode = this.GetInode(p.id);
|
||||||
const buf = typeof data == 'string' ? isoterminal.toUint8Array(data) : data
|
const buf = typeof data == 'string' ? isoterminal.convert.toUint8Array(data) : data
|
||||||
await this.Write(p.id, inode.size, buf.length, buf )
|
await this.Write(p.id, inode.size, buf.length, buf )
|
||||||
// update inode
|
// update inode
|
||||||
inode.size = inode.size + buf.length
|
inode.size = inode.size + buf.length
|
||||||
|
|
|
@ -2,28 +2,6 @@ ISOTerminal.addEventListener('emulator-started', function(e){
|
||||||
this.autorestore(e)
|
this.autorestore(e)
|
||||||
})
|
})
|
||||||
|
|
||||||
ISOTerminal.prototype.convert = {
|
|
||||||
|
|
||||||
arrayBufferToBase64: function(buffer){
|
|
||||||
let binary = '';
|
|
||||||
const bytes = new Uint8Array(buffer);
|
|
||||||
const len = bytes.byteLength;
|
|
||||||
for (let i = 0; i < len; i++) binary += String.fromCharCode(bytes[i]);
|
|
||||||
return window.btoa(binary);
|
|
||||||
},
|
|
||||||
|
|
||||||
base64ToArrayBuffer: function(base64) {
|
|
||||||
const binaryString = window.atob(base64);
|
|
||||||
const len = binaryString.length;
|
|
||||||
const bytes = new Uint8Array(len);
|
|
||||||
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
bytes[i] = binaryString.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return bytes.buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ISOTerminal.prototype.autorestore = async function(e){
|
ISOTerminal.prototype.autorestore = async function(e){
|
||||||
|
|
||||||
localforage.setDriver([
|
localforage.setDriver([
|
||||||
|
@ -32,7 +10,7 @@ ISOTerminal.prototype.autorestore = async function(e){
|
||||||
localforage.LOCALSTORAGE
|
localforage.LOCALSTORAGE
|
||||||
]).then( () => {
|
]).then( () => {
|
||||||
|
|
||||||
localforage.getItem("state", (err,stateBase64) => {
|
localforage.getItem("state", async (err,stateBase64) => {
|
||||||
if( !err && confirm('continue last session?') ){
|
if( !err && confirm('continue last session?') ){
|
||||||
this.noboot = true // see feat/boot.js
|
this.noboot = true // see feat/boot.js
|
||||||
state = this.convert.base64ToArrayBuffer( stateBase64 )
|
state = this.convert.base64ToArrayBuffer( stateBase64 )
|
||||||
|
@ -40,7 +18,19 @@ ISOTerminal.prototype.autorestore = async function(e){
|
||||||
this.emit('postReady',e)
|
this.emit('postReady',e)
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
this.emit('ready',e)
|
this.emit('ready',e)
|
||||||
this.send("alert last session restored\n")
|
// press CTRL+a l (=gnu screen redisplay)
|
||||||
|
setTimeout( () => this.send("l\n"),400 )
|
||||||
|
// reload index.js
|
||||||
|
this.emulator.read_file("root/index.js")
|
||||||
|
.then( this.convert.Uint8ArrayToString )
|
||||||
|
.then( this.runJavascript )
|
||||||
|
.catch( console.error )
|
||||||
|
// reload index.html
|
||||||
|
this.emulator.read_file("root/index.html")
|
||||||
|
.then( this.convert.Uint8ArrayToString )
|
||||||
|
.then( this.runHTML )
|
||||||
|
.catch( console.error )
|
||||||
|
|
||||||
}, 500 )
|
}, 500 )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -50,6 +40,13 @@ ISOTerminal.prototype.autorestore = async function(e){
|
||||||
console.log( String(this.convert.arrayBufferToBase64(state)).substr(0,5) )
|
console.log( String(this.convert.arrayBufferToBase64(state)).substr(0,5) )
|
||||||
localforage.setItem("state", this.convert.arrayBufferToBase64(state) )
|
localforage.setItem("state", this.convert.arrayBufferToBase64(state) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("beforeunload", function (e) {
|
||||||
|
var confirmationMessage = "Sure you want to leave?\nTIP: enter 'save' to continue this session later";
|
||||||
|
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
|
||||||
|
return confirmationMessage; //Webkit, Safari, Chrome
|
||||||
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ ISOTerminal.prototype.boot = async function(e){
|
||||||
if( typeof document.location[i] == 'string' )
|
if( typeof document.location[i] == 'string' )
|
||||||
env.push( 'export '+String(i).toUpperCase()+'="'+document.location[i]+'"')
|
env.push( 'export '+String(i).toUpperCase()+'="'+document.location[i]+'"')
|
||||||
}
|
}
|
||||||
await this.emulator.create_file("profile.browser", this.toUint8Array( env.join('\n') ) )
|
await this.emulator.create_file("profile.browser", this.convert.toUint8Array( env.join('\n') ) )
|
||||||
|
|
||||||
if( this.serial_input == 0 ){
|
if( this.serial_input == 0 ){
|
||||||
if( !this.noboot ){
|
if( !this.noboot ){
|
||||||
|
|
|
@ -10,14 +10,7 @@ ISOTerminal.addEventListener('init', function(){
|
||||||
const decoder = new TextDecoder('utf-8');
|
const decoder = new TextDecoder('utf-8');
|
||||||
const html = decoder.decode(buf)
|
const html = decoder.decode(buf)
|
||||||
try{
|
try{
|
||||||
let $scene = document.querySelector("a-scene")
|
this.runHTML(html)
|
||||||
let $root = document.querySelector("a-entity#root")
|
|
||||||
if( !$root ){
|
|
||||||
$root = document.createElement("a-entity")
|
|
||||||
$root.id = "root"
|
|
||||||
$scene.appendChild($root)
|
|
||||||
}
|
|
||||||
$root.innerHTML = html
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
@ -27,3 +20,13 @@ ISOTerminal.addEventListener('init', function(){
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ISOTerminal.prototype.runHTML = function(html){
|
||||||
|
let $scene = document.querySelector("a-scene")
|
||||||
|
let $root = document.querySelector("a-entity#root")
|
||||||
|
if( !$root ){
|
||||||
|
$root = document.createElement("a-entity")
|
||||||
|
$root.id = "root"
|
||||||
|
$scene.appendChild($root)
|
||||||
|
}
|
||||||
|
$root.innerHTML = html
|
||||||
|
}
|
||||||
|
|
|
@ -10,13 +10,7 @@ ISOTerminal.addEventListener('init', function(){
|
||||||
const decoder = new TextDecoder('utf-8');
|
const decoder = new TextDecoder('utf-8');
|
||||||
const js = decoder.decode(buf)
|
const js = decoder.decode(buf)
|
||||||
try{
|
try{
|
||||||
let $root = document.querySelector("script#root")
|
this.runJavascript(js)
|
||||||
if( !$root ){
|
|
||||||
$root = document.createElement("script")
|
|
||||||
$root.id = "root"
|
|
||||||
document.body.appendChild($root)
|
|
||||||
}
|
|
||||||
$root.innerHTML = js
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
@ -26,3 +20,13 @@ ISOTerminal.addEventListener('init', function(){
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ISOTerminal.prototype.runJavascript = function(js){
|
||||||
|
let $root = document.querySelector("script#root")
|
||||||
|
if( !$root ){
|
||||||
|
$root = document.createElement("script")
|
||||||
|
$root.id = "root"
|
||||||
|
document.body.appendChild($root)
|
||||||
|
}
|
||||||
|
$root.innerHTML = js
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,7 @@ ISOTerminal.addEventListener('init', function(){
|
||||||
// unix to js device
|
// unix to js device
|
||||||
this.readFromPipe( '/mnt/js', async (data) => {
|
this.readFromPipe( '/mnt/js', async (data) => {
|
||||||
const buf = await emulator.read_file("js")
|
const buf = await emulator.read_file("js")
|
||||||
const decoder = new TextDecoder('utf-8');
|
const script = this.convert.Uint8ArrayToString(buf)
|
||||||
const script = decoder.decode(buf)
|
|
||||||
let PID="?"
|
let PID="?"
|
||||||
try{
|
try{
|
||||||
if( script.match(/^PID/) ){
|
if( script.match(/^PID/) ){
|
||||||
|
@ -18,7 +17,7 @@ ISOTerminal.addEventListener('init', function(){
|
||||||
if( res && typeof res != 'string' ) res = JSON.stringify(res,null,2)
|
if( res && typeof res != 'string' ) res = JSON.stringify(res,null,2)
|
||||||
// write output to 9p with PID as filename
|
// write output to 9p with PID as filename
|
||||||
// *FIXME* not flexible / robust
|
// *FIXME* not flexible / robust
|
||||||
emulator.create_file(PID, this.toUint8Array(res) )
|
emulator.create_file(PID, this.convert.toUint8Array(res) )
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ AFRAME.registerComponent('window', {
|
||||||
this.el.emit('window.onclose',e)
|
this.el.emit('window.onclose',e)
|
||||||
if( e.halt ) return true
|
if( e.halt ) return true
|
||||||
this.data.dom.style.display = 'none';
|
this.data.dom.style.display = 'none';
|
||||||
|
if( this.el.parentNode ) this.el.remove() //parentElement.remove( this.el )
|
||||||
this.data.dom.parentElement.remove()
|
this.data.dom.parentElement.remove()
|
||||||
this.el.parentElement.remove( this.el )
|
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue