Skip to content

feat: add copy & download buttons to the web file viewer (and fix CSP-blocked modal controls)#56

Merged
Arthur742Ramos merged 1 commit into
mainfrom
arthur742ramos/web-ui-polish
Jun 11, 2026
Merged

feat: add copy & download buttons to the web file viewer (and fix CSP-blocked modal controls)#56
Arthur742Ramos merged 1 commit into
mainfrom
arthur742ramos/web-ui-polish

Conversation

@Arthur742Ramos

Copy link
Copy Markdown
Owner

Summary

The web demo's file-preview modal now has Copy and Download buttons, so users can grab a generated doc's contents without manually selecting text in the preview.

  • Copy uses the async Clipboard API, raced against a 1s timeout and backed by a document.execCommand fallback, so it never hangs and degrades gracefully on browsers/contexts where the async API is unavailable or denied.
  • Download saves the previewed content as a Blob named after the file (e.g. BOOTCAMP.md).

Bonus fix: CSP-blocked modal controls

While wiring the new buttons, I discovered the modal's existing close button (×) and click-outside-to-dismiss were implemented with inline onclick handlers — which the web server's Content-Security-Policy (script-src-attr 'none', set by Helmet) silently blocks. Those controls were effectively dead; the modal could only be closed with the Escape key.

I moved all modal controls to addEventListener, which both complies with the CSP and restores the close/dismiss behavior. There are now zero inline event handlers in the page.

Testing

  • Unit (test/templates.test.ts): asserts the Copy/Download/Close buttons exist, that the page uses addEventListener with no inline onclick (a regression guard for the CSP issue), the clipboard-with-fallback code path, the Promise.race timeout guard, and the Blob download wiring.
  • Playwright (test/playwright/web-ui.e2e.spec.ts): grants clipboard permission, opens a generated file, clicks Copy (asserts the label flips to "Copied!" and back), and clicks Download (asserts a download event with suggestedFilename() === "BOOTCAMP.md").
  • Full suite green: npm test → 1101 passing; Playwright web-ui spec passing; typecheck + lint + build clean.

🤖 Generated with Claude Code

The web demo's file-preview modal now has Copy and Download buttons, so
users can grab a generated doc's contents without manually selecting text.

- Copy uses the async Clipboard API, raced against a 1s timeout and backed by
  a document.execCommand fallback, so it never hangs and degrades gracefully.
- Download saves the previewed content as a Blob named after the file.

While wiring these, found that the modal's existing close button and
click-outside-to-dismiss used inline `onclick` handlers that the server's
Content-Security-Policy (`script-src-attr 'none'`) silently blocked — they
did nothing. Moved ALL modal controls to addEventListener, which both
complies with the CSP and fixes the previously-dead close/dismiss controls.

Tests: templates unit tests assert the buttons, the CSP-safe wiring (no inline
onclick), the clipboard-with-fallback path, and the Blob download. The
Playwright web-ui spec now grants clipboard permission and exercises Copy
(label flips to "Copied!") and Download (asserts the download filename).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Arthur742Ramos Arthur742Ramos merged commit 92c1101 into main Jun 11, 2026
13 checks passed
@Arthur742Ramos Arthur742Ramos deleted the arthur742ramos/web-ui-polish branch June 11, 2026 19:03
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.

2 participants