PageSourceSearch

https://imagej.net/assets/js/code.js

js imagej.net collected 2026-09-24 06:23:28 UTC 4,139 bytes, 118 lines download raw bytes

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.