diff --git a/content/tutorial/common/src/__client.js b/content/tutorial/common/src/__client.js index e9bca1cbb..51033a8cd 100644 --- a/content/tutorial/common/src/__client.js +++ b/content/tutorial/common/src/__client.js @@ -63,6 +63,15 @@ window.addEventListener('message', async (e) => { } }); +window.addEventListener('pointerdown', () => { + parent.postMessage( + { + type: 'pointerdown' + }, + '*' + ); +}); + function ping() { parent.postMessage( { @@ -89,18 +98,3 @@ if (import.meta.hot) { ); }); } - -/** - * The iframe sometimes takes focus control in ways we can't prevent - * while the editor is focussed. Refocus the editor in these cases. - */ -window.addEventListener('focusin', (e) => { - if (e.target.tagName === 'BODY') { - parent.postMessage( - { - type: 'focus_on_editor' - }, - '*' - ); - } -}); diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index 617052341..aeb9c6c18 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -11,7 +11,7 @@ import ImageViewer from './ImageViewer.svelte'; import ScreenToggle from './ScreenToggle.svelte'; import Sidebar from './Sidebar.svelte'; - import { state, selected, completed } from './state'; + import { state, selected, completed } from './state.js'; /** @type {import('./$types').PageData} */ export let data; @@ -160,20 +160,6 @@ flex-direction: column; } - iframe { - width: 100%; - height: 100%; - flex: 1; - resize: none; - box-sizing: border-box; - border: none; - background: var(--sk-back-2); - } - - iframe:not(.loaded) { - display: none; - } - .editor-container { position: relative; background-color: var(--sk-back-3); diff --git a/src/routes/tutorial/[slug]/Editor.svelte b/src/routes/tutorial/[slug]/Editor.svelte index e30ede38f..97e08b504 100644 --- a/src/routes/tutorial/[slug]/Editor.svelte +++ b/src/routes/tutorial/[slug]/Editor.svelte @@ -30,14 +30,7 @@ let w = 0; let h = 0; - /** - * The iframe sometimes takes focus control in ways we can't prevent - * while the editor is focussed. Refocus the editor in these cases. - * This boolean tracks whether or not the editor should be refocused. - */ - let preserve_focus = true; - /** @type {any} */ - let remove_focus_timeout; + let preserve_editor_focus = false; onMount(() => { let destroyed = false; @@ -238,9 +231,15 @@ { + console.log(`pointerdown ${container.contains(e.target)}`); + if (!container.contains(/** @type {HTMLElement} */ (e.target))) { + preserve_editor_focus = false; + } + }} on:message={(e) => { - if (preserve_focus && e.data.type === 'focus_on_editor') { - instance?.editor.focus(); + if (e.data.type === 'pointerdown') { + preserve_editor_focus = false; } }} /> @@ -248,17 +247,24 @@
{ + if (e.key === 'Tab') { + preserve_editor_focus = false; + + setTimeout(() => { + preserve_editor_focus = true; + }, 100); + } + }} on:focusin={() => { - clearTimeout(remove_focus_timeout); - preserve_focus = true; + preserve_editor_focus = true; }} on:focusout={() => { - // Heuristic: user did refocus themmselves if focus_on_editor - // doesn't happen in the next few miliseconds. Needed - // because else navigations inside the iframe refocus the editor. - remove_focus_timeout = setTimeout(() => { - preserve_focus = false; - }, 500); + if (preserve_editor_focus) { + setTimeout(() => { + instance?.editor.focus(); + }, 0); + } }} />
diff --git a/src/routes/tutorial/[slug]/Output.svelte b/src/routes/tutorial/[slug]/Output.svelte index e566260a7..9baf9aa70 100644 --- a/src/routes/tutorial/[slug]/Output.svelte +++ b/src/routes/tutorial/[slug]/Output.svelte @@ -5,7 +5,7 @@ import Chrome from './Chrome.svelte'; import Loading from './Loading.svelte'; import { create_adapter } from './adapter'; - import { state } from './state'; + import { state } from './state.js'; /** @type {string} */ export let path;