Skip to content

Commit a4a9dae

Browse files
committed
minor tab/shell refactor
1 parent 4190f1f commit a4a9dae

6 files changed

Lines changed: 248 additions & 211 deletions

File tree

packages/chrome/src/Tab/Tab.tsx

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import { AboutPage } from "../pages/AboutPage";
88
import { HistoryPage } from "../pages/HistoryPage";
99
import { SettingsPage } from "../pages/SettingsPage";
1010
import { DownloadsPage } from "../pages/DownloadsPage";
11-
import { ProxyFrame } from "../proxy/ProxyFrame";
1211
import { uuid } from "../util";
1312
import { mountedPromise } from "../App";
1413
import { tabsService } from "..";
1514
import { CDPConnection } from "../CDP";
15+
import { TabSession } from "./TabSession";
1616
// const requestInspectElement = createDelegate<[HTMLElement, Tab]>();
1717

1818
export type SerializedTab = {
@@ -25,10 +25,7 @@ export type SerializedTab = {
2525

2626
export class Tab extends StatefulClass {
2727
title: string | null = null;
28-
frame: ProxyFrame;
29-
devtoolsFrame: HTMLIFrameElement = (
30-
<iframe src="/front_end/inspexctor.html"></iframe>
31-
);
28+
session: TabSession;
3229
screenshot: string | null = null;
3330

3431
url: URL;
@@ -62,20 +59,7 @@ export class Tab extends StatefulClass {
6259
this.url ??= new URL(`${INTERNAL_URL_PROTOCOL}//newtab`);
6360
this.id ??= uuid("tab-");
6461

65-
// this.devtoolsFrame.onload = () => {
66-
// let session = new CDPConnection((msh) => {
67-
// this.devtoolsFrame.contentWindow.InspectorFrontendAPI.dispatchMessage(
68-
// msh
69-
// );
70-
// });
71-
// this.devtoolsFrame.contentWindow.InspectorFrontendHost.sendMessageToBackend =
72-
// (message) => {
73-
// console.warn(message);
74-
// session.sendMessage(message);
75-
// };
76-
// };
77-
78-
this.frame = new ProxyFrame();
62+
this.session = new TabSession();
7963
this.history = new History(this, history);
8064
this.own(this.history);
8165
this.waitForInit = new Promise((resolve) => {
@@ -158,50 +142,26 @@ export class Tab extends StatefulClass {
158142
if (url.protocol == INTERNAL_URL_PROTOCOL) {
159143
this.icon = null;
160144
this.history.current().favicon = "/icon.png";
161-
switch (url.host) {
162-
case "newtab":
163-
this.history.current().title = this.title = "New Tab";
164-
this.internalpage = <NewTabPage tab={this} />;
165-
break;
166-
case "playground":
167-
this.history.current().title = this.title = "Scramjet Playground";
168-
this.internalpage = <PlaygroundPage tab={this} />;
169-
break;
170-
case "history":
171-
this.history.current().title = this.title = "Browser History";
172-
this.internalpage = <HistoryPage tab={this}></HistoryPage>;
173-
break;
174-
case "version":
175-
this.history.current().title = this.title = "About Version";
176-
this.internalpage = <AboutPage tab={this} />;
177-
break;
178-
case "settings":
179-
this.history.current().title = this.title = "Settings";
180-
this.internalpage = (
181-
<SettingsPage
182-
tab={this}
183-
selected={
184-
url.pathname.length > 1 ? url.pathname.slice(1) : "general"
185-
}
186-
/>
187-
);
188-
break;
189-
case "downloads":
190-
this.history.current().title = this.title = "Downloads";
191-
this.internalpage = <DownloadsPage tab={this} />;
145+
const page = createInternalPage(url, this);
146+
if (page) {
147+
this.internalpage = page.page;
148+
this.history.current().title = this.title = page.title;
149+
} else {
150+
// TODO: make this better
151+
this.internalpage = (
152+
<div style={{ padding: "20px" }}>
153+
<h1>404 Not Found</h1>
154+
<p>No internal page found for {url.href}</p>
155+
</div>
156+
);
157+
this.history.current().title = this.title = "404 Not Found";
192158
}
193159
} else {
194160
// placeholder title until the page fills in
195161
this.history.current().title = this.title = url.href;
196162

197-
// if (!navigator.serviceWorker.controller) {
198-
// serviceWorkerReady.then(() => {
199163
console.warn("navigating to", url);
200-
this.frame.go(url);
201-
// });
202-
// } else {
203-
// this.frame.go(url);
204-
// }
164+
this.session.go(url);
205165
}
206166
}
207167

@@ -231,7 +191,54 @@ export class Tab extends StatefulClass {
231191
if (this.internalpage) {
232192
this._directnavigate(this.url);
233193
} else {
234-
this.frame.reload();
194+
this.session.reload();
235195
}
236196
}
237197
}
198+
199+
function createInternalPage(
200+
url: URL,
201+
tab: Tab
202+
): { title: string; page: HTMLElement } | null {
203+
switch (url.host) {
204+
case "newtab":
205+
return {
206+
title: "New Tab",
207+
page: <NewTabPage tab={tab} />,
208+
};
209+
case "playground":
210+
return {
211+
title: "Scramjet Playground",
212+
page: <PlaygroundPage tab={tab} />,
213+
};
214+
case "history":
215+
return {
216+
title: "Browser History",
217+
page: <HistoryPage tab={tab} />,
218+
};
219+
case "version":
220+
return {
221+
title: "About Version",
222+
page: <AboutPage tab={tab} />,
223+
};
224+
case "settings":
225+
return {
226+
title: "Settings",
227+
page: (
228+
<SettingsPage
229+
tab={tab}
230+
selected={
231+
url.pathname.length > 1 ? url.pathname.slice(1) : "general"
232+
}
233+
></SettingsPage>
234+
),
235+
};
236+
case "downloads":
237+
return {
238+
title: "Downloads",
239+
page: <DownloadsPage tab={tab} />,
240+
};
241+
default:
242+
return null;
243+
}
244+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { rewriteUrl } from "@mercuryworkshop/scramjet/bundled";
2+
import { Controller, controllerForURL } from "../proxy/Controller";
3+
4+
export class TabSession {
5+
frame: HTMLIFrameElement;
6+
frameWindowProxy!: WindowProxy;
7+
devtoolsFrame: HTMLIFrameElement;
8+
controller: Controller | null = null;
9+
constructor() {
10+
this.frame = document.createElement("iframe");
11+
this.devtoolsFrame = document.createElement("iframe");
12+
13+
// this.devtoolsFrame.onload = () => {
14+
// let session = new CDPConnection((msh) => {
15+
// this.devtoolsFrame.contentWindow.InspectorFrontendAPI.dispatchMessage(
16+
// msh
17+
// );
18+
// });
19+
// this.devtoolsFrame.contentWindow.InspectorFrontendHost.sendMessageToBackend =
20+
// (message) => {
21+
// console.warn(message);
22+
// session.sendMessage(message);
23+
// };
24+
// };
25+
}
26+
27+
mounted() {
28+
this.frameWindowProxy = this.frame.contentWindow!;
29+
}
30+
31+
async go(url: URL) {
32+
let controller = await controllerForURL(url);
33+
this.controller = controller;
34+
35+
const prefix = controller.prefix;
36+
37+
this.frame.src = rewriteUrl(url, controller.fetchHandler.context, {
38+
origin: prefix, // origin/base don't matter here because we're always sending an absolute URL
39+
base: prefix,
40+
});
41+
}
42+
43+
reload() {
44+
this.frame.contentWindow?.location.reload();
45+
}
46+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { css, type FC } from "dreamland/core";
2+
import type { Tab } from "./Tab";
3+
import { requestUnfocusFrames } from "@components/Shell";
4+
import { tabsService } from "..";
5+
import type { TabSession } from "./TabSession";
6+
7+
export function TabView(this: FC<{ tab: Tab; ts: TabSession }>) {
8+
const [lock, unlock] = requestUnfocusFrames();
9+
10+
let mouseMoveListen = (e: MouseEvent) => {
11+
this.tab.devtoolsWidth = window.innerWidth - e.clientX;
12+
};
13+
14+
this.ts.frame.classList.add(this.cx.id!);
15+
this.ts.devtoolsFrame.classList.add(this.cx.id!);
16+
17+
return (
18+
<div
19+
class="container"
20+
data-tab={this.tab.id}
21+
id={"tab" + this.tab.id}
22+
class:active={use(tabsService.activetab).map((t) => t === this.tab)}
23+
class:showframe={use(this.tab.internalpage).map((t) => !t)}
24+
>
25+
<div class="mainframecontainer">
26+
{use(this.tab.internalpage)}
27+
{this.ts.frame}
28+
</div>
29+
<div
30+
class="devtools"
31+
class:active={use(this.tab.devtoolsOpen)}
32+
style={use`width: ${this.tab.devtoolsWidth}px`}
33+
>
34+
<div
35+
on:mousedown={(e: MouseEvent) => {
36+
lock();
37+
document.body.style.cursor = "ew-resize";
38+
window.addEventListener("mousemove", mouseMoveListen);
39+
window.addEventListener("mouseup", () => {
40+
unlock();
41+
window.removeEventListener("mousemove", mouseMoveListen);
42+
document.body.style.cursor = "";
43+
});
44+
}}
45+
class="divider"
46+
></div>
47+
<div class="devtoolsframecontainer">{this.ts.devtoolsFrame}</div>
48+
</div>
49+
<progress value={use(this.tab.loadProgress)}></progress>
50+
</div>
51+
);
52+
}
53+
TabView.style = css`
54+
:scope {
55+
position: absolute;
56+
width: 100%;
57+
height: 100%;
58+
display: flex;
59+
top: 0;
60+
left: 0;
61+
z-index: -1;
62+
/*display: none;*/
63+
64+
/*https://screen-share.github.io/element-capture/#elements-eligible-for-restriction*/
65+
isolation: isolate;
66+
transform-style: flat;
67+
68+
background-color: var(--ntp_background);
69+
}
70+
:scope.active {
71+
z-index: 0;
72+
}
73+
.devtools {
74+
position: relative;
75+
display: none;
76+
width: 20em;
77+
}
78+
.devtools.active {
79+
display: flex;
80+
}
81+
82+
.devtoolsframecontainer {
83+
width: 100%;
84+
}
85+
86+
.mainframecontainer {
87+
display: flex;
88+
width: 100%;
89+
flex: 1;
90+
background: white;
91+
}
92+
93+
.divider {
94+
position: absolute;
95+
top: 0;
96+
left: -5px;
97+
width: 5px;
98+
/* background: #ccc; */
99+
border-right: 1px solid #ccc;
100+
height: 100%;
101+
cursor: ew-resize;
102+
}
103+
104+
iframe {
105+
flex: 1;
106+
height: 100%;
107+
width: 100%;
108+
border: none;
109+
display: none;
110+
}
111+
.showframe iframe {
112+
display: block;
113+
}
114+
progress {
115+
z-index: 1;
116+
position: absolute;
117+
width: 100%;
118+
height: 3px;
119+
border: none;
120+
}
121+
progress::-webkit-progress-bar {
122+
background-color: transparent;
123+
}
124+
progress::-webkit-progress-value {
125+
background-color: var(--tab_line);
126+
}
127+
`;

0 commit comments

Comments
 (0)