fix(embeds): second-pass review — Reddit auto-height, sandbox, Vimeo/Shorts gaps
From the second review pass (agents inspected providers' live embed scripts):
- FIX Reddit auto-height (was broken): embed.reddit.com posts
{ type:'resize.embed', data:<height> } — height is under 'data', not 'height',
so it never resized and clipped taller posts (scrolling=no). Add that shape.
- Align TweetEmbed sandbox with EMBED_SANDBOX (adds allow-popups-to-escape-sandbox)
so links/login popups opened from inside a tweet aren't crippled.
- Vimeo: resolve channel/group/album video forms (vimeo.com/channels/{n}/{id} etc.),
not just paths starting with the id.
- Mobile Shorts: m.youtube.com/shorts/{id} now renders portrait 9:16, not landscape.
- Move extractEmbedHeight into videoEmbed.ts and unit-test all three resize shapes
(Instagram MEASURE / Reddit resize.embed / Twitter twttr.private.resize).
Agents confirmed everything else current & robust (Dailymotion geo host, Tidal
gridify, sandbox tokens are a safe superset, X still on platform.twitter.com,
550px cap). Tests 21 in this suite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import { onEnterOrSpace } from '../../utils/keyboard';
|
||||
import { useSetting } from '../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
import {
|
||||
extractEmbedHeight,
|
||||
getTikTokVideoId,
|
||||
getTweetId,
|
||||
isTikTokLink,
|
||||
@@ -566,36 +567,6 @@ const EMBED_MAX_HEIGHT = 1400;
|
||||
const EMBED_SANDBOX =
|
||||
'allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-presentation';
|
||||
|
||||
// Pull a content height out of the various providers' postMessage shapes.
|
||||
function extractEmbedHeight(data: unknown): number | undefined {
|
||||
if (!data || typeof data !== 'object') return undefined;
|
||||
const d = data as {
|
||||
type?: string;
|
||||
height?: number;
|
||||
details?: { height?: number };
|
||||
'twttr.embed'?: unknown;
|
||||
};
|
||||
// Instagram: { type: 'MEASURE', details: { height } }
|
||||
if (d.type === 'MEASURE' && typeof d.details?.height === 'number') return d.details.height;
|
||||
// Twitter/X: { 'twttr.embed': [{ method: 'twttr.private.resize', params: [{ height }] }] }
|
||||
const tw = d['twttr.embed'];
|
||||
if (tw) {
|
||||
const calls = (Array.isArray(tw) ? tw : [tw]) as Array<{
|
||||
method?: string;
|
||||
params?: Array<{ height?: number }>;
|
||||
}>;
|
||||
for (let i = 0; i < calls.length; i += 1) {
|
||||
const c = calls[i];
|
||||
if (c?.method === 'twttr.private.resize' && typeof c.params?.[0]?.height === 'number') {
|
||||
return c.params[0].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reddit / generic: { height }
|
||||
if (typeof d.height === 'number') return d.height;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Variable-height iframe embeds (Twitter/Instagram/Reddit) report their content
|
||||
// height via postMessage; listen — scoped to the allowed origins + OUR iframe —
|
||||
// and grow to fit. `origins` must be a stable reference.
|
||||
@@ -644,7 +615,7 @@ function TweetEmbed({ id }: { id: string }) {
|
||||
)}&theme=${theme}&dnt=true`}
|
||||
title="Post on X"
|
||||
style={{ height: `${height}px` }}
|
||||
sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"
|
||||
sandbox={EMBED_SANDBOX}
|
||||
allow="autoplay; encrypted-media; picture-in-picture; fullscreen"
|
||||
loading="lazy"
|
||||
scrolling="no"
|
||||
|
||||
Reference in New Issue
Block a user