Public
Edited
Aug 11, 2024
Paused
Comments locked
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Object.assign(html`<iframe>`, sandbox ? { sandbox: "" } : {}, {
src: "javascript:'<!DOCTYPE html><p>Hello, World!</p>'",
style: "border: 1px solid;"
})
Insert cell
Insert cell
Insert cell
Insert cell
html`${message?.data || include.srcdoc}`
Insert cell
message?.data
Insert cell
message?.source.location
Insert cell
self.location
Insert cell
Insert cell
viewof svg = embed(
`<svg width="256" height="256" xmlns="http://www.w3.org/2000/svg"><style>@keyframes fade{to{fill:transparent}}@keyframes spin{to{transform:rotateZ(.5turn)}}path{opacity:.75}path:last-of-type{animation:fade 3s .5s cubic-bezier(.35,-.14,.79,1.22) alternate infinite}</style><rect width="256" height="256" fill="#639" rx="50%"/><g style="animation:spin 12s 6s ease-in-out forwards;transform-origin:128px 128px"><path fill="#ff0" d="M128 40 52 172h152Z"/><path fill="red" d="M128 40 52 172l76-44Z"/><path fill="#0f0" d="M128 40v88l76 44Z"/><path fill="#00f" d="m128 128-76 44h152Z"/><path fill="#ff0" d="M128 40 52 172h152Z"/></g></svg>`,
{ loading: "eager" }
)
Insert cell
svg.loading
Insert cell
svg.srcdoc
Insert cell
svg.contentWindow.innerWidth
Insert cell
svg.contentDocument.body.scrollHeight
Insert cell
Insert cell
viewof include = embed`<!DOCTYPE html><p id="${+new Date()}">Hello, <b>World!</b></p>`
Insert cell
include.loading
Insert cell
include.srcdoc
Insert cell
include.contentWindow.location
Insert cell
include.contentWindow.location.href
Insert cell
include.contentWindow.innerWidth
Insert cell
include.contentDocument.body.scrollHeight
Insert cell
Insert cell
mutable message = null
Insert cell
{
const update = (event) => {
if (event.source !== self) return;
mutable message = event;
};

window.addEventListener("message", update, false);

invalidation.then(() => window.removeEventListener("message", update));
}
Insert cell
Insert cell
embed = {
/*!
* Many thanks to Fabian Iwand, Sylvain Lesage, Corey Goldfeder, Mike Pennisi, and Willem van der Veen! - mg
*/
const attr = "srcdoc";
const iframe = Object.assign(html`<iframe>`, {
frameBorder: 0,
sandbox: "allow-same-origin allow-scripts",
width
});
const src = "javascript:self.frameElement.getAttribute('" + attr + "')";
const polyfill = !(attr in iframe) ? { src } : {};

const dom = new DOMParser();
const xml = new XMLSerializer();

const swap = (
(apos) => (m, quote, attr) =>
apos + attr.replace(new RegExp(apos, "g"), quote) + apos
)("'");

return function (srcdoc, { display = true, loading = "lazy" } = {}) {
if (Array.isArray(srcdoc) && srcdoc.raw) {
srcdoc = /* handle tagged template literal */ interpolate(arguments);
}
srcdoc = xml
.serializeToString(
dom.parseFromString(
srcdoc
/* escape ampersands */ .replace(/&(?!amp;)/g, "&amp;")
/* drop comments */ .replace(/<!--[\s\S]*?-->/g, "")
/* drop empty tags */ .replace(/<(\S+)\s*>\s*<[/]\1\s*>/g, ""),
"text/xml"
)
)
.replace(/^\s+/gm, "")
.split(/\n/)
.join("")
.replace(/(")([^"\\]*(?:(?:\1|\\)\1[^"]*)*)\1/g, swap);

const node = Object.assign(
iframe.cloneNode(),
!!display ? {} : { height: 0 }
);

for (const [k, v] of Object.entries(
Object.assign({ loading, srcdoc }, polyfill)
)) {
node.setAttribute.call(node, k, v);
Object.defineProperty(node, k, {
value: /* future-proof!? */ node.getAttribute(k)
});
}

return Object.assign(node, {
value: node,
onload() {
node.contentWindow.parent.postMessage(node.srcdoc);
node.dispatchEvent(new CustomEvent("input"));
}
});
};
}
Insert cell
// @see {@link https://leanpub.com/understandinges6/read#leanpub-auto-tagged-templates}
function interpolate(args) {
/*
* Many thanks to Addy Osmani, Andrea Giammarchi, and Nicholas Zakas! - mg
*/
return args[0].map((x, i) => x + (args[1 + i] || "")).join("");
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more