From fc086e8c4908e4b3c9e0765c1d169eed3ab85815 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilev Date: Tue, 11 Jul 2023 18:24:28 +0300 Subject: [PATCH] rename run_window -> app_window --- service_worker.js | 4 ++-- src/calltree.js | 2 +- src/cmd.js | 4 ++-- src/editor/files.js | 4 ++-- src/editor/ui.js | 14 +++++++------- src/editor/value_explorer.js | 14 +++++++------- src/effects.js | 8 ++++---- src/eval.js | 16 ++++++++++------ src/filesystem.js | 2 +- src/index.js | 34 +++++++++++++++++----------------- src/record_io.js | 4 ++-- test/utils.js | 30 +++++++++++++++--------------- 12 files changed, 70 insertions(+), 66 deletions(-) diff --git a/service_worker.js b/service_worker.js index d826c6d..9c204fd 100644 --- a/service_worker.js +++ b/service_worker.js @@ -66,10 +66,10 @@ const serve_response_from_dir = async event => { } - // client is null for run_window initial page load, and is run_window for + // client is null for app_window initial page load, and is app_window for // js scripts if(client == null) { - // User probably reloaded run_window by manually hitting F5 after IDE + // User probably reloaded app_window by manually hitting F5 after IDE // window was closed return new Response("", {status: 404}) } else { diff --git a/src/calltree.js b/src/calltree.js index 9ec8215..d66da32 100644 --- a/src/calltree.js +++ b/src/calltree.js @@ -45,7 +45,7 @@ export const has_error = n => !n.ok || ( - n.value instanceof globalThis.run_window.Promise + n.value instanceof globalThis.app_window.Promise && n.value.status != null && diff --git a/src/cmd.js b/src/cmd.js index 57d4284..cc47ffb 100644 --- a/src/cmd.js +++ b/src/cmd.js @@ -867,7 +867,7 @@ const create_file = (state, dir, current_module) => { return {...load_dir(state, dir, true), current_module} } -const open_run_window = (state, globals) => { +const open_app_window = (state, globals) => { // After we reopen run window, we should reload external modules in the // context of new window. Clear external_imports_cache return run_code({ @@ -895,7 +895,7 @@ const get_initial_state = (state, entrypoint_settings) => { export const COMMANDS = { get_initial_state, input, - open_run_window, + open_app_window, load_dir, create_file, step_into, diff --git a/src/editor/files.js b/src/editor/files.js index 3fe0c79..c071254 100644 --- a/src/editor/files.js +++ b/src/editor/files.js @@ -5,7 +5,7 @@ import { exec, get_state, open_directory, - reload_run_window, + reload_app_window, close_directory, } from '../index.js' @@ -28,7 +28,7 @@ export class Files { change_html_file(e) { const html_file = e.target.value exec('change_html_file', html_file) - reload_run_window(get_state()) + reload_app_window(get_state()) } diff --git a/src/editor/ui.js b/src/editor/ui.js index e8c38ec..9547c0c 100644 --- a/src/editor/ui.js +++ b/src/editor/ui.js @@ -1,4 +1,4 @@ -import {exec, get_state, open_run_window} from '../index.js' +import {exec, get_state, open_app_window} from '../index.js' import {Editor} from './editor.js' import {Files} from './files.js' import {CallTree} from './calltree.js' @@ -8,7 +8,7 @@ import {el} from './domutils.js' export class UI { constructor(container, state){ - this.open_run_window = this.open_run_window.bind(this) + this.open_app_window = this.open_app_window.bind(this) this.files = new Files(this) @@ -90,9 +90,9 @@ export class UI { el('a', { 'class': 'statusbar_action', href: 'javascript: void(0)', - click: this.open_run_window, + click: this.open_app_window, }, - '(Re)open run window (F7)' + '(Re)open app window (F7)' ), this.options = el('div', 'options', @@ -160,7 +160,7 @@ export class UI { } if(e.key == 'F7'){ - this.open_run_window() + this.open_app_window() } if(e.key == 'F8'){ @@ -210,8 +210,8 @@ export class UI { } } - open_run_window() { - open_run_window(get_state()) + open_app_window() { + open_app_window(get_state()) } render_debugger_loading(state) { diff --git a/src/editor/value_explorer.js b/src/editor/value_explorer.js index e31c474..9b038ce 100644 --- a/src/editor/value_explorer.js +++ b/src/editor/value_explorer.js @@ -8,27 +8,27 @@ import {el, stringify, scrollIntoViewIfNeeded} from './domutils.js' import {with_code_execution} from '../index.js' -// We test both for Object and globalThis.run_window.Object because objects may -// come both from run_window and current window (where they are created in +// We test both for Object and globalThis.app_window.Object because objects may +// come both from app_window and current window (where they are created in // metacircular interpreter const has_custom_toString = object => object.toString != null - && object.toString != globalThis.run_window.Object.prototype.toString + && object.toString != globalThis.app_window.Object.prototype.toString && object.toString != Object.prototype.toString const isError = object => object instanceof Error || - object instanceof globalThis.run_window.Error + object instanceof globalThis.app_window.Error const isPromise = object => - object instanceof globalThis.run_window.Promise + object instanceof globalThis.app_window.Promise // Override behaviour for Date, becase Date has toJSON defined const isDate = object => - object instanceof globalThis.run_window.Date + object instanceof globalThis.app_window.Date || - object instanceof globalThis.run_window.Date.__original + object instanceof globalThis.app_window.Date.__original const toJSON_safe = object => { try { diff --git a/src/effects.js b/src/effects.js index 531d9d5..ff92eba 100644 --- a/src/effects.js +++ b/src/effects.js @@ -9,10 +9,10 @@ import { import {current_cursor_position} from './calltree.js' import {exec, FILES_ROOT} from './index.js' -// Imports in the context of `run_window`, so global variables in loaded +// Imports in the context of `app_window`, so global variables in loaded // modules refer to that window's context -const import_in_run_window = url => { - return new globalThis.run_window.Function('url', ` +const import_in_app_window = url => { + return new globalThis.app_window.Function('url', ` return import(url) `)(url) } @@ -23,7 +23,7 @@ const load_external_imports = async state => { } const urls = state.loading_external_imports_state.external_imports const results = await Promise.allSettled( - urls.map(u => import_in_run_window( + urls.map(u => import_in_app_window( /^\w+:\/\//.test(u) ? // starts with protocol, import as is u diff --git a/src/eval.js b/src/eval.js index 76ab8c8..6adedc9 100644 --- a/src/eval.js +++ b/src/eval.js @@ -304,8 +304,8 @@ export const eval_modules = ( const is_async = has_toplevel_await(parse_result.modules) const Function = is_async - ? globalThis.run_window.eval('(async function(){})').constructor - : globalThis.run_window.Function + ? globalThis.app_window.eval('(async function(){})').constructor + : globalThis.app_window.Function const module_fns = parse_result.sorted.map(module => ( { @@ -347,7 +347,7 @@ export const eval_modules = ( calltree_changed_token, is_toplevel_call: true, - window: globalThis.run_window, + window: globalThis.app_window, } const result = run(module_fns, cxt, io_trace) @@ -435,8 +435,8 @@ account // Workaround with statement forbidden in strict mode (imposed by ES6 modules) // Also currently try/catch is not implemented TODO export const eval_codestring = (codestring, scope) => - // Note that we eval code in context of run_window - (new (globalThis.run_window.Function)('codestring', 'scope', + // Note that we eval code in context of app_window + (new (globalThis.app_window.Function)('codestring', 'scope', // Make a copy of `scope` to not mutate it with assignments ` try { @@ -585,6 +585,10 @@ const do_eval_frame_expr = (node, scope, callsleft, context) => { return {ok: false, children, calls} } else { if(typeof(children[0].result.value) != 'function') { + const is_promise_error = ( + context.calltree_node.ok && + (context.calltree_node.value instanceof globalThis.app_window.Promise) + ) return { ok: false, error: context.calltree_node.error, @@ -688,7 +692,7 @@ const do_eval_frame_expr = (node, scope, callsleft, context) => { ok = true value = - expr.result.value } else if(node.operator == 'await') { - if(expr.result.value instanceof globalThis.run_window.Promise) { + if(expr.result.value instanceof globalThis.app_window.Promise) { const status = expr.result.value.status if(status == null) { // Promise must be already resolved diff --git a/src/filesystem.js b/src/filesystem.js index b865620..2f9e0b0 100644 --- a/src/filesystem.js +++ b/src/filesystem.js @@ -65,7 +65,7 @@ const load_persisted_directory_handle = () => { .then(() => navigator.serviceWorker.ready) /* Main window also provides dir_handle to service worker, together with - run_window. run_window provides dir_handle to service worker when it + app_window. app_window provides dir_handle to service worker when it issues fetch event. If clientId is '' then service worker will try to get dir_handle from main window */ diff --git a/src/index.js b/src/index.js index 89f3b7c..6d50cf9 100644 --- a/src/index.js +++ b/src/index.js @@ -47,7 +47,7 @@ const get_html_url = state => { const on_window_load = w => { init_window_service_worker(w) exec( - 'open_run_window', + 'open_app_window', new Set(Object.getOwnPropertyNames(w)) ) } @@ -61,24 +61,24 @@ const open_run_iframe = (state) => { iframe.src = get_html_url(state) iframe.setAttribute('hidden', '') document.body.appendChild(iframe) - // for run_window, do not set unhandled rejection, because having rejected + // for app_window, do not set unhandled rejection, because having rejected // promises in user code is normal condition set_error_handler(iframe.contentWindow, false) - globalThis.run_window = iframe.contentWindow - init_run_window(globalThis.run_window) + globalThis.app_window = iframe.contentWindow + init_app_window(globalThis.app_window) } // Open another browser window so user can interact with application // TODO test in another browsers -export const open_run_window = state => { +export const open_app_window = state => { // TODO set_error_handler? Or we dont need to set_error_handler for child // window because error is always caught by parent window handler? - globalThis.run_window.close() - globalThis.run_window = open(get_html_url(state)) - init_run_window(globalThis.run_window) + globalThis.app_window.close() + globalThis.app_window = open(get_html_url(state)) + init_app_window(globalThis.app_window) } -const init_run_window = w => { +const init_app_window = w => { const is_loaded = () => { const nav = w.performance.getEntriesByType("navigation")[0] @@ -119,11 +119,11 @@ const init_run_window = w => { // Set timeout to 100ms because it takes some time for page to get closed // after triggering 'unload' event setTimeout(() => { - if(w.closed && w == globalThis.run_window) { + if(w.closed && w == globalThis.app_window) { // If by that time w.closed was set to true, then page was // closed. Get back to using iframe - globalThis.run_window = iframe.contentWindow - reload_run_window(get_state()) + globalThis.app_window = iframe.contentWindow + reload_app_window(get_state()) } else { add_load_handler() } @@ -134,11 +134,11 @@ const init_run_window = w => { add_load_handler() } -export const reload_run_window = state => { - // TODO after window location reload, open_run_window command will be fired. - // Maybe we should have separate commands for open_run_window and - // reload_run_window? - globalThis.run_window.location = get_html_url(state) +export const reload_app_window = state => { + // TODO after window location reload, open_app_window command will be fired. + // Maybe we should have separate commands for open_app_window and + // reload_app_window? + globalThis.app_window.location = get_html_url(state) } diff --git a/src/record_io.js b/src/record_io.js index ca3144c..ed208e1 100644 --- a/src/record_io.js +++ b/src/record_io.js @@ -10,7 +10,7 @@ export const set_current_context = _cxt => { // When we develop leporello.js inside itself, patches may be applied twice, // once for host leporello, and another for leporello under development. This // module would be loaded twice, once from host window, another time from - // run_window. Every module will have its own 'label', so we can apply + // app_window. Every module will have its own 'label', so we can apply // patches twice if(cxt.window.__io_patched_by == null) { cxt.window.__io_patched_by = new Set() @@ -213,7 +213,7 @@ const make_patched_method = (original, name, use_context) => { // originate from another window (if window was reopened after record // trace) and instanceof would not work if(call.value?.[Symbol.toStringTag] == 'Promise') { - // Always make promise originate from run_window + // Always make promise originate from app_window return new cxt.window.Promise(resolve => { cxt.io_trace_resolvers.set(cxt.io_trace_index - 1, resolve) }) diff --git a/test/utils.js b/test/utils.js index 61da4b5..527b232 100644 --- a/test/utils.js +++ b/test/utils.js @@ -9,20 +9,20 @@ Object.assign(globalThis, // for convenince, to type just `log` instead of `console.log` log: console.log, - // For test env, set globalThis.run_window to just globalThis - run_window: globalThis, + // For test env, set globalThis.app_window to just globalThis + app_window: globalThis, } ) export const patch_builtin = new Function(` - let originals = globalThis.run_window.__builtins_originals - let patched = globalThis.run_window.__builtins_patched + let originals = globalThis.app_window.__builtins_originals + let patched = globalThis.app_window.__builtins_patched if(originals == null) { - globalThis.run_window.__original_setTimeout = globalThis.setTimeout + globalThis.app_window.__original_setTimeout = globalThis.setTimeout // This code can execute twice when tests are run in self-hosted mode. // Ensure that patches will be applied only once - originals = globalThis.run_window.__builtins_originals = {} - patched = globalThis.run_window.__builtins_patched = {} + originals = globalThis.app_window.__builtins_originals = {} + patched = globalThis.app_window.__builtins_patched = {} const patch = (obj, name) => { originals[name] = obj[name] @@ -35,9 +35,9 @@ export const patch_builtin = new Function(` // Substitute some builtin functions: fetch, setTimeout, Math.random to be // able to patch them in tests - patch(globalThis.run_window, 'fetch') - patch(globalThis.run_window, 'setTimeout') - patch(globalThis.run_window.Math, 'random') + patch(globalThis.app_window, 'fetch') + patch(globalThis.app_window, 'setTimeout') + patch(globalThis.app_window.Math, 'random') } return (name, fn) => { @@ -45,18 +45,18 @@ export const patch_builtin = new Function(` } `)() -export const original_setTimeout = globalThis.run_window.__original_setTimeout +export const original_setTimeout = globalThis.app_window.__original_setTimeout export const do_parse = code => parse( code, - new Set(Object.getOwnPropertyNames(globalThis.run_window)) + new Set(Object.getOwnPropertyNames(globalThis.app_window)) ) export const parse_modules = (entry, modules) => load_modules( entry, module_name => modules[module_name], - new Set(Object.getOwnPropertyNames(globalThis.run_window)) + new Set(Object.getOwnPropertyNames(globalThis.app_window)) ) export const eval_tree = code => { @@ -103,7 +103,7 @@ export const assert_code_error_async = async (codestring, error) => { } export const test_initial_state = (code, entrypoint_settings, other) => { - return COMMANDS.open_run_window( + return COMMANDS.open_app_window( COMMANDS.get_initial_state( { files: typeof(code) == 'object' ? code : { '' : code}, @@ -115,7 +115,7 @@ export const test_initial_state = (code, entrypoint_settings, other) => { ...entrypoint_settings, } ), - new Set(Object.getOwnPropertyNames(globalThis.run_window)) + new Set(Object.getOwnPropertyNames(globalThis.app_window)) ) }