1const COPY_BUTTON_SELECTOR = '[data-article-social-copy-button]'; 2const COPY_STATUS_SELECTOR = '[data-article-social-copy-status]'; 3const COPY_SUCCESS_MESSAGE = 'Odkaz zkopÃrován'; 4const COPY_ERROR_MESSAGE = 'Odkaz se nepodaÅilo zkopÃrovat'; 5const STATUS_CLEAR_DELAY = 2000; 6 7export function initArticleSocialCopy(root = document) { 8 const buttons = root.querySelectorAll(`${COPY_BUTTON_SELECTOR}:not([data-article-social-copy-bound])`); 9 10 buttons.forEach((button) => { 11 if (!(button instanceof HTMLButtonElement)) { 12 return; 13 } 14 15 button.dataset.articleSocialCopyBound = 'true'; 16 button.addEventListener('click', async () => { 17 const url = button.dataset.copyUrl; 18 if (!url) { 19 return; 20 } 21 22 try { 23 await copyText(url); 24 setCopyStatus(button, COPY_SUCCESS_MESSAGE); 25 } catch (error) { 26 console.error(error); 27 setCopyStatus(button, COPY_ERROR_MESSAGE); 28 } 29 }); 30 }); 31} 32 33async function copyText(text) { 34 if (navigator.clipboard?.writeText) { 35 await navigator.clipboard.writeText(text); 36 return; 37 } 38 39 copyTextWithFallback(text); 40} 41 42function copyTextWithFallback(text) { 43 const textarea = document.createElement('textarea'); 44 textarea.value = text; 45 textarea.setAttribute('readonly', ''); 46 textarea.style.left = '-9999px'; 47 textarea.style.position = 'fixed'; 48 textarea.style.top = '0'; 49 50 document.body.appendChild(textarea); 51 textarea.focus(); 52 textarea.select(); 53 54 const copied = document.execCommand('copy'); 55 textarea.remove(); 56 57 if (!copied) { 58 throw new Error('Copy command failed.'); 59 } 60} 61 62function setCopyStatus(button, message) { 63 const socialSection = button.closest('.article-detail__social'); 64 const status = socialSection?.querySelector(COPY_STATUS_SELECTOR); 65 if (!(status instanceof HTMLElement)) { 66 return; 67 } 68 69 status.textContent = message; 70 window.setTimeout(() => { 71 if (status.textContent === message) { 72 status.textContent = ''; 73 } 74 }, STATUS_CLEAR_DELAY); 75}
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.