Published
Edited
Feb 22, 2021
3 stars
Insert cell
Insert cell
function patchAudioContext() {
'use strict';

// These are events on which we can tell the AudioContext to resume playing.
var triggers = ['mousedown', 'keydown'];

var original = window.AudioContext;
var patched = function AudioContext() {
var ctx = new (Function.prototype.bind.apply(original, [null].concat(arguments)));

if(ctx.state !== 'running') {
var onGesture = function() {
ctx.resume();
// Remove all of our event handlers.
triggers.forEach(function(name) { document.removeEventListener(name, onGesture); });
}
// Bind our handlers to listen for user input.
triggers.forEach(function(name) { document.addEventListener(name, onGesture); });
}
return ctx;
};
patched.prototype = window.AudioContext;
patched.prototype.constructor = patched;
window.AudioContext = patched;
}
Insert cell
Insert cell
{
const windowRatio = 16 / 10;
// Note that we are referencing a commit ID instead of "master" because
// master is a branch that may change at any point.
const baseUrl = 'https://rawcdn.githack.com/cabbibo/cabbibo.github.io/b581d51';
// Here we get the page HTML. Because both fetch() and Response.text()
// return Promises we need to use await (or .then()).
let page = await (await fetch(`${baseUrl}/index.html`)).text();
// Now we inject a base URL to ensure that all external resources get
// fetched via rawgit.com.
page = page.replace('<head>', `$& <base href="${baseUrl}/">`);
// Create the script tag that will contain our patch code.
const patchFuncs = [ patchCrossOrigin, patchAudioContext ];
const initScript = DOM.element('script');
// Turn all patch functions into strings, as IIFEs.
initScript.textContent = patchFuncs.map(f => `(${f.toString()})();`).join('');
// Add our scripts after the library scripts.
page = page.replace('<!-- THESE ALWAYS GOES LAST -->', `${initScript.outerHTML} $&`);
// Finally create an iframe and set our modified HTML.
const iframe = DOM.element('iframe', {
srcdoc: page,
// Note: Using the width variable will cause this cell to be
// reevaluated when the window size changes.
width: width,
height: width / windowRatio,
frameborder: 0,
sandbox: 'allow-scripts'
});
// Todo: Prevent scroll in parent page.
return iframe;
}
Insert cell
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