From ffec3e3cc239251a6deae75ce9b4ecf3b13555f2 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilev Date: Mon, 28 Nov 2022 20:53:35 +0800 Subject: [PATCH] select html file --- index.html | 1 + src/cmd.js | 6 +++++- src/editor/ui.js | 43 ++++++++++++++++++++++++++++++++++++++----- src/effects.js | 15 ++++++++++++++- src/index.js | 33 +++++++++++++++++++++++---------- 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index 676980a..00ea511 100644 --- a/index.html +++ b/index.html @@ -177,6 +177,7 @@ .entrypoint_title { margin-right: 0.5em; + margin-left: 1.5em; } .callnode { diff --git a/src/cmd.js b/src/cmd.js index 1ccf219..67d8894 100644 --- a/src/cmd.js +++ b/src/cmd.js @@ -506,6 +506,10 @@ const change_entrypoint = (state, entrypoint, index) => { ) } +const change_html_file = (state, html_file) => { + return {...state, html_file} +} + const goto_definition = (state, index) => { if(!state.parse_result.ok){ return {state, effects: {type: 'set_status', args: ['unresolved syntax errors']}} @@ -766,7 +770,6 @@ const load_dir = (state, dir) => { parse_result: null, project_dir: dir, files: {...files, ...state.files}, - }) } @@ -815,6 +818,7 @@ export const COMMANDS = { step_into, change_current_module, change_entrypoint, + change_html_file, goto_definition, goto_problem, move_cursor, diff --git a/src/editor/ui.js b/src/editor/ui.js index af6a7cb..876968b 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_run_window, reload_run_window} from '../index.js' import {Editor} from './editor.js' import {Files} from './files.js' import {CallTree} from './calltree.js' @@ -10,6 +10,8 @@ import {FLAGS} from '../feature_flags.js' export class UI { constructor(container, state){ this.change_entrypoint = this.change_entrypoint.bind(this) + this.change_html_file = this.change_html_file.bind(this) + this.open_run_window = this.open_run_window.bind(this) this.files = new Files(this) @@ -71,7 +73,7 @@ export class UI { el('a', { 'class': 'open_run_window', href: 'javascript: void(0)', - click: open_run_window, + click: this.open_run_window, }, '(Re)open run window (F6)' ), @@ -137,7 +139,7 @@ export class UI { } if(e.key == 'F6'){ - open_run_window() + this.open_run_window() } }) @@ -190,7 +192,7 @@ export class UI { render_entrypoint_select(state) { this.entrypoint_select.replaceChildren( - el('span', 'entrypoint_title', 'entrypoint'), + el('span', 'entrypoint_title', 'js entrypoint'), el('select', { click: e => e.stopPropagation(), change: this.change_entrypoint, @@ -207,10 +209,35 @@ export class UI { f == '' ? "*scratch*" : f ) ) - ) + ), + el('span', 'entrypoint_title', 'html page'), + el('select', { + click: e => e.stopPropagation(), + change: this.change_html_file, + }, + [''] + .concat( + Object + .keys(state.files) + .sort() + .filter(f => f.endsWith('.htm') || f.endsWith('.html')) + ) + .map(f => + el('option', + state.html_file == f + ? { value: f, selected: true } + : { value: f}, + f == '' ? 'abount:blank' : f + ) + ) + ), ) } + open_run_window() { + open_run_window(get_state()) + } + change_entrypoint(e) { const file = e.target.value const index = this.editor.get_caret_position(file) @@ -221,6 +248,12 @@ export class UI { this.editor.focus() } + change_html_file(e) { + const html_file = e.target.value + exec('change_html_file', html_file) + reload_run_window(get_state()) + } + render_debugger(state) { this.debugger_container.style = '' this.problems_container.style = 'display: none' diff --git a/src/effects.js b/src/effects.js index e414a04..c9f4fae 100644 --- a/src/effects.js +++ b/src/effects.js @@ -136,10 +136,19 @@ export const render_common_side_effects = (prev, next, command, ui) => { || prev.current_module != next.current_module ) { - ui.render_entrypoint_select(next) ui.files.render(next) } + if( + prev.project_dir != next.project_dir + || + prev.entrypoint != next.entrypoint + || + prev.html_file != next.html_file + ) { + ui.render_entrypoint_select(next) + } + if(prev.current_module != next.current_module) { localStorage.current_module = next.current_module ui.render_current_module(next.current_module) @@ -149,6 +158,10 @@ export const render_common_side_effects = (prev, next, command, ui) => { localStorage.entrypoint = next.entrypoint } + if(prev.html_file != next.html_file) { + localStorage.html_file = next.html_file + } + if(prev.current_module != next.current_module) { ensure_session(ui, next) ui.editor.unembed_value_explorer() diff --git a/src/index.js b/src/index.js index 4db5226..6738dda 100644 --- a/src/index.js +++ b/src/index.js @@ -18,25 +18,29 @@ const set_error_handler = w => { }) } +const get_html_url = state => { + return state.html_file == '' + ? 'about:blank' + : window.location.origin + '/' + state.html_file + '?leporello' +} + // By default run code in hidden iframe, until user explicitly opens visible // window -globalThis.run_window = (() => { +const open_run_iframe = state => { const iframe = document.createElement('iframe') - //iframe.src = 'about:blank' - iframe.src = '/index.html?leporello' + iframe.src = get_html_url(state) iframe.setAttribute('hidden', '') document.body.appendChild(iframe) set_error_handler(iframe.contentWindow) - return iframe.contentWindow -})() + globalThis.run_window = iframe.contentWindow +} // Open another browser window so user can interact with application // TODO test in another browsers -export const open_run_window = () => { +export const open_run_window = state => { globalThis.run_window.close() - //const next_window = open('about:blank') - const next_window = globalThis.run_window = open('/index.html?leporello') + const next_window = globalThis.run_window = open(get_html_url(state)) const is_loaded = () => { const nav = next_window.performance.getEntriesByType("navigation")[0] @@ -85,9 +89,7 @@ export const open_run_window = () => { // If by that time next_window.closed was set to true, then page was // closed // TODO get back to iframe? - console.log("CLOSED") } else { - console.log("REFRESHED") add_load_handler() } }, 100) @@ -97,12 +99,20 @@ export const open_run_window = () => { 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) +} + const read_modules = async () => { const default_module = {'': localStorage.code || EXAMPLE} const current = { // TODO fix when there are no such modules anymore current_module: localStorage.current_module ?? '', entrypoint: localStorage.entrypoint ?? '', + html_file: localStorage.html_file ?? '', } const project_dir = await load_dir(false) if(project_dir == null) { @@ -130,6 +140,9 @@ export const init = (container, _COMMANDS) => { set_error_handler(window) read_modules().then(initial_state => { + + open_run_iframe(initial_state) + state = COMMANDS.get_initial_state({ ...initial_state, on_async_call: (...args) => exec('on_async_call', ...args)