Skip to content

A browser extension for copying tabs to the clipboard in a variety of formats.

License

Notifications You must be signed in to change notification settings

hansifer/tab-copy

Repository files navigation

Tab Copy

A browser extension for copying tabs to the clipboard in a variety of formats

 
 

Features

  • Copy the current tab, tabs in the current window, or all tabs. Optionally group tabs by window.

  • Select from a wide variety of formats like Link, URL, Title & URL, Markdown, CSV, JSON, HTML, and more

  • Create your own formats with powerful format templates

  • Choose between using a popup or copying tabs with one click

  • Define keyboard shortcuts for your most commonly used ranges and formats

  • Add copy actions to web page context menus

  • Set up filtering for tabs you want to omit

  • Fine-tune your experience with a robust set of options

Read the usage docs for more.

Availability

Tab Copy is currently available for Chrome and other Chromium-based browsers.

Help support this project

Please consider helping out with a donation to enable the continued development and maintenance of this project.

Check out what's been done so far and what's planned.

Developing

Setup

  1. Ensure you're on Node.js version 18 or newer
  2. Run npm install
  3. Run npm run dev to generate build folder output
  4. Open chrome://extensions/
  5. Ensure Developer mode is toggled on
  6. Click Load unpacked and select the build folder

Running

npm run dev

Debugging

Popup

Right-click the extension icon, then click Inspect popup.

You can also access the popup in a separate tab at:

chrome-extension://replaceWithExtensionId/popup.html

Options

Open the options page directly at:

chrome-extension://replaceWithExtensionId/options.html

Known issues

  • npm run dev fails to output all necessary files
    • /icons and some /img files in /public do not get copied
    • pages listed in vite config's build.rollupOptions.input are not output
    • as a workaround, you can use npm run dev_workaround, which will automatically rebuild but not auto-refresh

Tech notes

This project was scaffolded with create-chrome-ext

Legacy clipboard write

Non-popup copy triggers like keyboard shortcuts, context menus, and one-click copy cannot use the Clipboard API because of limitations introduced by Manifest v3. Such copy actions need to be processed by the background process, which is now required to be a service worker. Service workers (and more broadly web workers) have limited access to DOM APIs and the Clipboard API is not among those permitted.

The solution is to use an offscreen document to process non-popup initiated clipboard writes. This comes with some challenges as offscreen documents have somewhat nuanced behaviors and limitations and require their lifecycle to be managed by the app. Additionally, while an offscreen document provides access to DOM APIs, it's still not possible to use the Clipboard API here since the API's write() method requires the document to be focused. The offscreen document must therefore use a legacy clipboard write approach involving programmatically setting the value of a Textarea element to the desired content, selecting the content, and subsequently calling document.execCommand('copy').

While the legacy clipboard write approach works, care must be taken when used in an offscreen document context. To prevent race conditions that lead to silent copy failures, offscreen document teardown cannot happen immediately after the execCommand('copy') call. To address this and related concerns, Tab Copy implements a single offscreen document servicing multiple use cases and manages its lifecycle by spinning up a document on-demand, ensuring only one instance exists at a time, and closing it after a period of inactivity.

Offscreen document plumbing and management is implemented in the offscreen actions module. The clipboard utility module contains functions for both standard and legacy clipboard writes.

Direct DOM calls vs React

While this is a React app, the popup itself is implemented with HTML and vanilla JS using direct DOM calls. The original intent was primarily to optimize load speed, although whether this has any meaningful effect is an open question. The popup's complexity has grown considerably, shifting the value of the performance/maintainability tradeoff.

License

This project is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. See the LICENSE file for more details.

About

A browser extension for copying tabs to the clipboard in a variety of formats.

Resources

License

Stars

Watchers

Forks

Packages

No packages published