A lightweight, stateless text highlighter for Firefox. Select text, highlight it, and refresh the page to clear.
JustHighlight operates entirely within the DOM. It does not use databases, does not make network requests, and does not collect or transmit any data. Highlights exist only in memory and are cleared on page refresh.
- 5 highlight colors — Yellow, Pink, Green, Blue, Red
- Keyboard shortcuts —
Alt+Sto highlight,Alt+Cto cycle colors - Context menu — Right-click with dynamic "Highlight" / "Un-highlight" labels
- Toggle — Same action adds or removes a highlight
- Paint over — Select any word within a highlighted block and repaint it a different color
- Partial un-highlight — Select a portion of highlighted text and remove just that part
- Live recolor — Select highlighted text and press
Alt+Cto cycle its color - WASM contrast engine — C compiled to a ~200-byte WASM binary for text readability
- Customizable keybinds — Configure shortcuts in the extension popup
-
Install build dependencies (
clang,wasm-ld,cppcheck):make install
This auto-detects your package manager (apt, dnf, pacman, brew) and installs missing tools.
-
Build the WASM binary:
make build
This runs
cppcheckstatic analysis and compileswasm/engine.c→wasm/engine.wasm. -
Load in Firefox:
- Navigate to
about:debugging→ This Firefox - Click Load Temporary Add-on
- Select the
manifest.jsonfile from this directory
- Navigate to
make packageThis builds and creates web-ext-artifacts/justhighlight.zip ready for upload to addons.mozilla.org.
| Command | Description |
|---|---|
make install |
Install required build tools |
make build |
Run static analysis and compile the WASM binary |
make check |
Run cppcheck static analysis only |
make package |
Build and package extension as .zip for AMO |
make clean |
Remove all compiled artifacts |
make help |
List all available targets |
| Action | Trigger |
|---|---|
| Highlight selected text | Alt+S or right-click → Highlight Text → choose a color |
| Remove highlight | Select highlighted text → Alt+S or right-click → Un-highlight Text → Remove Highlight |
| Change highlight color | Right-click highlighted text → Un-highlight Text → pick a new color |
| Cycle color | Alt+C (also recolors selected highlights in real-time) |
| Repaint a word in a highlighted block | Select the word → right-click → pick a new color |
| Un-highlight part of a block | Select the portion → Alt+S |
| Change settings | Click the extension icon in the toolbar |
JustHighlight/
├── manifest.json # Firefox MV3 manifest
├── Makefile # Build: cppcheck → clang → wasm-ld → package
├── wasm/
│ └── engine.c # BT.709 luminance → dark/light text decision
├── content/
│ ├── content.js # DOM highlighting, WASM bridge, keybinds
│ └── styles.css # Highlight color and contrast classes
├── background/
│ └── background.js # Context menu, message relay
├── popup/
│ ├── popup.html # Settings UI
│ ├── popup.css # Dark-mode popup styling
│ └── popup.js # Color picker, keybind capture
├── assets/ # Extension icons (16–256px)
└── _locales/en/
└── messages.json # i18n strings
- The user selects text and triggers a highlight via a keybind or the context menu.
content.jsuses aTreeWalkerto collect text nodes across element boundaries within the selection.- Each text node is wrapped in a
<mark class="wh-highlight wh-yellow wh-text-dark">element. - The text color class (
wh-text-darkorwh-text-light) is determined by the WASM engine, which calculates BT.709 perceived luminance of the highlight background color. - Partial recolor/removal: When a user selects a subset of highlighted text,
extractNodeFromMark()surgically splits the<mark>element at the selection boundaries, preserving the surrounding highlight while freeing the selected text for recoloring or removal. - To remove a highlight, the
<mark>wrapper is unwrapped and text nodes are merged vianormalize(). - On page refresh, all highlights are cleared — they exist only as DOM nodes in memory.
The contrast engine (wasm/engine.c) is a zero-dependency, zero-libc C function compiled to WebAssembly. It uses ITU-R BT.709 luminance coefficients scaled to integer math to avoid floating-point:
luminance = 2126·R + 7152·G + 722·B
threshold = 1,275,000 (midpoint: 0.5 × 255 × 10000)
If the background luminance exceeds the threshold, dark text is used; otherwise, light text. A pure-JS fallback with identical logic is included for environments where WASM loading fails.
The wasm-unsafe-eval Content Security Policy directive is required in the manifest to allow WebAssembly.instantiate() on extension pages. This is the standard Mozilla-recommended pattern and does not relax security for web pages — it applies only to the extension's own pages.
JustHighlight requests the minimum permissions necessary:
| Permission | Why |
|---|---|
activeTab |
Access the active tab's DOM to insert and remove <mark> highlight elements |
storage |
Persist user preferences (selected color, keybind configuration) via browser.storage.local |
menus |
Create the right-click context menu for highlight actions |
No host permissions, no network access, no remote code execution.
JustHighlight does not collect, store, transmit, or share any user data.
- No data collection — The extension does not access, read, or record any personal information, browsing history, page content, or user activity.
- No network requests — The extension makes zero network connections. All code runs locally. The WASM binary is bundled within the extension package.
- No analytics or tracking — No telemetry, no analytics beacons, no third-party services.
- Local storage only —
browser.storage.localis used exclusively for user preferences (highlight color and keyboard shortcuts). This data never leaves the browser. - Stateless highlights — Highlighted text exists only as DOM nodes in the current page's memory. No page content is ever persisted or recorded. All highlights vanish on page refresh.
- No private browsing data — The extension does not store any data from private browsing sessions.
This extension fully complies with Mozilla's Add-on Policies.