# Diff Highlighter A Chrome (Manifest V3) extension that highlights `.diff` and `.patch` files in the browser: **additions green, deletions red**, with hunk/file headers styled and the underlying code **syntax-highlighted** by language. Works on GitHub/Bitbucket PR `.diff`/`.patch` URLs, raw files, and local `file://` diffs. Light/dark aware, fast, and fully toggleable. ## How it works - A content script runs only on `text/plain` pages whose URL ends in `.diff`/`.patch` (the `include_globs` matcher covers query strings too, e.g. `…/123.diff?token=…`). - It reads the browser-rendered `
`, parses the unified-diff structure, and:
  1. **Instantly** repaints every line with its diff color (green/red/context/headers).
  2. **Progressively** layers syntax highlighting via [highlight.js](https://highlightjs.org/),
     processed in idle-time chunks so large diffs stay responsive. Above ~50k highlightable
     lines, syntax is skipped to preserve speed (diff colors remain).
- Toggling is instant and reload-free: the popup writes `chrome.storage.sync`, and the
  content script re-renders on change. `Alt+D` flips the master toggle from anywhere.
- Only the `storage` permission is requested — declarative content scripts need no host
  permissions.

## Toggles

| Control | Effect |
| --- | --- |
| **Highlighting** (popup) | Master switch for the green/red diff layer. |
| **Syntax highlighting** (popup) | Layer language-aware token colors on top. |
| `Alt+D` | Flip the master switch (rebind at `chrome://extensions/shortcuts`). |

## Build

Requires Node 20+.

```sh
npm ci
npm run build      # type-checks, then bundles to dist/
npm run watch      # rebuild on change (dev)
```

`dist/` is the unpacked extension (git-ignored).

## Load in Chrome

1. `chrome://extensions` → enable **Developer mode**.
2. **Load unpacked** → select the `dist/` folder.
3. For local diffs, open the extension's **Details** page and enable
   **“Allow access to file URLs.”** Then try `samples/example.diff`.

## Continuous integration (Codeberg / Forgejo Actions)

CI lives in [`.forgejo/workflows/ci.yml`](.forgejo/workflows/ci.yml) and runs
`npm ci → typecheck → build` in a `node:22-bookworm` container — the same steps as a
local build, so a green local build means green CI.

To wire it up on Codeberg:

1. Push this repo to Codeberg:
   ```sh
   git remote add origin https://codeberg.org//diff-highlighter.git
   git push -u origin main
   ```
2. Connect a runner: repo **Settings → Actions → Runners** (or use Codeberg's hosted
   runners). If using a hosted runner, change `runs-on: docker` to its label
   (e.g. `codeberg-tiny`).

## Scope

Triggers on URLs/files whose path ends in `.diff`/`.patch` and that render as plain text.
In-app **HTML** diff views (GitHub's "Files changed", Bitbucket's `/diff` endpoint) are out
of scope — those are full HTML pages, not raw text.

## Layout

```
src/
  manifest.json      MV3 manifest
  content.ts         detect + render + live toggle
  diff-parser.ts     pure diff parsing / language detection
  background.ts      defaults + Alt+D command
  popup/             popup UI
  styles/            diff.css, hljs-theme.css, popup.css (all light/dark)
scripts/             build.mjs (esbuild), make-icons.mjs
.forgejo/workflows/  CI
```