From fb9b47616fde83ccc28bbcbc0caee58d7e4e3c3f Mon Sep 17 00:00:00 2001 From: Greg von Nessi Date: Thu, 5 Feb 2026 22:57:32 +0000 Subject: [PATCH] feat: add Tumblr theme embed script Add tumblr-embed.js to the GitHub Pages site. The script finds links pointing to the embed page and replaces them with inline components, working around Tumblr's HTML sanitizer which strips custom elements and iframes from posts. --- demo/public/tumblr-embed.js | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 demo/public/tumblr-embed.js diff --git a/demo/public/tumblr-embed.js b/demo/public/tumblr-embed.js new file mode 100644 index 0000000..a12808c --- /dev/null +++ b/demo/public/tumblr-embed.js @@ -0,0 +1,69 @@ +/** + * Speed-Read Tumblr Embed + * + * Automatically replaces links pointing to the speed-read embed page + * with inline components. + * + * Theme setup — add both script tags before in your Tumblr theme: + * + * + * + * + * Post usage — in the post HTML, add a plain link: + * + * Read + * + * Supported query parameters: + * src - URL to an EPUB, PDF, or CBZ file + * tumblr - Tumblr post URL + * tumblr-proxy - Custom CORS proxy URL + * tumblr-playlist - Google Docs playlist URL + * manifest - chapters.json manifest URL + * height - Reader height (default: 600px) + */ +(function () { + var EMBED_PATH = '/speed-read/embed.html'; + var ATTRS = ['src', 'tumblr', 'tumblr-proxy', 'tumblr-playlist', 'manifest']; + + function init() { + var links = document.querySelectorAll('a[href*="' + EMBED_PATH + '"]'); + + for (var i = 0; i < links.length; i++) { + var link = links[i]; + try { + var url = new URL(link.href); + var params = url.searchParams; + + var hasContent = ATTRS.some(function (attr) { + return params.has(attr); + }); + if (!hasContent) continue; + + var container = document.createElement('div'); + container.style.height = params.get('height') || '600px'; + container.style.width = '100%'; + container.style.margin = '1em 0'; + + var reader = document.createElement('speed-reader'); + reader.style.width = '100%'; + reader.style.height = '100%'; + + for (var j = 0; j < ATTRS.length; j++) { + var value = params.get(ATTRS[j]); + if (value) reader.setAttribute(ATTRS[j], value); + } + + container.appendChild(reader); + link.parentNode.replaceChild(container, link); + } catch (e) { + // leave the link alone if URL parsing fails + } + } + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})();