a demonstration replicated social networking web app built with anproto wiredove.net/
social ed25519 protocols

Scope syntax highlighting to newly rendered content

+26 -11
+26 -1
render.js
··· 7 7 import { noteSeen } from './sync.js' 8 8 import { promptKeypair } from './identify.js' 9 9 import { addBlockedAuthor, addHiddenHash, addMutedAuthor, isBlockedAuthor, removeHiddenHash, removeMutedAuthor, shouldHideMessage } from './moderation.js' 10 - import { ensureQRious } from './lazy_vendor.js' 10 + import { ensureHighlight, ensureQRious } from './lazy_vendor.js' 11 11 import { addReplyToIndex, ensureReplyIndex, getReplyCount, getRepliesForParent } from './reply_index.js' 12 12 13 13 export const render = {} ··· 68 68 timestampObserver.observe(element) 69 69 } 70 70 71 + const highlightCodeIn = async (container) => { 72 + if (!container) { return } 73 + const nodes = Array.from(container.querySelectorAll('pre code, pre')) 74 + if (!nodes.length) { return } 75 + let hljs 76 + try { 77 + hljs = await ensureHighlight() 78 + } catch (err) { 79 + console.warn('highlight load failed', err) 80 + return 81 + } 82 + if (!hljs || typeof hljs.highlightElement !== 'function') { return } 83 + nodes.forEach((node) => { 84 + const target = node.matches('pre') && node.querySelector('code') 85 + ? node.querySelector('code') 86 + : node 87 + if (!target || target.dataset.hljsDone === 'true') { return } 88 + hljs.highlightElement(target) 89 + target.dataset.hljsDone = 'true' 90 + }) 91 + } 92 + 71 93 const updateReplyCount = (parentHash) => { 72 94 const target = replyCountTargets.get(parentHash) 73 95 if (!target) { return } ··· 573 595 : state.baseYaml.body 574 596 state.currentBody = bodySource 575 597 state.contentDiv.innerHTML = await renderBody(bodySource, baseReply) 598 + await highlightCodeIn(state.contentDiv) 576 599 hydrateReplyPreviews(state.contentDiv) 577 600 if (!currentEdit) { 578 601 await applyProfile(state.contentHash, state.baseYaml) ··· 1045 1068 div.classList.remove('material-symbols-outlined') 1046 1069 const bioHtml = await markdown(yaml.bio) 1047 1070 div.innerHTML = `<p><strong>New bio:</strong></p>${bioHtml}` 1071 + await highlightCodeIn(div) 1048 1072 await applyProfile(contentHash, yaml) 1049 1073 await queueLinkedHashes(yaml) 1050 1074 return ··· 1061 1085 updateReplyCount(yaml.reply) 1062 1086 } 1063 1087 div.innerHTML = await renderBody(yaml.body, yaml.reply) 1088 + await highlightCodeIn(div) 1064 1089 hydrateReplyPreviews(div) 1065 1090 await applyProfile(contentHash, yaml) 1066 1091 await queueLinkedHashes(yaml)
-10
route.js
··· 13 13 import { noteInterest } from './sync.js' 14 14 import { isBlockedAuthor } from './moderation.js' 15 15 import { buildProfileHeader } from './profile_header.js' 16 - import { ensureHighlight } from './lazy_vendor.js' 17 16 18 17 const HOME_SEED_COUNT = 3 19 18 const HOME_BACKFILL_DEPTH = 6 ··· 229 228 await render.blob(src, { hash, opened }) 230 229 } 231 230 } 232 - setTimeout(() => { 233 - void ensureHighlight().then((hljs) => { 234 - if (hljs && typeof hljs.highlightAll === 'function') { 235 - hljs.highlightAll() 236 - } 237 - }).catch((err) => { 238 - console.warn('highlight load failed', err) 239 - }) 240 - }, 100) 241 231 } 242 232 243 233 window.onhashchange = async () => {