1hljs.addPlugin({ 2 "after:highlightElement": ({ el, text }) => { 3 const wrapper = el.parentElement; 4 if (wrapper == null) { 5 return; 6 } 7 8 const copyButton = document.createElement("button"); 9 copyButton.classList.add("code__copy"); 10 let buttonTitle = 'Copy'; 11 copyButton.innerHTML = buttonTitle; 12 13 copyButton.onclick = () => { 14 navigator.clipboard.writeText(text); 15 copyButton.innerHTML='Copied!'; 16 setTimeout(() => {copyButton.innerHTML = buttonTitle}, 1500) 17 }; 18 // Append the copy button to the wrapper 19 wrapper.appendChild(copyButton); 20 }, 21}); 22 23// Run `fn` over `items` in small time-boxed slices instead of one long loop, 24// so pages with several code blocks don't tie up the main thread in a single 25// multi-hundred-ms task (each hljs.highlightElement() call is a synchronous, 26// regex-heavy tokenize+render). Total work is unchanged -- this only breaks 27// it into scheduler-friendly chunks, improving TBT/INP without changing the 28// end result. 29function processInChunks(items, fn) { 30 const schedule = window.requestIdleCallback || ((cb) => setTimeout(cb, 0)); 31 let i = 0; 32 function step() { 33 const start = performance.now(); 34 while (i < items.length && performance.now() - start < 8) { 35 fn(items[i]); 36 i++; 37 } 38 if (i < items.length) { 39 schedule(step); 40 } 41 } 42 schedule(step); 43} 44 45// patch legacy code blocks from pre > content to pre > code > content 46// also, wrap legacy code blocks withinh code__wrapper div 47// (kept synchronous and cheap -- just element creation/insertion -- because 48// the highlighting pass below queries for its output and must see it in place) 49document.querySelectorAll('pre.code').forEach((el) => { 50 if (!el.querySelector('code')) { 51 const code = document.createElement('code'); 52 code.textContent = el.textContent; 53 el.textContent = ''; 54 el.appendChild(code); 55 56 const wrapper = document.createElement('div'); 57 wrapper.classList.add("code__wrapper"); 58 el.parentNode.insertBefore(wrapper, el); 59 wrapper.appendChild(el); 60 } 61}); 62 63// The expensive part: highlight.js's regex-based tokenizing/rendering, run 64// once per block. Chunked so several code blocks don't stall the main 65// thread in one long task. 66processInChunks(document.querySelectorAll('pre > code'), (el) => {
67 hljs.highlightElement(el); 68});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.