rename run_window -> app_window

This commit is contained in:
Dmitry Vasilev
2023-07-11 18:24:28 +03:00
parent 0435367544
commit fc086e8c49
12 changed files with 70 additions and 66 deletions

View File

@@ -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 // js scripts
if(client == null) { 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 // window was closed
return new Response("", {status: 404}) return new Response("", {status: 404})
} else { } else {

View File

@@ -45,7 +45,7 @@ export const has_error = n =>
!n.ok !n.ok
|| ||
( (
n.value instanceof globalThis.run_window.Promise n.value instanceof globalThis.app_window.Promise
&& &&
n.value.status != null n.value.status != null
&& &&

View File

@@ -867,7 +867,7 @@ const create_file = (state, dir, current_module) => {
return {...load_dir(state, dir, true), 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 // After we reopen run window, we should reload external modules in the
// context of new window. Clear external_imports_cache // context of new window. Clear external_imports_cache
return run_code({ return run_code({
@@ -895,7 +895,7 @@ const get_initial_state = (state, entrypoint_settings) => {
export const COMMANDS = { export const COMMANDS = {
get_initial_state, get_initial_state,
input, input,
open_run_window, open_app_window,
load_dir, load_dir,
create_file, create_file,
step_into, step_into,

View File

@@ -5,7 +5,7 @@ import {
exec, exec,
get_state, get_state,
open_directory, open_directory,
reload_run_window, reload_app_window,
close_directory, close_directory,
} from '../index.js' } from '../index.js'
@@ -28,7 +28,7 @@ export class Files {
change_html_file(e) { change_html_file(e) {
const html_file = e.target.value const html_file = e.target.value
exec('change_html_file', html_file) exec('change_html_file', html_file)
reload_run_window(get_state()) reload_app_window(get_state())
} }

View File

@@ -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 {Editor} from './editor.js'
import {Files} from './files.js' import {Files} from './files.js'
import {CallTree} from './calltree.js' import {CallTree} from './calltree.js'
@@ -8,7 +8,7 @@ import {el} from './domutils.js'
export class UI { export class UI {
constructor(container, state){ 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) this.files = new Files(this)
@@ -90,9 +90,9 @@ export class UI {
el('a', { el('a', {
'class': 'statusbar_action', 'class': 'statusbar_action',
href: 'javascript: void(0)', 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', this.options = el('div', 'options',
@@ -160,7 +160,7 @@ export class UI {
} }
if(e.key == 'F7'){ if(e.key == 'F7'){
this.open_run_window() this.open_app_window()
} }
if(e.key == 'F8'){ if(e.key == 'F8'){
@@ -210,8 +210,8 @@ export class UI {
} }
} }
open_run_window() { open_app_window() {
open_run_window(get_state()) open_app_window(get_state())
} }
render_debugger_loading(state) { render_debugger_loading(state) {

View File

@@ -8,27 +8,27 @@ import {el, stringify, scrollIntoViewIfNeeded} from './domutils.js'
import {with_code_execution} from '../index.js' import {with_code_execution} from '../index.js'
// We test both for Object and globalThis.run_window.Object because objects may // We test both for Object and globalThis.app_window.Object because objects may
// come both from run_window and current window (where they are created in // come both from app_window and current window (where they are created in
// metacircular interpreter // metacircular interpreter
const has_custom_toString = object => const has_custom_toString = object =>
object.toString != null object.toString != null
&& object.toString != globalThis.run_window.Object.prototype.toString && object.toString != globalThis.app_window.Object.prototype.toString
&& object.toString != Object.prototype.toString && object.toString != Object.prototype.toString
const isError = object => const isError = object =>
object instanceof Error object instanceof Error
|| ||
object instanceof globalThis.run_window.Error object instanceof globalThis.app_window.Error
const isPromise = object => const isPromise = object =>
object instanceof globalThis.run_window.Promise object instanceof globalThis.app_window.Promise
// Override behaviour for Date, becase Date has toJSON defined // Override behaviour for Date, becase Date has toJSON defined
const isDate = object => 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 => { const toJSON_safe = object => {
try { try {

8
src/effects.js vendored
View File

@@ -9,10 +9,10 @@ import {
import {current_cursor_position} from './calltree.js' import {current_cursor_position} from './calltree.js'
import {exec, FILES_ROOT} from './index.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 // modules refer to that window's context
const import_in_run_window = url => { const import_in_app_window = url => {
return new globalThis.run_window.Function('url', ` return new globalThis.app_window.Function('url', `
return import(url) return import(url)
`)(url) `)(url)
} }
@@ -23,7 +23,7 @@ const load_external_imports = async state => {
} }
const urls = state.loading_external_imports_state.external_imports const urls = state.loading_external_imports_state.external_imports
const results = await Promise.allSettled( const results = await Promise.allSettled(
urls.map(u => import_in_run_window( urls.map(u => import_in_app_window(
/^\w+:\/\//.test(u) /^\w+:\/\//.test(u)
? // starts with protocol, import as is ? // starts with protocol, import as is
u u

View File

@@ -304,8 +304,8 @@ export const eval_modules = (
const is_async = has_toplevel_await(parse_result.modules) const is_async = has_toplevel_await(parse_result.modules)
const Function = is_async const Function = is_async
? globalThis.run_window.eval('(async function(){})').constructor ? globalThis.app_window.eval('(async function(){})').constructor
: globalThis.run_window.Function : globalThis.app_window.Function
const module_fns = parse_result.sorted.map(module => ( const module_fns = parse_result.sorted.map(module => (
{ {
@@ -347,7 +347,7 @@ export const eval_modules = (
calltree_changed_token, calltree_changed_token,
is_toplevel_call: true, is_toplevel_call: true,
window: globalThis.run_window, window: globalThis.app_window,
} }
const result = run(module_fns, cxt, io_trace) const result = run(module_fns, cxt, io_trace)
@@ -435,8 +435,8 @@ account
// Workaround with statement forbidden in strict mode (imposed by ES6 modules) // Workaround with statement forbidden in strict mode (imposed by ES6 modules)
// Also currently try/catch is not implemented TODO // Also currently try/catch is not implemented TODO
export const eval_codestring = (codestring, scope) => export const eval_codestring = (codestring, scope) =>
// Note that we eval code in context of run_window // Note that we eval code in context of app_window
(new (globalThis.run_window.Function)('codestring', 'scope', (new (globalThis.app_window.Function)('codestring', 'scope',
// Make a copy of `scope` to not mutate it with assignments // Make a copy of `scope` to not mutate it with assignments
` `
try { try {
@@ -585,6 +585,10 @@ const do_eval_frame_expr = (node, scope, callsleft, context) => {
return {ok: false, children, calls} return {ok: false, children, calls}
} else { } else {
if(typeof(children[0].result.value) != 'function') { 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 { return {
ok: false, ok: false,
error: context.calltree_node.error, error: context.calltree_node.error,
@@ -688,7 +692,7 @@ const do_eval_frame_expr = (node, scope, callsleft, context) => {
ok = true ok = true
value = - expr.result.value value = - expr.result.value
} else if(node.operator == 'await') { } 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 const status = expr.result.value.status
if(status == null) { if(status == null) {
// Promise must be already resolved // Promise must be already resolved

View File

@@ -65,7 +65,7 @@ const load_persisted_directory_handle = () => {
.then(() => navigator.serviceWorker.ready) .then(() => navigator.serviceWorker.ready)
/* /*
Main window also provides dir_handle to service worker, together with 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 issues fetch event. If clientId is '' then service worker will try to get
dir_handle from main window dir_handle from main window
*/ */

View File

@@ -47,7 +47,7 @@ const get_html_url = state => {
const on_window_load = w => { const on_window_load = w => {
init_window_service_worker(w) init_window_service_worker(w)
exec( exec(
'open_run_window', 'open_app_window',
new Set(Object.getOwnPropertyNames(w)) new Set(Object.getOwnPropertyNames(w))
) )
} }
@@ -61,24 +61,24 @@ const open_run_iframe = (state) => {
iframe.src = get_html_url(state) iframe.src = get_html_url(state)
iframe.setAttribute('hidden', '') iframe.setAttribute('hidden', '')
document.body.appendChild(iframe) 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 // promises in user code is normal condition
set_error_handler(iframe.contentWindow, false) set_error_handler(iframe.contentWindow, false)
globalThis.run_window = iframe.contentWindow globalThis.app_window = iframe.contentWindow
init_run_window(globalThis.run_window) init_app_window(globalThis.app_window)
} }
// Open another browser window so user can interact with application // Open another browser window so user can interact with application
// TODO test in another browsers // 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 // TODO set_error_handler? Or we dont need to set_error_handler for child
// window because error is always caught by parent window handler? // window because error is always caught by parent window handler?
globalThis.run_window.close() globalThis.app_window.close()
globalThis.run_window = open(get_html_url(state)) globalThis.app_window = open(get_html_url(state))
init_run_window(globalThis.run_window) init_app_window(globalThis.app_window)
} }
const init_run_window = w => { const init_app_window = w => {
const is_loaded = () => { const is_loaded = () => {
const nav = w.performance.getEntriesByType("navigation")[0] 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 // Set timeout to 100ms because it takes some time for page to get closed
// after triggering 'unload' event // after triggering 'unload' event
setTimeout(() => { 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 // If by that time w.closed was set to true, then page was
// closed. Get back to using iframe // closed. Get back to using iframe
globalThis.run_window = iframe.contentWindow globalThis.app_window = iframe.contentWindow
reload_run_window(get_state()) reload_app_window(get_state())
} else { } else {
add_load_handler() add_load_handler()
} }
@@ -134,11 +134,11 @@ const init_run_window = w => {
add_load_handler() add_load_handler()
} }
export const reload_run_window = state => { export const reload_app_window = state => {
// TODO after window location reload, open_run_window command will be fired. // TODO after window location reload, open_app_window command will be fired.
// Maybe we should have separate commands for open_run_window and // Maybe we should have separate commands for open_app_window and
// reload_run_window? // reload_app_window?
globalThis.run_window.location = get_html_url(state) globalThis.app_window.location = get_html_url(state)
} }

View File

@@ -10,7 +10,7 @@ export const set_current_context = _cxt => {
// When we develop leporello.js inside itself, patches may be applied twice, // When we develop leporello.js inside itself, patches may be applied twice,
// once for host leporello, and another for leporello under development. This // once for host leporello, and another for leporello under development. This
// module would be loaded twice, once from host window, another time from // 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 // patches twice
if(cxt.window.__io_patched_by == null) { if(cxt.window.__io_patched_by == null) {
cxt.window.__io_patched_by = new Set() 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 // originate from another window (if window was reopened after record
// trace) and instanceof would not work // trace) and instanceof would not work
if(call.value?.[Symbol.toStringTag] == 'Promise') { 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 => { return new cxt.window.Promise(resolve => {
cxt.io_trace_resolvers.set(cxt.io_trace_index - 1, resolve) cxt.io_trace_resolvers.set(cxt.io_trace_index - 1, resolve)
}) })

View File

@@ -9,20 +9,20 @@ Object.assign(globalThis,
// for convenince, to type just `log` instead of `console.log` // for convenince, to type just `log` instead of `console.log`
log: console.log, log: console.log,
// For test env, set globalThis.run_window to just globalThis // For test env, set globalThis.app_window to just globalThis
run_window: globalThis, app_window: globalThis,
} }
) )
export const patch_builtin = new Function(` export const patch_builtin = new Function(`
let originals = globalThis.run_window.__builtins_originals let originals = globalThis.app_window.__builtins_originals
let patched = globalThis.run_window.__builtins_patched let patched = globalThis.app_window.__builtins_patched
if(originals == null) { 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. // This code can execute twice when tests are run in self-hosted mode.
// Ensure that patches will be applied only once // Ensure that patches will be applied only once
originals = globalThis.run_window.__builtins_originals = {} originals = globalThis.app_window.__builtins_originals = {}
patched = globalThis.run_window.__builtins_patched = {} patched = globalThis.app_window.__builtins_patched = {}
const patch = (obj, name) => { const patch = (obj, name) => {
originals[name] = 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 // Substitute some builtin functions: fetch, setTimeout, Math.random to be
// able to patch them in tests // able to patch them in tests
patch(globalThis.run_window, 'fetch') patch(globalThis.app_window, 'fetch')
patch(globalThis.run_window, 'setTimeout') patch(globalThis.app_window, 'setTimeout')
patch(globalThis.run_window.Math, 'random') patch(globalThis.app_window.Math, 'random')
} }
return (name, fn) => { 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( export const do_parse = code => parse(
code, code,
new Set(Object.getOwnPropertyNames(globalThis.run_window)) new Set(Object.getOwnPropertyNames(globalThis.app_window))
) )
export const parse_modules = (entry, modules) => export const parse_modules = (entry, modules) =>
load_modules( load_modules(
entry, entry,
module_name => modules[module_name], module_name => modules[module_name],
new Set(Object.getOwnPropertyNames(globalThis.run_window)) new Set(Object.getOwnPropertyNames(globalThis.app_window))
) )
export const eval_tree = code => { 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) => { export const test_initial_state = (code, entrypoint_settings, other) => {
return COMMANDS.open_run_window( return COMMANDS.open_app_window(
COMMANDS.get_initial_state( COMMANDS.get_initial_state(
{ {
files: typeof(code) == 'object' ? code : { '' : code}, files: typeof(code) == 'object' ? code : { '' : code},
@@ -115,7 +115,7 @@ export const test_initial_state = (code, entrypoint_settings, other) => {
...entrypoint_settings, ...entrypoint_settings,
} }
), ),
new Set(Object.getOwnPropertyNames(globalThis.run_window)) new Set(Object.getOwnPropertyNames(globalThis.app_window))
) )
} }