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:
@@ -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', () => {
|
||||
|
||||
@@ -247,10 +247,10 @@ export function getSpotifyEmbedTarget(url: string): { type: SpotifyType; id: str
|
||||
export function isSoundCloudTrack(url: string): boolean {
|
||||
try {
|
||||
const { hostname, pathname } = new URL(url);
|
||||
const h = hostname.replace(/^www\./, '');
|
||||
// on.soundcloud.com/<code> is a share short link — the widget follows it.
|
||||
if (h === 'on.soundcloud.com') return pathname.replace(/^\/+|\/+$/g, '').length > 0;
|
||||
if (h !== 'soundcloud.com') return false;
|
||||
// NOTE: on.soundcloud.com short links are NOT handled here — the w.soundcloud
|
||||
// widget resolver doesn't follow the redirect; supporting them needs an oEmbed
|
||||
// round-trip (soundcloud.com/oembed is CORS-enabled) to get the canonical URL.
|
||||
if (hostname.replace(/^www\./, '') !== 'soundcloud.com') return false;
|
||||
// /<artist>/<track|sets/set> — at least two segments, not a bare profile
|
||||
const parts = pathname.replace(/^\/+|\/+$/g, '').split('/').filter(Boolean);
|
||||
return parts.length >= 2;
|
||||
|
||||
Reference in New Issue
Block a user