1/* Credit: 2 * - https://stackoverflow.com/a/987376/1207769 3 * - https://www.w3schools.com/howto/howto_js_copy_clipboard.asp 4 */ 5function selectAndCopy(element) { 6 if (document.body.createTextRange) { //ms 7 var range = document.body.createTextRange(); 8 range.moveToElementText(element); 9 range.select(); 10 } 11 else if (window.getSelection) { //all others 12 var selection = window.getSelection(); 13 var range = document.createRange(); 14 range.selectNodeContents(element); 15 selection.removeAllRanges(); 16 selection.addRange(range); 17 } 18 document.execCommand("copy"); 19} 20 21// Load emgithub embeds with the correct style for the current light/dark theme. 22// The _includes/code template emits a <div class="emgithub-embed" data-src-base="..."> 23// placeholder (URL without &style=). We inject the <script> tag at runtime so the 24// style can match the active theme, and re-inject when the user toggles the theme. 25(function () { 26 function emgithubStyle() { 27 return document.documentElement.getAttribute('data-theme') === 'dark' 28 ? 'github-dark' : 'github'; 29 } 30 31 function loadEmbed(div) { 32 div.innerHTML = ''; 33 var script = document.createElement('script'); 34 script.src = div.dataset.srcBase + '&style=' + emgithubStyle(); 35 div.appendChild(script); 36 } 37 38 function loadAllEmbeds() { 39 document.querySelectorAll('.emgithub-embed').forEach(loadEmbed); 40 } 41 42 if (document.readyState === 'loading') { 43 document.addEventListener('DOMContentLoaded', loadAllEmbeds); 44 } else { 45 loadAllEmbeds(); 46 } 47 48 // Re-render when the user toggles light/dark (theme.js sets data-theme on <html>). 49 new MutationObserver(function (mutations) { 50 for (var i = 0; i < mutations.length; i++) { 51 if (mutations[i].attributeName === 'data-theme') { loadAllEmbeds(); return; } 52 } 53 }).observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); 54})(); 55 56// Splice in a "Copy" button next to each code block. 57document.querySelectorAll("pre").forEach(function(pre) { 58 if (pre.childElementCount != 1) return; 59 var code = pre.children[0]; 60 if (code.nodeName != "CODE") return; 61 62 var copy = document.createElement("A"); 63 copy.innerHTML = "Copy"; 64 copy.style.backgroundColor = '#f7f7f7'; 65 copy.style.border = '1px solid black'; 66 copy.style.borderRadius = '3px'; 67 copy.style.color = '#586069'; 68 copy.style.cursor = 'pointer'; 69 copy.style.display = 'none'; 70 copy.style.font = 'bold 1em monospace'; 71 copy.style.padding = '0.4rem'; 72 copy.style.position = 'absolute'; 73 copy.style.right = '5px'; 74 copy.style.textDecoration = 'none'; 75 copy.style.top = '5px'; 76 copy.onclick = function(e) { selectAndCopy(code); } 77 78 pre.onmouseover = function(e) { copy.style.display = 'inline'; } 79 pre.onmouseout = function(e) { copy.style.display = 'none'; } 80 pre.style.position = 'relative'; 81 pre.insertBefore(copy, code); 82}); 83 84// Make scrollable code blocks keyboard-focusable for accessibility. 85// WCAG 2.1.1 Level A requires scrollable regions to be keyboard accessible. 86function makeScrollableCodeFocusable() { 87 document.querySelectorAll("pre code").forEach(function(code) { 88 // Check if the code block has horizontal overflow (is scrollable) 89 // Use setTimeout to ensure layout has been calculated 90 setTimeout(function() { 91 if (code.scrollWidth > code.clientWidth && !code.hasAttribute("tabindex")) { 92 code.setAttribute("tabindex", "0"); 93 } 94 }, 0); 95 }); 96} 97 98// Run on initial page load 99if (document.readyState === 'loading') { 100 document.addEventListener('DOMContentLoaded', makeScrollableCodeFocusable); 101} else { 102 makeScrollableCodeFocusable(); 103} 104 105// Re-run when emgithub embeds are loaded (they are added dynamically) 106// Watch for changes to .emgithub-embed containers 107new MutationObserver(function(mutations) { 108 var needsUpdate = false; 109 mutations.forEach(function(mutation) { 110 if (mutation.addedNodes.length > 0) { 111 needsUpdate = true; 112 } 113 }); 114 if (needsUpdate) { 115 // Delay to allow emgithub content to fully render 116 setTimeout(makeScrollableCodeFocusable, 500); 117 } 118}).observe(document.body, { childList: true, subtree: true });
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.