fix(embeds): quality pass — close button, focus, a11y, perf, SoundCloud revert

From the quality-review agents:
- Revert on.soundcloud.com support: the w.soundcloud widget doesn't follow the
  redirect (needs an oEmbed resolve, deferred).
- Add a Close button to playing video/TikTok embeds and a Collapse button to the
  expanded X post — playback was previously one-way (only escapable by scrolling).
- focus-visible ring on the embed facade (folds resets outline:none, leaving
  keyboard users with no indicator).
- Only subscribe to resize postMessages while the iframe is mounted (was attaching
  a global listener per Instagram/Reddit facade before play).
- TikTok oEmbed fetch now uses AbortController (abort on unmount) + aria-busy /
  'Loading…' label on the resolving spinner.
- Decorative facade thumbnails use alt="" (parent already names them); drop the
  dangling-colon aria-labels when there's no title.
- Cap URL previews at 6 per message so a link-dump can't spawn dozens of fetches.

Tests 728. No CSP change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 00:45:51 -04:00
co-authored by Claude Opus 4.8
parent a28c305835
commit a52c9e12a4
5 changed files with 98 additions and 24 deletions
+3 -3
View File
@@ -132,11 +132,11 @@ test('Spotify target + height', () => {
assert.equal(spotifyEmbedHeight('album'), 352);
});
test('SoundCloud track detection (+ on. short link)', () => {
test('SoundCloud track detection', () => {
assert.equal(isSoundCloudTrack('https://soundcloud.com/artist/some-track'), true);
assert.equal(isSoundCloudTrack('https://soundcloud.com/artist'), false); // bare profile
assert.equal(isSoundCloudTrack('https://on.soundcloud.com/abc123'), true); // share short link
assert.equal(parseMediaEmbed('https://on.soundcloud.com/abc123', 'h')?.provider, 'soundcloud');
// on.soundcloud.com short links intentionally not handled (need oEmbed resolve)
assert.equal(isSoundCloudTrack('https://on.soundcloud.com/abc123'), false);
});
test('buildVideoEmbedUrl: cookie-less YouTube + Vimeo', () => {