Skip to content

Commit 4512313

Browse files
committed
[frontend] swap tlds for tldts, highlight only relevant url sections in omnibox
1 parent 27e093d commit 4512313

File tree

3 files changed

+93
-14
lines changed

3 files changed

+93
-14
lines changed

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"html-to-image": "^1.11.13",
2323
"html2canvas": "^1.4.1",
2424
"monaco-editor": "^0.52.2",
25-
"tlds": "^1.259.0",
25+
"tldts": "^7.0.11",
2626
"vite-plugin-static-copy": "^3.1.0"
2727
}
2828
}

frontend/src/components/UrlInput.tsx

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import {
44
type Component,
55
type Delegate,
66
} from "dreamland/core";
7-
import iconShield from "@ktibow/iconset-ion/shield-outline";
7+
import iconOptions from "@ktibow/iconset-ion/options-outline";
88
import iconStar from "@ktibow/iconset-ion/star-outline";
99
import iconSearch from "@ktibow/iconset-ion/search";
1010
import iconForwards from "@ktibow/iconset-ion/arrow-forward";
1111
import { Icon } from "./Icon";
1212
import { browser, scramjet } from "../main";
1313
import { IconButton } from "./IconButton";
14+
import { parse } from "tldts";
1415

1516
export const focusOmnibox = createDelegate<void>();
1617
export function trimUrl(v: URL) {
@@ -22,6 +23,24 @@ export function trimUrl(v: URL) {
2223
);
2324
}
2425

26+
// subdomain, domain+tld+port, path+search+query
27+
function splitUrl(url: URL): [string, string, string] {
28+
let last = url.pathname + url.search + url.hash;
29+
if (last == "/") last = "";
30+
31+
let results = parse(url.href);
32+
let domain = results.domain;
33+
if (domain && url.port) {
34+
domain += ":" + url.port;
35+
}
36+
let subdomain = results.subdomain;
37+
if (subdomain) {
38+
subdomain += ".";
39+
}
40+
41+
return [subdomain || "", domain || "", last];
42+
}
43+
2544
type OmniboxResult = {
2645
kind: "search" | "history" | "bookmark" | "direct";
2746
title?: string | null;
@@ -37,6 +56,7 @@ export const UrlInput: Component<
3756
{
3857
value: string;
3958
active: boolean;
59+
justselected: boolean;
4060
input: HTMLInputElement;
4161

4262
focusindex: number;
@@ -151,6 +171,7 @@ export const UrlInput: Component<
151171
}
152172
this.input.focus();
153173
this.input.select();
174+
this.justselected = true;
154175

155176
this.input.scrollLeft = 0;
156177
};
@@ -232,9 +253,27 @@ export const UrlInput: Component<
232253
))}
233254
</div>
234255
<div class="realbar">
235-
<IconButton icon={iconShield}></IconButton>
256+
<div class="lefticon">
257+
{use(this.active, this.focusindex, this.overflowItems).map(() =>
258+
this.active ? (
259+
this.focusindex > 0 && this.overflowItems.length > 0 ? (
260+
<img
261+
src={
262+
this.overflowItems[this.focusindex - 1].favicon ||
263+
"/vite.svg"
264+
}
265+
></img>
266+
) : (
267+
<Icon icon={iconSearch}></Icon>
268+
)
269+
) : (
270+
<Icon icon={iconOptions}></Icon>
271+
)
272+
)}
273+
</div>
236274
{use(this.active).andThen(
237275
<input
276+
spellcheck="false"
238277
this={use(this.input)}
239278
value={use(this.value)}
240279
on:keydown={(e: KeyboardEvent) => {
@@ -260,6 +299,8 @@ export const UrlInput: Component<
260299
}}
261300
// keyup, we want this to happen after the input has been processed (so the user can delete the whole thing)
262301
on:keyup={(e: KeyboardEvent) => {
302+
if (!this.justselected) return;
303+
263304
// if the user didn't modify anything
264305
if (this.input.value == trimUrl(this.tabUrl)) {
265306
// insert the untrimmed version
@@ -275,6 +316,8 @@ export const UrlInput: Component<
275316
this.input.setSelectionRange(schemelen, schemelen);
276317
}
277318
}
319+
320+
this.justselected = false;
278321
}}
279322
on:input={(e: InputEvent) => {
280323
this.value = this.input.value;
@@ -285,7 +328,17 @@ export const UrlInput: Component<
285328
{use(this.active, this.tabUrl)
286329
.map(([active, url]) => !active && url.href != "puter://newtab")
287330
.andThen(
288-
<span class="inactiveurl">{use(this.tabUrl).map(trimUrl)}</span>
331+
<span class="inactiveurl">
332+
<span class="subdomain">
333+
{use(this.tabUrl).map((t) => splitUrl(t)[0])}
334+
</span>
335+
<span class="domain">
336+
{use(this.tabUrl).map((t) => splitUrl(t)[1])}
337+
</span>
338+
<span class="rest">
339+
{use(this.tabUrl).map((t) => splitUrl(t)[2])}
340+
</span>
341+
</span>
289342
)}
290343
{use(this.active, this.tabUrl)
291344
.map(([active, url]) => !active && url.href == "puter://newtab")
@@ -318,6 +371,19 @@ UrlInput.style = css`
318371
height: 100%;
319372
}
320373
374+
.lefticon {
375+
font-size: 1.25em;
376+
color: grey;
377+
display: flex;
378+
margin: 0.25em;
379+
align-self: stretch;
380+
align-items: center;
381+
}
382+
.lefticon img {
383+
width: 20px;
384+
height: 20px;
385+
}
386+
321387
.favicon {
322388
width: 16px;
323389
height: 16px;
@@ -356,7 +422,7 @@ UrlInput.style = css`
356422
color: grey;
357423
}
358424
.overflowitem.focused {
359-
background: blue;
425+
background: #fff;
360426
}
361427
362428
.overflow.active {
@@ -390,6 +456,12 @@ UrlInput.style = css`
390456
display: flex;
391457
align-items: center;
392458
}
459+
.inactiveurl .subdomain,
460+
.inactiveurl .rest {
461+
opacity: 0.7;
462+
color: grey;
463+
}
464+
393465
.placeholder {
394466
color: grey;
395467
display: flex;

pnpm-lock.yaml

Lines changed: 16 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)