Skip to content

add --web-snapshot-viewer mode#203

Open
maagenta wants to merge 1 commit intoatauenis:devfrom
maagenta:web-snapshot-viewer
Open

add --web-snapshot-viewer mode#203
maagenta wants to merge 1 commit intoatauenis:devfrom
maagenta:web-snapshot-viewer

Conversation

@maagenta
Copy link
Copy Markdown

@maagenta maagenta commented Apr 5, 2026

Adds a new exclusive proxy mode that renders modern web pages server-side using Playwright and serves them to old browsers as interactive strip images.

When started with --web-snapshot-viewer, all HTTP requests are routed through WebSnapshotViewer instead of the normal proxy flow. The flow is:

  1. Browser requests any URL → proxy returns a lightweight probe page (JS)
  2. JS reads viewport dimensions and redirects to snapshot.webone.internal/snap
  3. Playwright takes a full-page PNG screenshot at the requested viewport size
  4. Screenshot is split into horizontal strips (default 100px height each)
  5. Shell page is returned with tags — only the first visible strips load
  6. As the user scrolls, strips load lazily via JS
  7. Clicks are forwarded to Playwright, changed strips are updated in place
  • WebSnapshotViewer.cs: HTTP router for all snapshot endpoints

  • DimensionProbe.cs: generates the probe page for viewport detection

  • ScreenshotEngine.cs: Playwright wrapper (screenshot, scroll, click)

  • SnapshotPage.cs: generates the HTML shell page with strip images

  • StripManager.cs: splits PNG into strips, hashes each for change detection

  • BlankStrip.cs: generates per-session checkerboard GIF placeholder

  • ScrollHandler.cs: inline scroll sync JS + /scroll-pos endpoint

  • ClickHandler.cs: click overlay JS + /click endpoint

  • ClientStripManager.cs: shared JS helpers (sendCmd, updateStrip, reloadPage)

  • ARCHITECTURE.md: full system documentation

  • --web-snapshot-viewer: enable the mode

  • --snapshot-headed: run Playwright browser in visible (headed) mode

  • --quality N: JPEG quality 1-100 (default 85)

  • --strip-size N: strip height in pixels (default 100)

  • --set-min-threads N: thread pool minimum (default 1000)

  • JPEG encoded as RGB colorspace to avoid YCbCr->RGB AltiVec crash in Safari 1 on Mac OS X 10.3 PPC (vec_ycc_rgb_convert bug)

  • Lazy strip loading: only first viewport/stripHeight+2 strips load initially

  • Blank strip placeholder: per-session checkerboard GIF instead of black/white

  • Scroll sync via new Image() fire-and-forget (no XHR, Safari 1 compatible)

  • Click transport via hidden cmd iframe (Safari 1 compatible AJAX equivalent)

  • Thread pool raised to 1000 to avoid starvation with many concurrent connections

  • Browser pre-warmed at startup so first request does not wait for Playwright

  • Microsoft.Playwright 1.*

  • SixLabors.ImageSharp 3.*

Adds a new exclusive proxy mode that renders modern web pages server-side
using Playwright and serves them to old browsers as interactive strip images.

When started with --web-snapshot-viewer, all HTTP requests are routed through
WebSnapshotViewer instead of the normal proxy flow. The flow is:

1. Browser requests any URL → proxy returns a lightweight probe page (JS)
2. JS reads viewport dimensions and redirects to snapshot.webone.internal/snap
3. Playwright takes a full-page PNG screenshot at the requested viewport size
4. Screenshot is split into horizontal strips (default 100px height each)
5. Shell page is returned with <IMG> tags — only the first visible strips load
6. As the user scrolls, strips load lazily via JS
7. Clicks are forwarded to Playwright, changed strips are updated in place

- WebSnapshotViewer.cs: HTTP router for all snapshot endpoints
- DimensionProbe.cs: generates the probe page for viewport detection
- ScreenshotEngine.cs: Playwright wrapper (screenshot, scroll, click)
- SnapshotPage.cs: generates the HTML shell page with strip images
- StripManager.cs: splits PNG into strips, hashes each for change detection
- BlankStrip.cs: generates per-session checkerboard GIF placeholder
- ScrollHandler.cs: inline scroll sync JS + /scroll-pos endpoint
- ClickHandler.cs: click overlay JS + /click endpoint
- ClientStripManager.cs: shared JS helpers (sendCmd, updateStrip, reloadPage)
- ARCHITECTURE.md: full system documentation

- --web-snapshot-viewer: enable the mode
- --snapshot-headed: run Playwright browser in visible (headed) mode
- --quality N: JPEG quality 1-100 (default 85)
- --strip-size N: strip height in pixels (default 100)
- --set-min-threads N: thread pool minimum (default 1000)

- JPEG encoded as RGB colorspace to avoid YCbCr->RGB AltiVec crash in
  Safari 1 on Mac OS X 10.3 PPC (vec_ycc_rgb_convert bug)
- Lazy strip loading: only first viewport/stripHeight+2 strips load initially
- Blank strip placeholder: per-session checkerboard GIF instead of black/white
- Scroll sync via new Image() fire-and-forget (no XHR, Safari 1 compatible)
- Click transport via hidden cmd iframe (Safari 1 compatible AJAX equivalent)
- Thread pool raised to 1000 to avoid starvation with many concurrent connections
- Browser pre-warmed at startup so first request does not wait for Playwright

- Microsoft.Playwright 1.*
- SixLabors.ImageSharp 3.*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant