diff --git a/src/XDocumentANSIShell.js b/src/XDocumentANSIShell.js deleted file mode 100644 index d5e72fe..0000000 --- a/src/XDocumentANSIShell.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 Puter Technologies Inc. - * - * This file is part of Phoenix Shell. - * - * Phoenix Shell is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -export class XDocumentANSIShell { - constructor (params) { - this.internal_ = {}; - for ( const k in params ) this.internal_[k] = params[k]; - } - - attachToIframe (iframeEl) { - const source = this.internal_.source; - - iframeEl.src = source; - - this.internal_.window = iframeEl.contentWindow; - this.attachToWindow_(); - } - - attachToWindow_ () { - const contentWindow = this.internal_.window; - const ptt = this.internal_.ptt; - - window.addEventListener('message', evt => { - if ( evt.source !== contentWindow ) return; - if ( ! (evt.data instanceof Uint8Array) ) return; - - ptt.out.write(evt.data); - }); - - (async () => { - for ( ;; ) { - const chunk = (await ptt.in.read()).value; - contentWindow.postMessage(chunk, this.internal_.source); - } - })(); - } -} diff --git a/src/main_puter.js b/src/main_puter.js index 5fc4e42..9fed096 100644 --- a/src/main_puter.js +++ b/src/main_puter.js @@ -30,27 +30,27 @@ window.main_shell = async () => { const configured_ = new Promise(rslv => { resolveConfigured = rslv; }); - window.addEventListener('message', evt => { - if ( evt.source !== window.parent ) return; - if ( evt.data instanceof Uint8Array ) { - return; - } - if ( ! evt.data.hasOwnProperty('$') ) { - console.error(`unrecognized window message`, evt); - return; - } - if ( evt.data.$ !== 'config' ) return; - console.log('received configuration at ANSI shell'); - const configValues = { ...evt.data }; - delete configValues.$; - for ( const k in configValues ) { - config[k] = configValues[k]; + const terminal = puter.ui.parentApp(); + if (!terminal) { + console.error('Phoenix cannot run without a parent Terminal. Exiting...'); + puter.exit(); + return; + } + terminal.on('message', message => { + if (message.$ === 'config') { + const configValues = { ...message }; + delete configValues.$; + for ( const k in configValues ) { + config[k] = configValues[k]; + } + resolveConfigured(); } - resolveConfigured(); }); - window.parent.postMessage({ $: 'ready' }, '*'); + // FIXME: on terminal close, close ourselves + + terminal.postMessage({ $: 'ready' }); await configured_; @@ -63,7 +63,7 @@ window.main_shell = async () => { || 'https://api.puter.com'; await puterSDK.setAPIOrigin(source_without_trailing_slash); - const ptt = new XDocumentPTT(); + const ptt = new XDocumentPTT(terminal); await launchPuterShell(new Context({ ptt, config, puterSDK, diff --git a/src/pty/XDocumentPTT.js b/src/pty/XDocumentPTT.js index fbf96d8..13ea657 100644 --- a/src/pty/XDocumentPTT.js +++ b/src/pty/XDocumentPTT.js @@ -21,7 +21,7 @@ import { BetterReader } from "dev-pty"; const encoder = new TextEncoder(); export class XDocumentPTT { - constructor() { + constructor(terminalConnection) { this.ioctl_listeners = {}; this.readableStream = new ReadableStream({ @@ -37,24 +37,25 @@ export class XDocumentPTT { if (typeof chunk === 'string') { chunk = encoder.encode(chunk); } - window.parent.postMessage(chunk, '*'); + terminalConnection.postMessage({ + $: 'output', + data: chunk, + }); } }); this.out = this.writableStream.getWriter(); this.in = this.readableStream.getReader(); this.in = new BetterReader({ delegate: this.in }); - window.addEventListener('message', evt => { - if ( ! evt.source === window.parent ) return; - - if ( evt.data.hasOwnProperty('$') ) { - if ( evt.data.$ === 'ioctl.set' ) { - this.emit('ioctl.set', evt); - } + terminalConnection.on('message', message => { + if (message.$ === 'ioctl.set') { + this.emit('ioctl.set', message); + return; + } + if (message.$ === 'input') { + this.readController.enqueue(message.data); + return; } - - if ( ! (evt?.data instanceof Uint8Array) ) return; - this.readController.enqueue(evt.data); }); } diff --git a/src/puter-shell/XDocumentPuterShell.js b/src/puter-shell/XDocumentPuterShell.js deleted file mode 100644 index 8fb322d..0000000 --- a/src/puter-shell/XDocumentPuterShell.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2024 Puter Technologies Inc. - * - * This file is part of Phoenix Shell. - * - * Phoenix Shell is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -export class XDocumentPuterShell extends EventTarget { - constructor (params) { - super(); - this.internal_ = {}; - for ( const k in params ) this.internal_[k] = params[k]; - this.ready_ = false; - } - - set ready (v) { - if ( ! v ) throw new Error(`can't set ready to false`); - if ( this.ready_ ) throw new Error(`duplicate ready event`); - this.ready_ = true; - console.log('dispatching the ready event'); - this.dispatchEvent(new CustomEvent('ready', {})); - } - - get ready () { return this.ready_ } - - attachToIframe (iframeEl) { - const source = this.internal_.source; - - iframeEl.src = source; - - this.internal_.window = iframeEl.contentWindow; - this.attachToWindow_(); - } - - attachToWindow_ () { - const contentWindow = this.internal_.window; - const ptt = this.internal_.ptt; - - window.addEventListener('message', evt => { - if ( evt.source !== contentWindow ) return; - - if ( ! evt.data.$ ) { - throw new Error('unrecognized message format'); - } - - if ( evt.data.$ === 'ready' ) { - this.ready = true; - } - }); - } - - configure (config) { - const contentWindow = this.internal_.window; - contentWindow.postMessage({ - ...config, - $: 'config' - }, this.internal_.source); - } - - async command (cmdName, command) { - const contentWindow = this.internal_.window; - let result; - const p = new Promise(rslv => { - const lis = evt => { - if ( evt.source !== contentWindow ) return; - if ( ! evt.data.$ ) { - console.error('message without $ when waiting'); - return; - } - if ( evt.data.$ !== 'command-done' ) return; - result = evt.data.result; - rslv(); - window.removeEventListener('message', lis); - } - window.addEventListener('message', lis); - }); - contentWindow.postMessage({ - ...command, - $: 'command', - $$: cmdName, - }, this.internal_.source); - await p; - return result; - } -} diff --git a/src/puter-shell/main.js b/src/puter-shell/main.js index 8ccbf54..0e62529 100644 --- a/src/puter-shell/main.js +++ b/src/puter-shell/main.js @@ -17,7 +17,6 @@ * along with this program. If not, see . */ import builtins from './coreutils/__exports__.js'; -import { XDocumentPTT } from "../pty/XDocumentPTT.js"; import ReadlineLib from "../ansi-shell/readline/readline.js"; // TODO: auto-gen argument parser registry from files @@ -125,7 +124,7 @@ export const launchPuterShell = async (ctx) => { ptt.on('ioctl.set', evt => { ansiShell.dispatchEvent(new CustomEvent('signal.window-resize', { detail: { - ...evt.data.windowSize + ...evt.windowSize } })); });