mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
rename run_window -> app_window
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
&&
|
&&
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
8
src/effects.js
vendored
@@ -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
|
||||||
|
|||||||
16
src/eval.js
16
src/eval.js
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
34
src/index.js
34
src/index.js
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user