PageSourceSearch

https://www.meshweaver.cloud/_content/MeshWeaver.Blazor/Components/CodeBlock.03h86pbhlq.razor.js

js meshweaver.cloud collected 2026-09-25 22:09:04 UTC 3,996 bytes, 118 lines download raw bytes

1/**
2 * Highlights code within the provided element
3 * @param {HTMLElement} element - The element containing code to highlight
4 */
5
6import { ensureHighlightJs, initializeThemeUpdates } from '../highlightUtils.js';
7
8export async function highlightBlock(element) {
9    // Check if element is valid
10    if (!element) {
11        return;
12    }
13
14    await ensureHighlightJs();
15    initializeThemeUpdates();
16
17    if (!window.hljs) {
18        return;
19    }
20
21    // Find all code blocks within the element
22    const codeElements = element.querySelectorAll("pre code");
23
24    if (codeElements.length === 0) {
25        // If no pre code elements found, try to highlight the element itself if it's a code element
26        if (element.tagName === 'CODE' || element.classList.contains('language-')) {
27            hljs.highlightElement(element);
28        } else {
29            // Look for any code elements
30            const allCodeElements = element.querySelectorAll("code");
31            allCodeElements.forEach(block => {
32                hljs.highlightElement(block);
33            });
34        }
35    } else {
36        codeElements.forEach(block => {
37            hljs.highlightElement(block);
38        });
39    }
40}
41
42export function getCodeText(element) {
43    if (!element) {
44        return "";
45    }
46
47    const codeElement = element.querySelector("pre code") || element.querySelector("code");
48    return codeElement ? codeElement.textContent : element.textContent || "";
49}
50
51/**
52 * Wires the copy-to-clipboard icon inside the code block to a NATIVE click handler.
53 *
54 * Safari only permits navigator.clipboard.writeText from inside the synchronous call stack of a
55 * user gesture (a "transient activation"). The previous Blazor Server `@onclick` handler
56 * round-tripped over SignalR and then invoked writeText from the server -> JS, i.e. outside the
57 * gesture — Chrome tolerates that, Safari rejects it with NotAllowedError, so the button silently
58 * did nothing. Attaching a native DOM click listener here keeps the whole read-then-write in the
59 * gesture. A synchronous execCommand("copy") fallback covers older Safari / non-secure contexts.
60 *
61 * @param {HTMLElement} element - The code-block container holding the `.copy-to-clipboard` icon.
62 */
63export function setupCopyButton(element) {
64    if (!element) {
65        return;
66    }
67    const button = element.querySelector(".copy-to-clipboard");
68    if (!button || button.dataset.copyWired === "1") {
69        return;   // idempotent — OnAfterRenderAsync can re-run
70    }
71    button.dataset.copyWired = "1";
72
73    const doCopy = () => {
74        const text = getCodeText(element);
75        // Called synchronously in the gesture handler so Safari's gesture check passes.
76        if (navigator.clipboard && window.isSecureContext) {
77            navigator.clipboard.writeText(text).then(
78                () => flashCopied(button),
79                () => { if (copyViaExecCommand(text)) flashCopied(button); });
80        } else if (copyViaExecCommand(text)) {
81            flashCopied(button);
82        }
83    };
84
85    button.addEventListener("click", doCopy);
86    // Keyboard activation for the role="button" icon (Enter / Space).
87    button.addEventListener("keydown", (e) => {
88        if (e.key === "Enter" || e.key === " ") {
89            e.preventDefault();
90            doCopy();
91        }
92    });
93}
94
95function copyViaExecCommand(text) {
96    const ta = document.createElement("textarea");
97    ta.value = text;
98    ta.setAttribute("readonly", "");
99    ta.style.position = "fixed";
100    ta.style.top = "0";
101    ta.style.left = "0";
102    ta.style.opacity = "0";
103    document.body.appendChild(ta);
104    try {
105        ta.focus();
106        ta.select();
107        return document.execCommand("copy");
108    } catch {
109        return false;
110    } finally {
111        document.body.removeChild(ta);   // always clean up, even if select/execCommand throws
112    }
113}
114
115function flashCopied(button) {
116    button.classList.add("copied");
117    setTimeout(() => button.classList.remove("copied"), 1200);
118}

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.