var bricks = window.bricks || {}; /* dependent on xterm.js */ bricks.Wterm = class extends bricks.JsWidget { /* { ws_url: ping_timeout:19 } */ constructor(opts){ super(opts); this.socket = null; this.ping_timeout = opts.ping_timeout || 19; schedule_once(this.open.bind(this), 1); this.bind('domon', this.send_term_size.bind(this)); this.bind('domoff', this.destroy.bind(this)); } close_websocket(){ try { console.log('socket alive, destroy it'); // this.socket.send(JSON.stringify({ type: "close"})); this.socket.close(1000,'close now'); this.socket.onopen = null; this.socket.onmessage = null; this.socket.onerror = null; this.socket.onclose = null; this.socket = null; } catch(e) { this.socket = null; console.log('e=', e); } } close_terminal(){ try { this.fitAddon.dispose(); this.term.dispose(); this.term = null; } catch(e){ this.term = null; console.log('e=', e); } } destroy(){ console.debug('------domoff event, destory this widget'); try { this.unbind('element_resize', this.term_resize.bind(this)) } catch(e) { console.log('error ', e); } console.debug('---1--domoff event, destory this widget'); if (this.socket){ this.close_websocket(); } console.debug('---2--domoff event, destory this widget'); if (this.term){ this.close_terminal(); } console.debug('---3--domoff event, destory this widget'); } charsize_sizing(){ var cs = bricks.app.charsize; this.term.setOption('fontSize', cs); } send_term_size(){ console.debug('------domon event, send the terminal size to server'); try { console.log('resize():rows=', this.term.rows, this.term.cols); this.socket.send(JSON.stringify({ type: "resize", width:this.get_width(), height: this.get_height(), rows: this.term.rows, cols: this.term.cols })); } catch (e) { console.log('ws not ready'); } } send_data(d){ this.socket.send(JSON.stringify({type: "input", "data":d})); } async open(){ var term_options = bricks.extend({width: "100%", height: "100%"}, this.term_options); var term = new Terminal(term_options); this.term = term; term.open(this.dom_element); // var sessdata = bricks.app.get_session(); // var ws = new WebSocket(this.opts.ws_url, sessdata); var ws = new WebSocket(this.opts.ws_url); this.socket = ws; this.fitAddon = new FitAddon.FitAddon() term.loadAddon(this.fitAddon) this.fitAddon.fit(); this.charsize_sizing(); ws.onmessage = event => { var msg = JSON.parse(event.data); console.log('ws msg=', msg); if (msg.data.type == 'heartbeat'){ console.log('connection alive'); } else if (msg.data.type == 'data') { term.write(msg.data.data); } else { console.log('get server data = ', msg.data); } }; ws.onclose = (event) => { console.log('websocket closed:', event.code, '--', event.reason); }; ws.onopen = () => { this.send_term_size(); this.bind('element_resize', this.term_resize.bind(this)) }; term.onData((key) => { console.log('key=', key); this.send_data(key); }); term.onResize(({cols, rows}) =>{ this.send_term_size(); }); this.send_term_size(); term.focus(); } term_resize(){ try { console.log('widget resize event fired'); this.fitAddon.fit(); // this.send_term_size(); } catch(e){ console.log('resize error', e); } } } bricks.Factory.register('Wterm', bricks.Wterm);