Fix embeds (#1375)

* Fix wavlake embed

* Fix invalid DOM property

* Fix iframe message not received

* Fix spotify embed controller and popups

* Allow popups to escape sandbox
This commit is contained in:
ekzyis 2024-09-08 17:32:35 +02:00 committed by GitHub
parent 62556d2154
commit 1822b3fe42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 53 additions and 20 deletions

View File

@ -210,11 +210,18 @@ export const NostrEmbed = memo(function NostrEmbed ({ src, className, topLevel,
const iframeRef = useRef(null) const iframeRef = useRef(null)
useEffect(() => { useEffect(() => {
if (!iframeRef.current) return
const setHeightFromIframe = (e) => { const setHeightFromIframe = (e) => {
if (e.origin !== 'https://njump.me' || !e?.data?.height || e.source !== iframeRef.current.contentWindow) return if (e.origin !== 'https://njump.me' || !e?.data?.height || e.source !== iframeRef.current.contentWindow) return
iframeRef.current.height = `${e.data.height}px` iframeRef.current.height = `${e.data.height}px`
} }
window?.addEventListener('message', setHeightFromIframe) window?.addEventListener('message', setHeightFromIframe)
// https://github.com/vercel/next.js/issues/39451
iframeRef.current.src = `https://njump.me/${id}?embed=yes`
return () => { return () => {
window?.removeEventListener('message', setHeightFromIframe) window?.removeEventListener('message', setHeightFromIframe)
} }
@ -224,12 +231,11 @@ export const NostrEmbed = memo(function NostrEmbed ({ src, className, topLevel,
<div className={classNames(styles.nostrContainer, !show && styles.twitterContained, className)}> <div className={classNames(styles.nostrContainer, !show && styles.twitterContained, className)}>
<iframe <iframe
ref={iframeRef} ref={iframeRef}
src={`https://njump.me/${id}?embed=yes`}
width={topLevel ? '550px' : '350px'} width={topLevel ? '550px' : '350px'}
style={{ maxWidth: '100%' }} style={{ maxWidth: '100%' }}
height={iframeRef.current?.height || (topLevel ? '200px' : '150px')} height={iframeRef.current?.height || (topLevel ? '200px' : '150px')}
frameBorder='0' frameBorder='0'
sandbox='allow-scripts allow-same-origin allow-popups' sandbox='allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox'
allow='' allow=''
/> />
{!show && {!show &&
@ -241,6 +247,49 @@ export const NostrEmbed = memo(function NostrEmbed ({ src, className, topLevel,
) )
}) })
const SpotifyEmbed = function SpotifyEmbed ({ src, className }) {
const iframeRef = useRef(null)
// https://open.spotify.com/track/1KFxcj3MZrpBGiGA8ZWriv?si=f024c3aa52294aa1
// Remove any additional path segments
const url = new URL(src)
url.pathname = url.pathname.replace(/\/intl-\w+\//, '/')
useEffect(() => {
if (!iframeRef.current) return
const id = url.pathname.split('/').pop()
// https://developer.spotify.com/documentation/embeds/tutorials/using-the-iframe-api
window.onSpotifyIframeApiReady = (IFrameAPI) => {
const options = {
uri: `spotify:episode:${id}`
}
const callback = (EmbedController) => {}
IFrameAPI.createController(iframeRef.current, options, callback)
}
return () => { window.onSpotifyIframeApiReady = null }
}, [iframeRef.current, url.pathname])
return (
<div className={classNames(styles.spotifyWrapper, className)}>
<iframe
ref={iframeRef}
title='Spotify Web Player'
src={`https://open.spotify.com/embed${url.pathname}`}
width='100%'
height='152'
allowFullScreen
frameBorder='0'
allow='encrypted-media; clipboard-write;'
style={{ borderRadius: '12px' }}
sandbox='allow-scripts allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-presentation'
/>
</div>
)
}
export const Embed = memo(function Embed ({ src, provider, id, meta, className, topLevel, onError }) { export const Embed = memo(function Embed ({ src, provider, id, meta, className, topLevel, onError }) {
const [darkMode] = useDarkMode() const [darkMode] = useDarkMode()
const [overflowing, setOverflowing] = useState(true) const [overflowing, setOverflowing] = useState(true)
@ -277,31 +326,15 @@ export const Embed = memo(function Embed ({ src, provider, id, meta, className,
<iframe <iframe
src={`https://embed.wavlake.com/track/${id}`} width='100%' height='380' frameBorder='0' src={`https://embed.wavlake.com/track/${id}`} width='100%' height='380' frameBorder='0'
allow='encrypted-media' allow='encrypted-media'
sandbox='allow-scripts' sandbox='allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-same-origin'
/> />
</div> </div>
) )
} }
if (provider === 'spotify') { if (provider === 'spotify') {
// https://open.spotify.com/track/1KFxcj3MZrpBGiGA8ZWriv?si=f024c3aa52294aa1
// Remove any additional path segments
const url = new URL(src)
url.pathname = url.pathname.replace(/\/intl-\w+\//, '/')
return ( return (
<div className={classNames(styles.spotifyWrapper, className)}> <SpotifyEmbed src={src} className={className} />
<iframe
title='Spotify Web Player'
src={`https://open.spotify.com/embed${url.pathname}`}
width='100%'
height='152'
allowfullscreen=''
frameBorder='0'
allow='encrypted-media; clipboard-write;'
style={{ borderRadius: '12px' }}
sandbox='allow-scripts'
/>
</div>
) )
} }