commit 44d5b62b3c8533bff09f59b07274fad4fc4e2c3c Author: Râu Cao Date: Wed Apr 23 12:43:41 2025 +0400 GM diff --git a/background.js b/background.js new file mode 100644 index 0000000..82c5d06 --- /dev/null +++ b/background.js @@ -0,0 +1,28 @@ + +browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { + if (changeInfo.status !== 'complete') { + browser.pageAction.hide(tabId); + await browser.storage.local.remove(`nl_tab_${sender.tab.id}`); + return; + } +}, { properties: ["status"] }); + +browser.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.action === "showNostrLinksPageAction" && sender.tab?.id) { + const tabLinks = { [`nl_tab_${sender.tab.id}`]: message.links }; + browser.storage.local.set(tabLinks, () => { + browser.pageAction.show(sender.tab.id); + }); + } + + if (message.action === "getNostrLinks" && message.tabId) { + browser.storage.local.get(`nl_tab_${message.tabId}`, (result) => { + sendResponse({ links: result[`nl_tab_${message.tabId}`] || [] }); + }); + return true; // Keep message channel open for async response + } +}); + +browser.tabs.onRemoved.addListener((tabId) => { + browser.storage.local.remove(`nl_tab_${tabId}`); +}); diff --git a/content.js b/content.js new file mode 100644 index 0000000..254bec1 --- /dev/null +++ b/content.js @@ -0,0 +1,20 @@ +document.addEventListener('DOMContentLoaded', function() { + const alternateLinks = document.querySelectorAll('link[rel="alternate"][type="application/nostr+json"]'); + + if (alternateLinks.length > 0) { + console.debug("[nostr-links] Found:", alternateLinks); + + const links = Array.from(alternateLinks).map((link, index) => ({ + uri: link.href.replace(/^(nostr|web+nostr):/, ""), + text: link.title.trim() + // icon: "icon.png" + })); + + browser.runtime.sendMessage({ + action: "showNostrLinksPageAction", + links: links + }); + } else { + console.debug("[nostr-links] No nostr links found"); + } +}); diff --git a/icons/nostr-48.png b/icons/nostr-48.png new file mode 100644 index 0000000..06fa7b8 Binary files /dev/null and b/icons/nostr-48.png differ diff --git a/icons/nostr-96.png b/icons/nostr-96.png new file mode 100644 index 0000000..0da1684 Binary files /dev/null and b/icons/nostr-96.png differ diff --git a/icons/nostr.svg b/icons/nostr.svg new file mode 100644 index 0000000..ff7a7a5 --- /dev/null +++ b/icons/nostr.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..aa1c8ec --- /dev/null +++ b/manifest.json @@ -0,0 +1,34 @@ +{ + "manifest_version": 3, + "name": "Nostr Links", + "version": "1.0.0", + "description": "A web extension to discover Nostr links", + "author": "Râu Cao", + "homepage_url": "https://gitea.kosmos.org/raucao/nostr-links", + "icons": { + "48": "icons/nostr-48.png", + "96": "icons/nostr-96.png" + }, + "permissions": [ + "storage", + "tabs", + "activeTab" + ], + "background": { + "scripts": [ + "background.js" + ] + }, + "content_scripts": [ + { + "matches": [ "http://*/*", "https://*/*", "file:///*" ], + "js": ["content.js"], + "run_at": "document_end" + } + ], + "page_action": { + "default_icon": "icons/nostr.svg", + "default_title": "Nostr", + "default_popup": "popup/nostr-links.html" + } +} diff --git a/popup/nostr-links.css b/popup/nostr-links.css new file mode 100644 index 0000000..390cf72 --- /dev/null +++ b/popup/nostr-links.css @@ -0,0 +1,49 @@ +body { + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, sans-serif; + background-color: #fff; + min-width: 200px; + border: 1px solid #ccc; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); +} + +.dropdown-menu { + list-style: none; + margin: 0; + padding: 4px 0; +} + +.dropdown-menu li { + margin: 0; + padding: 0; +} + +.dropdown-menu a { + display: flex; + align-items: center; + padding: 8px 12px; + color: #333; + text-decoration: none; + white-space: nowrap; + transition: background-color 0.1s ease; +} + +.dropdown-menu a:hover { + background-color: #f0f0f0; + color: #000; +} + +.dropdown-menu a.disabled { + color: #999; + pointer-events: none; + cursor: default; +} + +.menu-icon { + display: none; + width: 16px; + height: 16px; + margin-right: 8px; + vertical-align: middle; +} diff --git a/popup/nostr-links.html b/popup/nostr-links.html new file mode 100644 index 0000000..c2e1cd6 --- /dev/null +++ b/popup/nostr-links.html @@ -0,0 +1,13 @@ + + + + + + Nostr Links + + + + + + + diff --git a/popup/nostr-links.js b/popup/nostr-links.js new file mode 100644 index 0000000..3feb3bb --- /dev/null +++ b/popup/nostr-links.js @@ -0,0 +1,20 @@ +browser.tabs.query({ active: true, currentWindow: true }, (tabs) => { + const tabId = tabs[0].id; + + browser.runtime.sendMessage({ action: "getNostrLinks", tabId }, (response) => { + const menu = document.getElementById("link-menu"); + if (response.links && response.links.length > 0) { + menu.innerHTML = response.links + .map( + (link) => ` +
  • + + ${link.text || "Open on Nostr"} + +
  • + ` + ) + .join(""); + } + }); +});