The easiest way to open issue is to follow one of the templates.
It’s always helpful it you include debug info (Link Hints version, browser version, configuration, etc.). Click the Link Hints toolbar button, press “Copy debug info” and paste in the issue.
If you’d like to make a pull request, here’s what you need to know.
- Node.js 18 with npm 8.
- Latest Chrome or Chromium.
- Latest Firefox Developer Edition or Firefox Nightly.
- Clone this repository.
- Run
npm ci
to install dependencies. - Run
npm test
to verify the installation.
- web-ext for development, building and linting.
- Rollup for
import
/export
and npm package support. - TypeScript for type checking.
- ESLint for linting.
- Prettier for automatic code formatting.
- Sucrase for compiling TypeScript type annotation and JSX.
- Preact for easily making the options UI and the website.
- WebExtension Polyfill for using the
browser
API both in Chrome and Firefox.
- The repo root contains mostly configuration files.
src/
contains the source code for the extension.scripts/
contains a couple of build scripts.html/
contains lots of test pages for the extension.docs/
contains the source code for the website (https://lydell.github.io/LinkHints/).@types/
contains TypeScript declarations, for npm packages that lack them and for global variables.
These directories are generated and gitignored:
compiled/
is the compiled version ofsrc/
.compiled-docs/
is the compiled version ofdocs/
and is served on https://lydell.github.io/LinkHints/.dist-chrome/
anddist-firefox/
contains production builds of the extension.
The most important files:
project.config.ts
contains information about the whole project, all in one place. Other config files and build scripts read from it. For example, it maps entrypoint files insrc/
to output files incompiled/
.rollup.config.js
defines howcompiled/
is made. Rollup compiles and bundles JavaScript; generatesmanifest.json
, HTML files and SVG icons; copies the WebExtension Polyfill, CSS files, and PNG icons; and defines a couple of global variables (see also@types/globals.d.ts
).web-ext-config.js
configures web-ext, both for building and for running.custom.config.example.js
can be copied intocustom.config.js
to customizeweb-ext run
as well as default options for development.src/manifest.ts
is called via Rollup and generatesmanifest.json
. In fact, all.ts
files directly insidesrc/
are called via Rollup and generate other files.src/icons.tsx
generates all SVG icons (even outsidecompiled/
).src/icons/
contains PNG versions of those. They can be updated by runningnpm run png-icons
(which requires Inkscape and OptiPNG). You can preview all icons by openingcompiled/icons/test.html
in a browser.src/html.tsx
generates HTML files. All HTML files are very minimal. JavaScript is used to render content.src/css.ts
injects the colors defined inproject.config.ts
into CSS files.
Compilation pipeline:
project.config.ts .--> dist-chrome/
rollup.config.js web-ext-config.js /
src/ ---------------------> compiled/ ----------------------
\
'--> dist-firefox/
Code structure:
src/background/
contains the main code of the extension.src/worker/
is loaded into every frame of every tab and is responsible for listening to key presses and keeping track of clickable elements.src/renderer/
is loaded into the top frame of every tab and draws the link hints and text underlines.src/popup/
renders the toolbar button popup.src/options/
renders the options UI.src/shared/
contains functions and types shared by all of the above.
All of the above directories, except src/shared/
, have a Program.ts
file with a Program
class inside. The different “programs” talk to each by exchanging messages with src/background/
. The messages are defined in src/shared/messages.ts
. The Program.ts
files are bootstrapped from the main.ts
files next to them, which are the main entrypoints.
When developing, you need to start a watcher (Rollup) that compiles the code as you change it:
npm run watch
It is recommended to set up TypeScript, ESLint and Prettier integrations in your editor. You can also run these tools from the command line:
npx tsc
npx eslint . --fix
npx prettier . --write
See package.json
for details and additional scripts.
Open Chrome/Firefox, with a new profile where Link Hints is pre-installed:
npm run chrome
# or:
npm run firefox
The extension is automatically reloaded when files inside compiled/
change.
The above commands are wrappers around web-ext run
. To customize how Chrome/Firefox is run, copy custom.config.example.js
to custom.config.js
. The latter file is gitignored, so you can change it however you wish.
It’s also possible to develop in Chrome without using npm run chrome
.
- Open
chrome://extensions
. - Enable “Developer mode” there.
- Click “Load unpacked”.
- Choose the
compiled/
directory in this repo.
Link Hints should now be installed. You need to press the refresh button after you make changes to the code.
npm start
starts npm run watch
, npm run firefox
and npm run chrome
all at once using run-pty.
Open compiled-docs/index.html
in a browser.
If you want to install a locally built version of Link Hints, follow these instructions.
You can install Link Hints as an “unpacked” extension, as mentioned in the Manual workflow in Chrome section.
However, for daily use you might not want to depend on the compiled/
directory to always exist and contain correct files. For example, if you run npm run build:firefox
, the compiled/
directory will contain Firefox-specific code and won’t work in Chrome.
The alternative is to pack the extension and install that.
- Run
npm run build:chrome
. - Open
chrome://extensions
. - Enable “Developer mode” there.
- Drag and drop
dist-chrome/link_hints-X.X.X.crx
into the page. (Note:.crx
, not.zip
.)
Note: The first time you run npm run build:chrome
, the file dist-chrome/key.pem
is generated. Keep that file. Otherwise Chrome will install a duplicate Link Hints rather than update the previous version the next time you build and install.
Note: Regular Firefox does not allow installing unsigned extensions. You can sign the extension yourself, but it’s easier to use Firefox Developer Edition instead. (You can also use Firefox Nightly or unbranded builds).
- Run
npm run build:firefox
. - Go to
about:config
. - Set
xpinstall.signatures.required
tofalse
. (Note: This does not work in regular Firefox – see above.) - Go to
File > Open File…
or pressctrl+O
. - Choose
dist-firefox/link_hints-X.X.X.xpi
. (Note:.xpi
, not.zip
.)
Note: If you regularly develop for Chrome, you might want to run npm run build:firefox && npm run compile
instead of just npm run build:firefox
. Otherwise your compiled/
directory will contain Firefox-specific code that won’t work in Chrome. npm run compile
is like npm run watch
but it only runs once and does not start watching for changes.