Skip to content

Commit da6059b

Browse files
authored
Add files via upload
1 parent 369051d commit da6059b

File tree

8 files changed

+92
-0
lines changed

8 files changed

+92
-0
lines changed

icon-128.png

208 KB
Loading

icon-16.png

40.3 KB
Loading

icon-48.png

131 KB
Loading

manifest.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"manifest_version": 3,
3+
"name": "Quick Screenshot → Clipboard",
4+
"version": "1.0.0",
5+
"description": "Click the icon to copy the visible area of the current tab as an image to your clipboard.",
6+
"permissions": [
7+
"activeTab",
8+
"clipboardWrite"
9+
],
10+
"background": {
11+
"service_worker": "service_worker.js"
12+
},
13+
"action": {
14+
"default_title": "Copy visible screenshot",
15+
"default_popup": "popup.html"
16+
},
17+
"icons": {
18+
"16": "icon-16.png",
19+
"48": "icon-48.png",
20+
"128": "icon-128.png"
21+
}
22+
}

popup.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Copy Screenshot</title>
6+
<style>
7+
body { font-family: -apple-system, Arial, sans-serif; width: 230px; padding: 10px; }
8+
#status { font-size: 14px; }
9+
#detail { margin-top: 6px; font-size: 12px; opacity: .85; word-break: break-word; }
10+
</style>
11+
</head>
12+
<body>
13+
<div id="status">Copying…</div>
14+
<div id="detail"></div>
15+
<script src="popup.js"></script>
16+
</body>
17+
</html>

popup.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
async function copyPngDataUrlToClipboard(dataUrl) {
2+
const res = await fetch(dataUrl);
3+
const blob = await res.blob();
4+
await navigator.clipboard.write([
5+
new ClipboardItem({ [blob.type || "image/png"]: blob })
6+
]);
7+
}
8+
9+
(async () => {
10+
const status = document.getElementById("status");
11+
const detail = document.getElementById("detail");
12+
13+
try {
14+
const resp = await chrome.runtime.sendMessage({ type: "CAPTURE_VISIBLE" });
15+
if (!resp?.ok || !resp?.dataUrl) throw new Error(resp?.error || "Capture failed");
16+
17+
await copyPngDataUrlToClipboard(resp.dataUrl);
18+
19+
status.textContent = "Copied ✓";
20+
setTimeout(() => window.close(), 250);
21+
} catch (e) {
22+
console.error(e);
23+
status.textContent = "Failed !";
24+
detail.textContent = String(e);
25+
}
26+
})();

quick-screenshot-clipboard.zip

385 KB
Binary file not shown.

service_worker.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
2+
(async () => {
3+
if (msg?.type !== "CAPTURE_VISIBLE") {
4+
sendResponse({ ok: false, error: "Unknown message" });
5+
return;
6+
}
7+
8+
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
9+
if (!tab?.windowId || !tab?.url) {
10+
sendResponse({ ok: false, error: "No active tab" });
11+
return;
12+
}
13+
14+
if (tab.url.startsWith("chrome://") || tab.url.startsWith("chrome-extension://")) {
15+
sendResponse({ ok: false, error: "Cannot capture chrome:// pages" });
16+
return;
17+
}
18+
19+
const dataUrl = await chrome.tabs.captureVisibleTab(tab.windowId, { format: "png" });
20+
sendResponse({ ok: true, dataUrl });
21+
})().catch((e) => {
22+
console.error("SW error:", e);
23+
sendResponse({ ok: false, error: String(e) });
24+
});
25+
26+
return true; // async
27+
});

0 commit comments

Comments
 (0)