diff --git a/jrx/pages/gb.html b/jrx/pages/gb.html index 939e9e2..c6bfc13 100644 --- a/jrx/pages/gb.html +++ b/jrx/pages/gb.html @@ -15,5 +15,7 @@
+ + diff --git a/jrx/pages/gb.js b/jrx/pages/gb.js new file mode 100644 index 0000000..372c14c --- /dev/null +++ b/jrx/pages/gb.js @@ -0,0 +1,17 @@ +// see b_lib.ts, function gb for the thing that talks to this +main(); + +async function main() { + // connect to the runtime + let port = browser.runtime.connect(); + // wait for a message + port.onMessage.addListener( + function({title, miscinfo, timeout_ms}) { + console.log('title', title); + console.log('miscinfo', miscinfo); + console.log('timeout_ms', timeout_ms); + document.getElementById('title-h1').innerHTML = title; + document.getElementById('miscinfo').innerHTML = miscinfo; + } + ); +} diff --git a/jrx/scratch/clown-town.ts b/jrx/scratch/clown-town.ts new file mode 100644 index 0000000..7231835 --- /dev/null +++ b/jrx/scratch/clown-town.ts @@ -0,0 +1,50 @@ + + function + the_function_that_runs_in_the_context_of_gb_dot_html + (gb_title : string, + gb_miscinfo : string, + gb_timeout_ms : number) + : string + { + // FIXME: not alerting user about bobs + alert('bobs!'); + //// the last evaluated statement of this function is the "return value" + //// as far as scripting.executeScript is concerned + //console.log('gb_title', gb_title); + //console.log('gb_miscinfo', gb_miscinfo); + //console.log('gb_timeout_ms', gb_timeout_ms); + + //document.getElementById('title-h1')!.innerHTML = gb_title; + + return 'good'; + } + + console.log('badness'); + // @ts-ignore i'm just assuming typescript is going to be stupid here i don't even know + let dialog_result: Array<{result: gb} | {error: any}> = + await browser.scripting.executeScript( + // @ts-ignore i'm just assuming typescript is going to be stupid here i don't even know + {func : the_function_that_runs_in_the_context_of_gb_dot_html, + args : [title, miscinfo, timeout_ms], + target : {tabId : tabid}, + // script just hangs forever without this line + // in no case does it alert user about bobs + // alright + // need a break + // when we get back, let's try a file + // otherwise we're going to have to try a totally different idiom + // maybe go back to some retarded message passing nonsense + injectImmediately: true + } + ); + + console.log('dialog_result', dialog_result[0]); + // @ts-ignore + if (dialog_result[0].error) { + // @ts-ignore + throw dialog_result.error; + } + else { + // @ts-ignore + return dialog_result[0].result; + } diff --git a/jrx/src/b_lib.ts b/jrx/src/b_lib.ts index 7b1bef3..6250ab6 100644 --- a/jrx/src/b_lib.ts +++ b/jrx/src/b_lib.ts @@ -495,6 +495,40 @@ let GB_MIN = 60*GB_SEC; * Timeout should be a multiple of 5. Use `GB_SEC` or `GB_MIN` because you're * stupid and can't do math. * + * # Why this is stupid + * + * Ok super important thing: there's a very stupid idiom in here for talking to + * the good/bad popup window. This is not because I am stupid. This is because + * web browsers are stupid. + * + * We cannot just spawn a window and then start talking to it. The problem is + * that this isn't Erlang where the process has a mailbox and we can count on + * the messages being delivered there and then being there when the process + * initiates a `raseev`. + * + * Instead the good/bad popup-window process has to spawn *and then listen for + * messages*, and if we send a message before it's listening, tough, it just + * doesn't get there. + * + * First instinct was of course to just wait for however many milliseconds for + * the popup window to spawn before sending it messages. But 200ms was not + * enough time for this approach to work on my beast of a machine. Given that + * our users are going to be running JR on normal machines, this approach is + * simply infeasible. + * + * Instead after much denial and error, I found the approach where the good/bad page script + * initiates a connection works consistently and is idiomatically sane, at + * least in relative terms. In this case, we are using the Port abstraction + * rather than the "one-off" connection thing that Mozilla says is low class. + * It is better in this case so that we don't have to deal with process-level + * global state in this function. + * + * If we wanted to interleave that nonsense into the global raseev loop at the + * top of this file, we would have to basically have some registry of pages + * we're trying to talk to, and then have some message queue that pairs each + * message from a script with whomever is trying to listen to it. That's + * doable but I would prefer not to create global state if it's unnecessary. + * * @internal */ async function @@ -504,72 +538,50 @@ gb timeout_ms : number) : Promise { - console.log('507'); + // we're going to make an unresolved result first + // write our code to handle messages from the popup window + // which updates this variable + // once this variable is updated with resolved: true + // then the entire function returns + let the_result : {resolved : false} + | {resolved : true, + result : gb} + = {resolved : false}; + // this is a closure that talks to the popup window from this context + // it updates the_result when it gets something back from the user + let port_talker_toer_lambda = + function(port : browser.runtime.Port) { + // @ts-ignore bad type info in the typedefs + port.postMessage({title : title, + miscinfo : miscinfo, + timeout_ms : timeout_ms}); + + // oh my god + // nested lambdas + // i think we've reached peak js + let result_handler = + function(result_from_gb_popup_window : gb) { + // the message will either be good or bad + the_result = {resolved : true, + result : result_from_gb_popup_window}; + }; + // @ts-ignore types from github are wrong + port.onMessage.addListener(result_handler); + } + browser.runtime.onConnect.addListener(port_talker_toer_lambda); + // does the user want to sign the message let confirm_window = await browser.windows.create({url : '../pages/gb.html', type : 'popup'}); - console.log('509'); // @ts-ignore shut the fuck up - let tabid : number = confirm_window.tabs[0].id; - console.log('515'); - - function - the_function_that_runs_in_the_context_of_gb_dot_html - (gb_title : string, - gb_miscinfo : string, - gb_timeout_ms : number) - : string - { - // FIXME: not alerting user about bobs - alert('bobs!'); - //// the last evaluated statement of this function is the "return value" - //// as far as scripting.executeScript is concerned - //console.log('gb_title', gb_title); - //console.log('gb_miscinfo', gb_miscinfo); - //console.log('gb_timeout_ms', gb_timeout_ms); - - //document.getElementById('title-h1')!.innerHTML = gb_title; - - return 'good'; - } - - console.log('badness'); - // @ts-ignore i'm just assuming typescript is going to be stupid here i don't even know - let dialog_result: Array<{result: gb} | {error: any}> = - await browser.scripting.executeScript( - // @ts-ignore i'm just assuming typescript is going to be stupid here i don't even know - {func : the_function_that_runs_in_the_context_of_gb_dot_html, - args : [title, miscinfo, timeout_ms], - target : {tabId : tabid}, - // script just hangs forever without this line - // in no case does it alert user about bobs - // alright - // need a break - // when we get back, let's try a file - // otherwise we're going to have to try a totally different idiom - // maybe go back to some retarded message passing nonsense - injectImmediately: true - } - ); - - console.log('dialog_result', dialog_result[0]); - // @ts-ignore - if (dialog_result[0].error) { - // @ts-ignore - throw dialog_result.error; - } - else { - // @ts-ignore - return dialog_result[0].result; - } - + // let tabid : number = confirm_window.tabs[0].id; + return 'bad'; } - /** * Make the dumb address_subscribe thing *