Compare commits
5 Commits
v1.0.1
...
feature/ch
| Author | SHA1 | Date | |
|---|---|---|---|
|
a1a9a01e2c
|
|||
|
bb56e269c4
|
|||
|
d6ef7cdd5e
|
|||
|
0dd0f8bf3d
|
|||
|
f1c2b4a592
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <https://unlicense.org/>
|
||||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Nostr Links Web Extension
|
||||||
|
|
||||||
|
A browser extension for discovering and opening Nostr links.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Details described in this article: https://nostr.kosmos.org/@raucao/link-rel-nostr
|
||||||
|
|
||||||
|
## ngit
|
||||||
|
|
||||||
|
This repo is also available via ngit:
|
||||||
|
|
||||||
|
git clone nostr://raucao@kosmos.org/nostr-links
|
||||||
|
|
||||||
|
[Issues and PRs](https://gitworkshop.dev/raucao@kosmos.org/nostr-links/prs)
|
||||||
|
are also accepted this way.
|
||||||
|
|
||||||
|
Quick start: https://gitworkshop.dev/quick-start
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||||
if (changeInfo.status !== 'complete') {
|
if (changeInfo.status !== 'complete') {
|
||||||
browser.pageAction.hide(tabId);
|
chrome.action.disable(tabId);
|
||||||
browser.storage.local.remove(`nl_tab_${sender.tab.id}`);
|
chrome.storage.local.remove(`nl_tab_${tabId}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}, { properties: ["status"] });
|
});
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
if (message.action === "showNostrLinksPageAction" && sender.tab?.id) {
|
if (message.action === 'showNostrLinksPageAction' && sender.tab?.id) {
|
||||||
const tabLinks = { [`nl_tab_${sender.tab.id}`]: message.links };
|
const tabLinks = { [`nl_tab_${sender.tab.id}`]: message.links };
|
||||||
browser.storage.local.set(tabLinks, () => {
|
chrome.storage.local.set(tabLinks, () => {
|
||||||
browser.pageAction.show(sender.tab.id);
|
chrome.action.enable(sender.tab.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.action === "getNostrLinks" && message.tabId) {
|
if (message.action === 'getNostrLinks' && message.tabId) {
|
||||||
browser.storage.local.get(`nl_tab_${message.tabId}`, (result) => {
|
chrome.storage.local.get(`nl_tab_${message.tabId}`, (result) => {
|
||||||
sendResponse({ links: result[`nl_tab_${message.tabId}`] || [] });
|
sendResponse({ links: result[`nl_tab_${message.tabId}`] || [] });
|
||||||
});
|
});
|
||||||
return true; // Keep message channel open for async response
|
return true; // Keep message channel open for async response
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
browser.tabs.onRemoved.addListener((tabId) => {
|
chrome.tabs.onRemoved.addListener((tabId) => {
|
||||||
browser.storage.local.remove(`nl_tab_${tabId}`);
|
chrome.storage.local.remove(`nl_tab_${tabId}`);
|
||||||
});
|
});
|
||||||
|
|||||||
34
content.js
34
content.js
@@ -1,20 +1,26 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const alternateLinks = document.querySelectorAll('link[rel="alternate"][type="application/nostr+json"]');
|
const linkRels = ['alternate', 'me', 'author'];
|
||||||
|
const selector = linkRels.map(rel => `link[rel="${rel}"][type="application/nostr+json"]`).join(',');
|
||||||
|
const links = document.querySelectorAll(selector);
|
||||||
|
const linkMap = new Map();
|
||||||
|
|
||||||
if (alternateLinks.length > 0) {
|
if (links.length > 0) {
|
||||||
console.debug("[nostr-links] Found:", alternateLinks);
|
links.forEach(link => {
|
||||||
|
const uri = link.href.replace(/^(nostr|web+nostr):/, "").trim();
|
||||||
|
let text = link.title?.trim() || '';
|
||||||
|
if (link.rel === "author") text = `Author: ${text}`;
|
||||||
|
|
||||||
const links = Array.from(alternateLinks).map((link, index) => ({
|
linkMap.set(uri, {
|
||||||
uri: link.href.replace(/^(nostr|web+nostr):/, ""),
|
uri: uri,
|
||||||
text: link.title.trim()
|
text: text,
|
||||||
// icon: "icon.png"
|
rel: link.rel
|
||||||
}));
|
// icon: "icon.png"
|
||||||
|
});
|
||||||
browser.runtime.sendMessage({
|
});
|
||||||
action: "showNostrLinksPageAction",
|
|
||||||
links: links
|
chrome.runtime.sendMessage({
|
||||||
|
action: "showNostrLinksPageAction",
|
||||||
|
links: Array.from(linkMap.values())
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
console.debug("[nostr-links] No nostr links found");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Nostr Links",
|
"name": "Nostr Links",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"description": "A web extension to discover Nostr links",
|
"description": "A web extension to discover Nostr links",
|
||||||
"author": "Râu Cao",
|
"author": "Râu Cao",
|
||||||
"homepage_url": "https://gitea.kosmos.org/raucao/nostr-links",
|
"homepage_url": "https://gitea.kosmos.org/raucao/nostr-links",
|
||||||
@@ -15,9 +15,7 @@
|
|||||||
"activeTab"
|
"activeTab"
|
||||||
],
|
],
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": [
|
"service_worker": "background.js"
|
||||||
"background.js"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
@@ -26,7 +24,7 @@
|
|||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"page_action": {
|
"action": {
|
||||||
"default_icon": "icons/nostr.svg",
|
"default_icon": "icons/nostr.svg",
|
||||||
"default_title": "Nostr",
|
"default_title": "Nostr",
|
||||||
"default_popup": "popup/nostr-links.html"
|
"default_popup": "popup/nostr-links.html"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
browser.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
||||||
const tabId = tabs[0].id;
|
const tabId = tabs[0].id;
|
||||||
|
|
||||||
browser.runtime.sendMessage({ action: "getNostrLinks", tabId }, (response) => {
|
chrome.runtime.sendMessage({ action: "getNostrLinks", tabId }, (response) => {
|
||||||
const menu = document.getElementById("link-menu");
|
const menu = document.getElementById("link-menu");
|
||||||
if (response.links && response.links.length > 0) {
|
if (response.links && response.links.length > 0) {
|
||||||
menu.innerHTML = response.links
|
menu.innerHTML = response.links
|
||||||
|
|||||||
Reference in New Issue
Block a user