Skip to content

Commit 34550fe

Browse files
committed
[frontend] add icons to link context menu
1 parent ae04677 commit 34550fe

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

frontend/src/Tab.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import iconForwards from "@ktibow/iconset-ion/arrow-forward";
2020
import iconRefresh from "@ktibow/iconset-ion/refresh";
2121
import iconBookmark from "@ktibow/iconset-ion/bookmark-outline";
2222
import iconCode from "@ktibow/iconset-ion/code-outline";
23+
import iconLink from "@ktibow/iconset-ion/link-outline";
24+
import iconAdd from "@ktibow/iconset-ion/duplicate-outline";
25+
import iconCopy from "@ktibow/iconset-ion/copy-outline";
26+
import iconSave from "@ktibow/iconset-ion/save-outline";
2327

2428
const requestInspectElement = createDelegate<[HTMLElement, Tab]>();
2529

@@ -632,6 +636,7 @@ function pageContextItems(client: ScramjetClient, tab: Tab, e: MouseEvent) {
632636
browser.activetab.pushNavigate(new URL(url));
633637
}
634638
},
639+
icon: iconLink,
635640
},
636641
{
637642
label: "Open Link in New Tab",
@@ -640,18 +645,21 @@ function pageContextItems(client: ScramjetClient, tab: Tab, e: MouseEvent) {
640645
browser.newTab(new URL(url));
641646
}
642647
},
648+
icon: iconAdd,
643649
},
644650
{
645651
label: "Copy Link Address",
646652
action: () => {
647653
navigator.clipboard.writeText(scramjet.decodeUrl(target.href));
648654
},
655+
icon: iconCopy,
649656
},
650657
{
651658
label: "Save Link As...",
652659
action: () => {
653660
// TODO
654661
},
662+
icon: iconSave,
655663
},
656664
];
657665
}

frontend/src/utils.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { parse } from "tldts";
2+
3+
export function formatBytes(bytes: number, decimals: number = 2): string {
4+
if (bytes === 0) return "0 Bytes";
5+
6+
const k = 1024;
7+
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
8+
const i = Math.floor(Math.log(bytes) / Math.log(k));
9+
10+
return (
11+
parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + " " + sizes[i]
12+
);
13+
}
14+
15+
export function emToPx(
16+
em: number | string,
17+
element: HTMLElement = document.body
18+
): number {
19+
const computedStyle = getComputedStyle(element);
20+
21+
// Handle CSS variable input like var(--some-variable)
22+
if (typeof em === "string" && em.startsWith("var(") && em.endsWith(")")) {
23+
// Extract the variable name from var(--name)
24+
const varName = em.substring(4, em.length - 1);
25+
// Get the computed value of the CSS variable
26+
const varValue = computedStyle.getPropertyValue(varName).trim();
27+
28+
if (varValue) {
29+
// If the value ends with 'em', parse it as em
30+
if (varValue.endsWith("em")) {
31+
em = parseFloat(varValue);
32+
}
33+
// If the value is in px, return it directly
34+
else if (varValue.endsWith("px")) {
35+
return parseFloat(varValue);
36+
}
37+
// For other units or invalid values, default to 0
38+
else {
39+
return 0;
40+
}
41+
} else {
42+
return 0; // CSS variable not found
43+
}
44+
}
45+
46+
const fontSize = parseFloat(computedStyle.fontSize);
47+
return (typeof em === "number" ? em : 0) * fontSize;
48+
}
49+
50+
// subdomain, domain+tld+port, path+search+query
51+
export function splitUrl(url: URL): [string, string, string] {
52+
let last = url.pathname + url.search + url.hash;
53+
if (last == "/") last = "";
54+
55+
let results = parse(url.href);
56+
let domain = results.domain;
57+
if (domain && url.port) {
58+
domain += ":" + url.port;
59+
}
60+
let subdomain = results.subdomain;
61+
if (subdomain) {
62+
subdomain += ".";
63+
}
64+
65+
return [subdomain || "", domain || "", last];
66+
}

0 commit comments

Comments
 (0)