[Embeds] Embed subdomain landing page (#3501)
* add build output to web build * simplify post-build step by copying everything at once * make script that converts placeholder -> iframe * dynamically resize iframe based on inner content Requires the iframe content to `postMessage` its height back up to the parent * add lang to embed * svg explicit height -> viewBox * add build output to web build * simplify post-build step by copying everything at once * attempt to fix go embed issue * rm changes to bskyweb * remove another bskyweb change * embed landing page * Drop xl breakpoint, too far down * Remove pointer enter behavior * Avoid button width jump * Escape HTML --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
parent
8e29b1f633
commit
4b3ec55732
19 changed files with 482 additions and 57 deletions
90
bskyembed/snippet/embed.ts
Normal file
90
bskyembed/snippet/embed.ts
Normal file
|
@ -0,0 +1,90 @@
|
|||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Window {
|
||||
bluesky: {
|
||||
scan: (element?: Pick<Element, 'querySelectorAll'>) => void
|
||||
}
|
||||
}
|
||||
|
||||
const EMBED_URL = 'https://embed.bsky.app'
|
||||
|
||||
window.bluesky = window.bluesky || {
|
||||
scan,
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for messages from the Bluesky embed iframe and adjust the height of
|
||||
* the iframe accordingly.
|
||||
*/
|
||||
window.addEventListener('message', event => {
|
||||
if (event.origin !== EMBED_URL) {
|
||||
return
|
||||
}
|
||||
|
||||
const id = (event.data as {id: string}).id
|
||||
if (!id) {
|
||||
return
|
||||
}
|
||||
|
||||
const embed = document.querySelector<HTMLIFrameElement>(
|
||||
`[data-bluesky-id="${id}"]`,
|
||||
)
|
||||
|
||||
if (!embed) {
|
||||
return
|
||||
}
|
||||
|
||||
const height = (event.data as {height: number}).height
|
||||
if (height) {
|
||||
embed.style.height = `${height}px`
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Scan the document for all elements with the data-bluesky-aturi attribute,
|
||||
* and initialize them as Bluesky embeds.
|
||||
*
|
||||
* @param element Only scan this specific element @default document @optional
|
||||
* @returns
|
||||
*/
|
||||
function scan(node = document) {
|
||||
const embeds = node.querySelectorAll('[data-bluesky-uri]')
|
||||
|
||||
for (let i = 0; i < embeds.length; i++) {
|
||||
const id = String(Math.random()).slice(2)
|
||||
|
||||
const embed = embeds[i]
|
||||
const aturi = embed.getAttribute('data-bluesky-uri')
|
||||
|
||||
if (!aturi) {
|
||||
continue
|
||||
}
|
||||
|
||||
const iframe = document.createElement('iframe')
|
||||
iframe.setAttribute('data-bluesky-id', id)
|
||||
iframe.src = `${EMBED_URL}/embed/${aturi.slice('at://'.length)}?id=${id}`
|
||||
iframe.width = '100%'
|
||||
iframe.style.border = 'none'
|
||||
iframe.style.display = 'block'
|
||||
iframe.style.flexGrow = '1'
|
||||
iframe.frameBorder = '0'
|
||||
iframe.scrolling = 'no'
|
||||
|
||||
const container = document.createElement('div')
|
||||
container.style.maxWidth = '600px'
|
||||
container.style.width = '100%'
|
||||
container.style.marginTop = '10px'
|
||||
container.style.marginBottom = '10px'
|
||||
container.style.display = 'flex'
|
||||
container.className = 'bluesky-embed'
|
||||
|
||||
container.appendChild(iframe)
|
||||
|
||||
embed.replaceWith(container)
|
||||
}
|
||||
}
|
||||
|
||||
if (['interactive', 'complete'].indexOf(document.readyState) !== -1) {
|
||||
scan()
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', () => scan())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue