feat: Implement Gogh Theme Engine with options page, theme parsing, and semantic theme derivation
We're cooked. <skull emoji> - Added options page for YAML palette editing, live color preview, and diagnostics. - Implemented theme engine to parse Gogh YAML palettes and derive semantic themes. - Configured TypeScript and Vite for building the extension. - Created new tab and popup HTML pages with corresponding scripts and styles. - Established storage management for user configurations in Chrome storage. - Added icons for the extension and updated manifest for MV3 compatibility.
This commit is contained in:
130
gogh-theme-engine/README.md
Normal file
130
gogh-theme-engine/README.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Gogh Theme Engine
|
||||
|
||||
A production-grade Chrome Extension (Manifest V3) that applies Gogh-style 16-color terminal palettes to all web pages by intelligently computing and rewriting styles at runtime using perceptual OKLCH color remapping.
|
||||
|
||||
## Features
|
||||
|
||||
- **OKLCH Perceptual Color Model** — All color math uses OKLCH for perceptually uniform transformations
|
||||
- **Semantic Theme Derivation** — Automatically maps 16 terminal colors to semantic roles (error, success, accent, etc.) using hue + brightness analysis
|
||||
- **Smart DOM Processing** — TreeWalker-based traversal, MutationObserver with batched/debounced updates, Shadow DOM support
|
||||
- **WCAG Contrast Enforcement** — Ensures minimum 4.5:1 contrast ratio for text
|
||||
- **Gradient & SVG Support** — Parses and transforms CSS gradients and inline SVG fill/stroke
|
||||
- **Dynamic CSS Class Generation** — Reuses CSS classes instead of inline styles for performance
|
||||
- **Per-site Toggle** — Enable/disable theming on a per-domain basis
|
||||
- **Intensity Slider** — Blend between original and themed colors (0–100%)
|
||||
- **Options Page** — YAML editor, live preview, contrast diagnostics, site management
|
||||
|
||||
## Build Instructions
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js ≥ 18
|
||||
- npm ≥ 9
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
cd gogh-theme-engine
|
||||
npm install
|
||||
```
|
||||
|
||||
### Development Build (with watch)
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Production Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Load in Chrome
|
||||
|
||||
1. Run `npm run build`
|
||||
2. Open `chrome://extensions/`
|
||||
3. Enable **Developer mode**
|
||||
4. Click **Load unpacked**
|
||||
5. Select the `dist/` folder
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── background.ts # Service worker — storage, per-domain toggle, messaging
|
||||
├── content.ts # Content script — DOM processing, style injection, coordination
|
||||
├── color.ts # OKLCH color engine — all color math and transforms
|
||||
├── themeEngine.ts # YAML parsing, validation, semantic theme derivation
|
||||
├── observer.ts # DOM observation — TreeWalker, MutationObserver, Shadow DOM
|
||||
├── js-yaml.d.ts # Type declarations for js-yaml
|
||||
└── options/
|
||||
├── options.html # Options page UI
|
||||
└── options.ts # Options page controller
|
||||
|
||||
public/
|
||||
├── manifest.json # Manifest V3 configuration
|
||||
└── icons/ # Extension icons
|
||||
```
|
||||
|
||||
## Palette Format
|
||||
|
||||
Provide a YAML palette in Gogh format:
|
||||
|
||||
```yaml
|
||||
name: My Theme
|
||||
author: Your Name
|
||||
variant: dark
|
||||
color_01: "#282a36"
|
||||
color_02: "#ff5555"
|
||||
color_03: "#50fa7b"
|
||||
color_04: "#f1fa8c"
|
||||
color_05: "#bd93f9"
|
||||
color_06: "#ff79c6"
|
||||
color_07: "#8be9fd"
|
||||
color_08: "#f8f8f2"
|
||||
color_09: "#44475a"
|
||||
color_10: "#ff6e6e"
|
||||
color_11: "#69ff94"
|
||||
color_12: "#ffffa5"
|
||||
color_13: "#d6acff"
|
||||
color_14: "#ff92df"
|
||||
color_15: "#a4ffff"
|
||||
color_16: "#ffffff"
|
||||
background: "#282a36"
|
||||
foreground: "#f8f8f2"
|
||||
cursor: "#f8f8f2"
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Color Pipeline
|
||||
|
||||
1. **Parse** — CSS color strings are parsed into RGBA
|
||||
2. **Convert** — RGBA → sRGB → Linear RGB → OKLAB → OKLCH
|
||||
3. **Classify** — Colors are classified as neutral (achromatic) or chromatic with a hue bucket
|
||||
4. **Remap** — Neutral colors map to surface/background bands; chromatic colors map to semantic roles
|
||||
5. **Contrast** — WCAG contrast is enforced by adjusting the L (lightness) channel
|
||||
6. **Blend** — Final color is blended with original based on intensity setting
|
||||
7. **Cache** — Results are memoized by color + context key
|
||||
|
||||
### Theme Derivation
|
||||
|
||||
Instead of fixed index mapping, semantic roles are derived by analyzing each palette color's OKLCH properties:
|
||||
- Red hue range → `error`
|
||||
- Green → `success`
|
||||
- Blue/Cyan → `accentPrimary` / `info`
|
||||
- Yellow/Orange → `warning`
|
||||
- Purple → `accentSecondary`
|
||||
- Low chroma → `muted`
|
||||
- Surface/border colors are synthesized from background by shifting lightness
|
||||
|
||||
## Architecture Notes
|
||||
|
||||
- No naive CSS inversion or global filters
|
||||
- `TreeWalker` for initial traversal (faster than `querySelectorAll`)
|
||||
- `MutationObserver` with `requestIdleCallback` batching
|
||||
- `WeakSet` for tracking processed nodes
|
||||
- `Element.prototype.attachShadow` monkey-patching for shadow DOM
|
||||
- Dynamic CSS class generation with reuse to minimize inline styles
|
||||
- Transform results cached with LRU-like eviction (max 8192 entries)
|
||||
Reference in New Issue
Block a user