Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/improsocial/impro
An extensible Bluesky client for web impro.social
Something went wrong. Try again.
1.7 kB · 53 lines
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354import { Component } from "/js/components/component.js";import { Signal, ReactiveStore, effect } from "/js/signals.js";
class RenderedMarkdown extends Component { connectedCallback() { if (this.initialized) return; this.initialized = true; this.state = new ReactiveStore("rendered-markdown"); this.state.$dependencies = new Signal.State(null); this.state.$content = new Signal.State(this.getAttribute("content") || ""); // Fetch dependencies Promise.all([ import("/js/lib/dompurify.js"), import("/js/lib/marked.js"), ]).then(([{ default: DOMPurify }, { marked }]) => { this.state.$dependencies.set({ DOMPurify, marked }); }); this.dispose = effect(() => { const dependencies = this.state.$dependencies.get(); if (!dependencies) return; const { DOMPurify, marked } = dependencies; const content = this.state.$content.get(); this.innerHTML = DOMPurify.sanitize(marked.parse(content)); }); // Treat links inside rendered markdown as external this.onLinkClick = (event) => { if (event.target.closest("a")) { event.stopPropagation(); } }; this.addEventListener("click", this.onLinkClick); }
static get observedAttributes() { return ["content"]; }
attributeChangedCallback(name, oldValue, newValue) { if (!this.initialized || oldValue === newValue) return; if (name === "content") { this.state.$content.set(newValue); } }
disconnectedCallback() { if (!this.initialized) return; this.dispose?.(); this.dispose = null; this.removeEventListener("click", this.onLinkClick); }}
RenderedMarkdown.register();