Firefox WebExtension (Desktop and Mobile) that lets you share the current tab to Margit.at, frontpage.fyi, etc. with minimal effort.
1const api = globalThis.browser ?? globalThis.chrome;
2const MAX_TITLE = 120;
3
4const form = document.getElementById("submit-form");
5const titleInput = document.getElementById("title");
6const urlInput = document.getElementById("url");
7const statusEl = document.getElementById("status");
8const titleCountEl = document.getElementById("title-count");
9const submitBtn = document.getElementById("submit-btn");
10const openOptionsBtn = document.getElementById("open-options");
11const openFrontpageLink = document.getElementById("open-frontpage");
12
13function showStatus(message, isError = false) {
14 statusEl.textContent = message;
15 statusEl.className = isError ? "status error" : "status success";
16}
17
18function updateTitleCounter() {
19 const value = titleInput.value ?? "";
20 titleCountEl.textContent = `${value.length}/${MAX_TITLE}`;
21 if (value.length > MAX_TITLE) {
22 titleCountEl.classList.add("over-limit");
23 } else {
24 titleCountEl.classList.remove("over-limit");
25 }
26}
27
28async function populateFromTab() {
29 try {
30 const tabs = await api.tabs.query({ active: true, currentWindow: true });
31 const tab = tabs?.[0];
32 if (!tab) return;
33 if (tab.title) {
34 titleInput.value = tab.title.trim().slice(0, MAX_TITLE);
35 }
36 if (tab.url && /^https?:/i.test(tab.url)) {
37 urlInput.value = tab.url;
38 }
39 updateTitleCounter();
40 } catch (error) {
41 console.error("Unable to read active tab", error);
42 }
43}
44
45let hasAuth = false;
46
47async function checkAuth() {
48 try {
49 const response = await api.runtime.sendMessage({ type: "frontpage-get-auth" });
50 hasAuth = Boolean(response?.auth);
51 if (!hasAuth) {
52 showStatus("Configure your Frontpage credentials in the options page.", true);
53 } else {
54 showStatus("");
55 }
56 } catch (error) {
57 console.error("Failed to query auth state", error);
58 showStatus("Unable to read authentication state.", true);
59 }
60}
61
62form.addEventListener("submit", async (event) => {
63 event.preventDefault();
64 if (!hasAuth) {
65 showStatus("Configure your Frontpage credentials in the options page.", true);
66 return;
67 }
68 showStatus("");
69 submitBtn.disabled = true;
70 try {
71 const payload = {
72 title: titleInput.value,
73 url: urlInput.value
74 };
75 const response = await api.runtime.sendMessage({
76 type: "frontpage-submit",
77 payload
78 });
79 if (!response?.ok) {
80 throw new Error(response?.error ?? "Unknown error");
81 }
82 const uri = response?.result?.uri;
83 showStatus(uri ? `Posted! ${uri}` : "Posted to Frontpage!", false);
84 } catch (error) {
85 console.error("Submission failed", error);
86 showStatus(error.message, true);
87 } finally {
88 submitBtn.disabled = false;
89 }
90});
91
92titleInput.addEventListener("input", updateTitleCounter);
93
94openOptionsBtn.addEventListener("click", () => {
95 api.runtime.openOptionsPage();
96});
97
98openFrontpageLink.addEventListener("click", (event) => {
99 event.preventDefault();
100 api.tabs.create({ url: "https://frontpage.fyi" });
101});
102
103populateFromTab();
104checkAuth();