Skip to content

OpalAayan/JustHighlight

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JustHighlight logo

A lightweight, stateless text highlighter for Firefox. Select text, highlight it, and refresh the page to clear.

License: MIT Firefox: MV3 WASM

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.

Features

  • 5 highlight colors — Yellow, Pink, Green, Blue, Red
  • Keyboard shortcutsAlt+S to highlight, Alt+C to 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+C to 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

From Source

  1. Install build dependencies (clang, wasm-ld, cppcheck):

    make install

    This auto-detects your package manager (apt, dnf, pacman, brew) and installs missing tools.

  2. Build the WASM binary:

    make build

    This runs cppcheck static analysis and compiles wasm/engine.cwasm/engine.wasm.

  3. Load in Firefox:

    • Navigate to about:debuggingThis Firefox
    • Click Load Temporary Add-on
    • Select the manifest.json file from this directory

Package for AMO Submission

make package

This builds and creates web-ext-artifacts/justhighlight.zip ready for upload to addons.mozilla.org.

Build Targets

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

Usage

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 TextRemove 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

Project Structure

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

How It Works

  1. The user selects text and triggers a highlight via a keybind or the context menu.
  2. content.js uses a TreeWalker to collect text nodes across element boundaries within the selection.
  3. Each text node is wrapped in a <mark class="wh-highlight wh-yellow wh-text-dark"> element.
  4. The text color class (wh-text-dark or wh-text-light) is determined by the WASM engine, which calculates BT.709 perceived luminance of the highlight background color.
  5. 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.
  6. To remove a highlight, the <mark> wrapper is unwrapped and text nodes are merged via normalize().
  7. On page refresh, all highlights are cleared — they exist only as DOM nodes in memory.

WASM Contrast Engine

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.

Permissions

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.

Privacy Policy

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 onlybrowser.storage.local is 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.

License

MIT

About

A small text highlighting firefox extention written in WASM(C) and JS [Keyboard driven]

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages