mirror of
https://github.com/chenasraf/copy-tab-url.git
synced 2026-05-17 17:38:15 +00:00
feat: context menu
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"description": "Easy shortcuts for copying tab URL with or without title, with customizable format.",
|
||||
"packageManager": "pnpm@9.9.0",
|
||||
"packageManager": "pnpm@9.12.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run clear && cross-env NODE_ENV=development run-p 'dev:*'",
|
||||
@@ -22,6 +22,7 @@
|
||||
"pack:xpi": "cross-env WEB_EXT_ARTIFACTS_DIR=./ web-ext build --source-dir ./extension --filename extension.xpi --overwrite-dest",
|
||||
"start:chromium": "web-ext run --source-dir ./extension --target=chromium",
|
||||
"start:firefox": "web-ext run --source-dir ./extension --target=firefox-desktop",
|
||||
"start:zed": "web-ext run --source-dir ./extension --target=firefox-desktop --firefox='/Applications/Zen Browser.app/Contents/MacOS/zen'",
|
||||
"clear": "rimraf extension/dist extension/manifest.json 'extension.*'",
|
||||
"lint": "eslint --ignore-path .gitignore './**/*.{ts,tsx,js,jsx}'"
|
||||
},
|
||||
|
||||
@@ -11,31 +11,51 @@ if (import.meta.hot) {
|
||||
import('./contentScriptHMR')
|
||||
}
|
||||
|
||||
browser.runtime.onInstalled.addListener((): void => {
|
||||
logger.log('Extension installed')
|
||||
})
|
||||
|
||||
logger.log('Hello from background script')
|
||||
|
||||
async function getCurrentTab() {
|
||||
return browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => tabs[0])
|
||||
function init() {
|
||||
browser.runtime.onInstalled.addListener((): void => {
|
||||
logger.log('Extension installed')
|
||||
})
|
||||
|
||||
// Commands (keyboard shortcuts)
|
||||
browser.commands.onCommand.addListener(async (cmd) => {
|
||||
const tab = await getCurrentTab()
|
||||
logger.debug('command received', cmd, tab)
|
||||
const resp = getResponse(cmd, tab)
|
||||
if (!resp || !tab) return
|
||||
|
||||
logger.debug('sending message', resp, 'to tab', tab.id)
|
||||
return sendMessage(resp.cmd, resp.payload!, {
|
||||
context: 'content-script',
|
||||
tabId: tab.id!,
|
||||
})
|
||||
})
|
||||
|
||||
// Context menu
|
||||
browser.contextMenus.create({
|
||||
id: 'copy-tab-url',
|
||||
title: 'Copy Tab URL',
|
||||
contexts: ['all'],
|
||||
})
|
||||
browser.contextMenus.create({
|
||||
id: 'copy-tab-markdown',
|
||||
title: 'Copy Tab Markdown',
|
||||
contexts: ['all'],
|
||||
})
|
||||
browser.contextMenus.onClicked.addListener(async (info) => {
|
||||
const tab = await getCurrentTab()
|
||||
const resp = getResponse(info.menuItemId as string, tab)
|
||||
if (!resp || !tab) return
|
||||
return sendMessage(resp.cmd, resp.payload!, { context: 'content-script', tabId: tab.id! })
|
||||
})
|
||||
|
||||
// Popup listeners
|
||||
onMessage('copy-tab-url', responder('copy-tab-url'))
|
||||
onMessage('copy-tab-markdown', responder('copy-tab-markdown'))
|
||||
}
|
||||
|
||||
browser.commands.onCommand.addListener(async (cmd) => {
|
||||
const tab = await getCurrentTab()
|
||||
logger.debug('command received', cmd, tab)
|
||||
const resp = getResponse(cmd, tab)
|
||||
if (!resp || !tab) return
|
||||
|
||||
logger.debug('sending message', resp, 'to tab', tab.id)
|
||||
return sendMessage(resp.cmd, resp.payload!, {
|
||||
context: 'content-script',
|
||||
tabId: tab.id!,
|
||||
})
|
||||
})
|
||||
|
||||
onMessage('copy-tab-url', responder('copy-tab-url'))
|
||||
onMessage('copy-tab-markdown', responder('copy-tab-markdown'))
|
||||
init()
|
||||
|
||||
function responder(cmd: string) {
|
||||
return async (payload: BridgeMessage<string>) => {
|
||||
@@ -54,13 +74,17 @@ function getResponse(msg: string, tab: Tabs.Tab) {
|
||||
switch (msg) {
|
||||
case 'copy-tab-url':
|
||||
// copy tab url to clipboard
|
||||
return { cmd: 'copy-text', payload: tab?.url }
|
||||
return { cmd: msg, payload: tab?.url }
|
||||
case 'copy-tab-markdown':
|
||||
// copy tab url and title in markdown format
|
||||
return {
|
||||
cmd: 'copy-text',
|
||||
cmd: msg,
|
||||
payload: `[${tab?.title}](${tab?.url})`,
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
async function getCurrentTab() {
|
||||
return browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => tabs[0])
|
||||
}
|
||||
|
||||
@@ -30,7 +30,15 @@ export async function getManifest() {
|
||||
48: './assets/icon-512.png',
|
||||
128: './assets/icon-512.png',
|
||||
},
|
||||
permissions: ['tabs', 'storage', 'activeTab', 'clipboardWrite', 'http://*/', 'https://*/'],
|
||||
permissions: [
|
||||
'tabs',
|
||||
'storage',
|
||||
'activeTab',
|
||||
'clipboardWrite',
|
||||
'contextMenus',
|
||||
'http://*/',
|
||||
'https://*/',
|
||||
],
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ['http://*/*', 'https://*/*'],
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
html,
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.App {
|
||||
width: 300px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
@@ -29,15 +29,6 @@
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: calc(10px + 2vmin);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user