Skip to content

Commit 417770a

Browse files
committed
fix: better iframe navigation
- uses postMessage to trigger the inner SvelteKit's goto method - monkeypatches iframe's history.pushState to use replaceState instead to not create history entries, keeping the parent window's navigation order intact
1 parent 46dda23 commit 417770a

File tree

2 files changed

+16
-48
lines changed

2 files changed

+16
-48
lines changed

content/tutorial/common/src/__client.js

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,22 @@ window.alert = (message) => {
1515
};
1616

1717
window.addEventListener('message', async (e) => {
18-
if (e.data.type === 'fetch') {
19-
const names = e.data.names;
20-
21-
const transformed = await Promise.all(
22-
names.map(async (name) => {
23-
const res = await fetch(name);
24-
return {
25-
name,
26-
code: await res.text()
27-
};
28-
})
29-
);
30-
31-
const css_files = [];
32-
33-
for (const { name, code } of transformed) {
34-
if (
35-
name.endsWith('.svelte') &&
36-
code.includes('svelte&type=style&lang.css')
37-
) {
38-
css_files.push(name + '?svelte&type=style&lang.css');
39-
}
40-
}
41-
42-
if (css_files.length > 0) {
43-
const css_transformed = await Promise.all(
44-
css_files.map(async (name) => {
45-
const res = await fetch(name);
46-
return {
47-
name,
48-
code: await res.text()
49-
};
50-
})
51-
);
52-
53-
transformed.push(...css_transformed);
54-
}
55-
56-
parent.postMessage(
57-
{
58-
type: 'fetch-result',
59-
data: transformed
60-
},
61-
'*'
62-
);
18+
// Belts and braces against malicious messages
19+
if (e.data.type === 'goto' && e.data.path?.startsWith('/')) {
20+
// SvelteKit's client.js will pick this up
21+
const a = document.createElement('a');
22+
a.href = e.data.path;
23+
document.firstElementChild.append(a);
24+
a.click();
25+
a.remove();
6326
}
6427
});
6528

29+
history.pushState = function (state, title, url) {
30+
// Don't create a new history entry for better back/forward navigation in the parent window
31+
history.replaceState(state, title, url);
32+
};
33+
6634
function ping() {
6735
parent.postMessage(
6836
{
@@ -90,7 +58,7 @@ if (import.meta.hot) {
9058
});
9159
}
9260

93-
/**
61+
/**
9462
* The iframe sometimes takes focus control in ways we can't prevent
9563
* while the editor is focussed. Refocus the editor in these cases.
9664
*/

src/routes/tutorial/[slug]/Output.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
if (new_path) {
214214
ignore_path_change = true;
215215
[history_bwd, history_fwd] = [history_bwd.slice(0, -1), [path, ...history_fwd]];
216-
route_to(new_path);
216+
iframe.contentWindow?.postMessage({ type: 'goto', path: new_path }, '*');
217217
}
218218
}
219219
@@ -222,7 +222,7 @@
222222
if (new_path) {
223223
ignore_path_change = true;
224224
[history_bwd, history_fwd] = [[...history_bwd, path], history_fwd.slice(1)];
225-
route_to(new_path);
225+
iframe.contentWindow?.postMessage({ type: 'goto', path: new_path }, '*');
226226
}
227227
}
228228
</script>

0 commit comments

Comments
 (0)