Skip to content

Commit f31aad0

Browse files
committed
[frontend] clean up some jank with devtools
1 parent 6aa2a58 commit f31aad0

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

frontend/src/Tab.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class Tab extends StatefulClass {
1717
id: number;
1818
title: string | null;
1919
frame: ScramjetFrame;
20-
devtoolsFrame: HTMLIFrameElement | null = null;
20+
devtoolsFrame: ScramjetFrame;
2121
screenshot: string | null = null;
2222

2323
dragoffset: number;
@@ -60,12 +60,17 @@ export class Tab extends StatefulClass {
6060
const frame = scramjet.createFrame();
6161
addHistoryListeners(frame, this);
6262
frame.addEventListener("contextInit", (ctx) => {
63-
injectHistoryEmulation(ctx.client, this);
6463
injectContextMenu(ctx.client, this);
65-
injectDevtools(ctx.client, this);
64+
65+
// make sure it's top level, ctxInit calls for all frames too
66+
if (ctx.window == frame.frame.contentWindow) {
67+
injectHistoryEmulation(ctx.client, this);
68+
injectDevtools(ctx.client, this);
69+
}
6670
});
6771

6872
this.frame = frame;
73+
this.devtoolsFrame = scramjet.createFrame();
6974
}
7075

7176
// only caller should be history.ts for this
@@ -122,34 +127,34 @@ function injectDevtools(client: ScramjetClient, tab: Tab) {
122127
// then we set up communication between the devtools frame and the page frame
123128
// then, hand off the devtools frame to the page frame so that it can inject itself into it, but cannot use the globals to escape
124129

130+
let devtoolsFrameClient: ScramjetClient;
131+
132+
// listen to the *page's* beforeunload, so we can get rid of the previous scramjet client (and associated devtools frame) in time for the new site to load
133+
client.global.addEventListener("beforeunload", () => {
134+
console.log("before unload");
135+
tab.devtoolsFrame.frame.src = "about:blank";
136+
});
125137
// we're loading the entire bundle through scramjet so that eval() will be rewritten
138+
// if the frame is about:blank it won't have a client yet, so we need to create one
126139
// to start, apply the same hack as window.open to scramjetify the devtools frame
127-
const contentwindow = tab.devtoolsFrame!.contentWindow;
140+
const contentwindow = tab.devtoolsFrame.frame.contentWindow;
128141
const ctor: any = client.constructor;
129-
const devtoolsFrameClient: ScramjetClient = new ctor(contentwindow);
130-
// TODO: move this to frame creation
131-
scramjet.createFrame(tab.devtoolsFrame!);
142+
devtoolsFrameClient = new ctor(contentwindow);
143+
// TODO i should probably put this in core
132144
devtoolsFrameClient.hook();
145+
133146
// the fake origin is defined in sw.js
134147
const devtoolsUrl = "https://fake-devtools.invalid";
135148
// make sure to create the element through the proxied document
136149
let devtoolsScript = client.global.document.createElement("script");
137150
devtoolsScript.setAttribute("src", devtoolsUrl + "/target.js");
138151
devtoolsScript.setAttribute("embedded", "true");
139152

140-
devtoolsFrameClient.frame!.addEventListener("contextInit", () => {
153+
tab.devtoolsFrame.addEventListener("contextInit", (e) => {
141154
// devtools frontend will try to access the parent window's postMessage
142155
// this won't work, i manually patched it to use this global instead
143156
//@ts-expect-error
144-
tab.devtoolsFrame.contentWindow.parentPostMessage = (
145-
data: any,
146-
origin: string
147-
) => {
148-
if (!JSON.parse(data).method) {
149-
console.error("ignoring some data");
150-
return;
151-
}
152-
157+
e.window.parentPostMessage = (data: any, origin: string) => {
153158
// oh god
154159
// i will fix this later
155160
// we're not supposed to be postmessaging from a non-scramjet context into a scramjet one

frontend/src/components/Shell.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export const Shell: Component<{
99
activetab: Tab;
1010
}> = function (cx) {
1111
pushTab.listen((tab) => {
12+
// paint the iframes
1213
tab.frame.frame.classList.add(cx.id);
13-
let devtoolsFrame: HTMLIFrameElement = (
14-
<iframe class:unfocus={use(browser.unfocusframes)}></iframe>
15-
);
14+
tab.devtoolsFrame.frame.classList.add(cx.id);
15+
1616
let mouseMoveListen = (e: MouseEvent) => {
1717
tab.devtoolsWidth = window.innerWidth - e.clientX;
1818
};
@@ -48,11 +48,15 @@ export const Shell: Component<{
4848
}}
4949
class="divider"
5050
></div>
51-
{devtoolsFrame}
51+
<div
52+
class="devtoolsframecontainer"
53+
class:unfocus={use(browser.unfocusframes)}
54+
>
55+
{tab.devtoolsFrame.frame}
56+
</div>
5257
</div>
5358
</div>
5459
);
55-
tab.devtoolsFrame = devtoolsFrame;
5660
});
5761
popTab.listen((tab) => {
5862
const container = cx.root.querySelector(`[data-tab="${tab.id}"]`);

0 commit comments

Comments
 (0)