{"id":49652407,"url":"https://github.com/bubkoo/dom-crowbar","last_synced_at":"2026-05-09T07:09:59.784Z","repository":{"id":355460445,"uuid":"1225212343","full_name":"bubkoo/dom-crowbar","owner":"bubkoo","description":"DOM node screenshot extension for Chrome","archived":false,"fork":false,"pushed_at":"2026-05-03T18:21:55.000Z","size":78,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-03T19:30:46.763Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bubkoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-30T03:58:51.000Z","updated_at":"2026-05-03T18:21:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bubkoo/dom-crowbar","commit_stats":null,"previous_names":["bubkoo/dom-crowbar"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bubkoo/dom-crowbar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdom-crowbar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdom-crowbar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdom-crowbar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdom-crowbar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bubkoo","download_url":"https://codeload.github.com/bubkoo/dom-crowbar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdom-crowbar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32679444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-06T05:01:40.790Z","updated_at":"2026-05-06T05:01:41.588Z","avatar_url":"https://github.com/bubkoo.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dom-crowbar\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.4-blue?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![Vite](https://img.shields.io/badge/Vite-5.4-646CFF?logo=vite\u0026logoColor=white)](https://vitejs.dev/)\n[![Chrome Extension](https://img.shields.io/badge/Chrome_Extension-Manifest_V3-4285F4?logo=googlechrome\u0026logoColor=white)](https://developer.chrome.com/docs/extensions/mv3/intro/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n\n\u003e DOM node screenshot extension for Chrome\n\n---\n\n## Overview\n\ndom-crowbar captures any visible DOM node with pixel-level precision.\nIt uses a content-script overlay for selection, background capture orchestration,\nand an offscreen document for crop/stitch/clipboard operations under Manifest V3.\n\n### Core Features\n\n- Click the extension icon to start DOM node selection\n- Pixel-perfect capture of any visible DOM node\n- Support for Canvas and WebGL content\n- Auto-copy to clipboard and download after screenshot\n- Keyboard shortcuts for precise selection control\n\n### Non-Goals\n\n- No cross-browser support (Chrome / Chromium only)\n- No batch screenshots or scheduled tasks\n- No built-in image editing features\n\n---\n\n## Usage\n\n### Basic Flow\n\n1. Click the extension icon\n2. Hover over highlighted nodes\n3. Click or press **Enter** to capture\n4. Screenshot is automatically copied to clipboard and downloaded\n\n### Keyboard Shortcuts\n\nHold **?** or **/** to show the shortcuts panel.\n\n| Key     | Action                     |\n|---------|----------------------------|\n| `?`     | Show shortcuts help (hold) |\n| `[`     | Select parent element      |\n| `]`     | Select child element       |\n| `↑`     | Expand top edge by 1px     |\n| `↓`     | Expand bottom edge by 1px  |\n| `←`     | Expand left edge by 1px    |\n| `→`     | Expand right edge by 1px   |\n| `+`     | Expand all edges by 1px    |\n| `-`     | Shrink all edges by 1px    |\n| `Enter` | Confirm capture            |\n| `Esc`   | Cancel selection           |\n\n---\n\n## How It Works\n\n1. **Activate** - Click extension icon to start DOM selection\n2. **Select** - Hover to highlight, use keyboard to adjust, click or Enter to capture\n3. **Capture** - Background script captures the visible tab\n4. **Crop** - Offscreen document crops the image to selected region\n5. **Export** - Screenshot is auto-copied to clipboard and downloaded\n\nThe extension uses `chrome.tabs.captureVisibleTab` API to capture screenshots at native resolution, then crops to the selected DOM node region.\n\n---\n\n## Tech Stack\n\n| Aspect     | Choice              | Reason                                  |\n|------------|---------------------|-----------------------------------------|\n| Extension  | Manifest V3         | Chrome current standard                 |\n| Language   | TypeScript          | Type safety and better DX               |\n| Screenshot | `captureVisibleTab` | Native capture, high DPI support        |\n| Cropping   | Offscreen Document  | MV3 Service Worker cannot access Canvas |\n| Build Tool | Vite + CRXJS        | Fast builds, hot-reload, MV3 compatible |\n| Test       | Vitest              | Fast, Vite-native test runner           |\n| i18n       | Chrome i18n API     | Built-in localization support           |\n\n---\n\n## Architecture\n\n```text\n┌──────────────────────────────────────────────────────────────────────┐\n│                              Browser                                 │\n│                                                                      │\n│  ┌────────────────────────┐      ┌───────────────────────────────┐   │\n│  │   Action (Click Icon)  │ ──▶  │   Background SW               │   │\n│  └────────────────────────┘      │   background.ts               │   │\n│                                  │   capture.ts                  │   │\n│  ┌────────────────────────┐      │  - ENTER_PICK_MODE            │   │\n│  │   Content Script       │ ◀──▶ │  - CAPTURE_SUCCESS / ERROR    │   │\n│  │   content.ts           │      │  - captureVisibleTab          │   │\n│  │   overlay.ts           │      │  - scroll/tiled strategy      │   │\n│  │   screenshot-result.ts │      │  - download (downloads API)   │   │\n│  └────────────────────────┘      └───────────────┬───────────────┘   │\n│           │                                      │ CROP/STITCH       │\n│           │ NODE_SELECTED                        │ COPY_TO_CLIPBOARD │\n│           ▼                                      ▼                   │\n│  ┌────────────────────────────────────────────────────────────────┐  │\n│  │                      Offscreen Document                        │  │\n│  │                      src/offscreen/index.ts                    │  │\n│  │                      - Canvas crop/stitch                      │  │\n│  │                      - Clipboard API                           │  │\n│  └────────────────────────────────────────────────────────────────┘  │\n└──────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Project Structure\n\n```\nsrc/\n├── background/\n│   └── background.ts         # Service Worker entry point\n├── content/\n│   ├── content.ts            # Content Script entry point\n│   ├── overlay.ts            # Node highlight and selection overlay\n│   └── selector-builder.ts   # CSS selector generator\n├── offscreen/\n│   ├── index.html            # Offscreen document HTML\n│   └── index.ts              # Image crop and clipboard operations\n└── shared/\n    ├── types.ts              # Type definitions\n    ├── constants.ts          # Constants\n    ├── errors.ts             # Error types\n    ├── retry.ts              # Retry utilities\n    ├── logger.ts             # Logging utility\n    └── i18n.ts               # Internationalization\n\npublic/\n├── assets/\n│   ├── icon.svg              # Source icon\n│   ├── icon-16.png           # Generated at build time\n│   ├── icon-48.png           # Generated at build time\n│   └── icon-128.png          # Generated at build time\n└── _locales/\n    ├── en/messages.json      # English translations\n    └── zh_CN/messages.json   # Chinese translations\n```\n\nNote: PNG icons are generated from `public/assets/icon.svg` by `scripts/build-icons.mjs` and are git-ignored.\nIf missing, run `npm run build:icons` once.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Node.js 18+\n- Chrome/Chromium browser\n\n### Install Dependencies\n\n```bash\nnpm install\n```\n\n### Development Mode\n\n```bash\nnpm run dev\n```\n\n`dev` runs icon generation first, so a fresh clone can start directly.\n\n### Watch Mode\n\nFor development with auto-rebuild on file changes:\n\n```bash\nnpm run watch\n```\n\n### Production Build\n\n```bash\nnpm run build\n```\n\n`build` and `watch` automatically run icon generation first.\n\n### Generate Icons Only\n\n```bash\nnpm run build:icons\n```\n\n### Run Tests\n\n```bash\nnpm test\n```\n\n### Load Extension\n\n1. Open `chrome://extensions/`\n2. Enable \"Developer mode\"\n3. Click \"Load unpacked\"\n4. Select the `dist` directory\n\n---\n\n## CI/CD and Chrome Web Store Publishing\n\nRelease and publish documentation has been moved to:\n\n- [docs/release-and-publishing.md](docs/release-and-publishing.md)\n\nWorkflow files:\n\n- [.github/workflows/ci.yml](.github/workflows/ci.yml)\n- [.github/workflows/publish-chrome-web-store.yml](.github/workflows/publish-chrome-web-store.yml)\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbubkoo%2Fdom-crowbar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbubkoo%2Fdom-crowbar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbubkoo%2Fdom-crowbar/lists"}