1/** 2 * Shared clipboard functionality for documentation section links. 3 * Used by admin-web docs.js and cdr-site right-toc-handler.js files. 4 */ 5window.HelpClipboard = (function() { 6 'use strict'; 7 8 var DEFAULT_NAVBAR_HEIGHT = 90; 9 10 /** 11 * Copy text to clipboard with fallback for older browsers. 12 * @param {string} text - The text to copy 13 * @returns {Promise<boolean>} - Resolves to true if copy succeeded, false otherwise 14 */ 15 function copyToClipboard(text) { 16 // Check for modern clipboard API (requires secure context) 17 if (navigator.clipboard && navigator.clipboard.writeText) { 18 return navigator.clipboard.writeText(text) 19 .then(function() { return true; }) 20 .catch(function() { return false; }); 21 } 22 23 // Fallback for older browsers or non-HTTPS contexts 24 // Note: document.execCommand('copy') is deprecated but needed for legacy browser support 25 return new Promise(function(resolve) { 26 try { 27 var textarea = document.createElement('textarea'); 28 textarea.value = text; 29 textarea.style.position = 'fixed'; 30 textarea.style.left = '-9999px'; 31 textarea.style.top = '0'; 32 document.body.appendChild(textarea); 33 textarea.focus(); 34 textarea.select(); 35 var success = document.execCommand('copy'); 36 document.body.removeChild(textarea); 37 resolve(success); 38 } catch (err) { 39 resolve(false); 40 } 41 }); 42 } 43 44 /** 45 * Show a floating notification near the clicked element. 46 * @param {HTMLElement} element - The element that was clicked 47 * @param {string} message - The message to display 48 * @param {boolean} isError - Whether this is an error notification 49 */ 50 function showNotification(element, message, isError) { 51 var existing = document.querySelector('.helpSectionLink-copied'); 52 if (existing) { 53 existing.remove(); 54 } 55 56 var notification = document.createElement('div'); 57 notification.className = 'helpSectionLink-copied'; 58 notification.textContent = message; 59 if (isError) { 60 notification.style.backgroundColor = '#933'; 61 } 62 63 var rect = element.getBoundingClientRect(); 64 65 // For subsection links (helpSectionLinkTwo), position below; otherwise above 66 var isSubsectionLink = element.classList.contains('helpSectionLinkTwo'); 67 var navBarHeight = DEFAULT_NAVBAR_HEIGHT; 68 var header = document.querySelector('.navbar-fixed-top, .fixed-top, header.fixed'); 69 if (header) { 70 navBarHeight = header.offsetHeight + 10; 71 } 72 73 var top; 74 if (isSubsectionLink) { 75 top = rect.bottom + 5; 76 } else { 77 top = rect.top - 30; 78 } 79 // Ensure notification stays below nav bar 80 top = Math.max(top, navBarHeight); 81 82 notification.style.position = 'fixed'; 83 notification.style.top = top + 'px'; 84 notification.style.right = '20px'; 85 86 document.body.appendChild(notification); 87 88 requestAnimationFrame(function() { 89 notification.classList.add('show'); 90 }); 91 92 setTimeout(function() { 93 notification.classList.remove('show'); 94 setTimeout(function() { 95 notification.remove(); 96 }, 300); 97 }, 1500); 98 } 99 100 /** 101 * Setup click handler for help section links to copy URL to clipboard. 102 * @param {HTMLElement|string} container - The container element or selector 103 */ 104 function setupSectionLinkClipboard(container) { 105 var docsContent = typeof container === 'string' 106 ? document.querySelector(container) 107 : container; 108 109 if (!docsContent) { 110 return; 111 } 112 113 if (docsContent.hasAttribute('data-clipboard-initialized')) { 114 return; 115 } 116 docsContent.setAttribute('data-clipboard-initialized', 'true'); 117 118 docsContent.addEventListener('click', function(event) { 119 var link = event.target.closest('.helpSectionLink, .helpSectionLinkTwo'); 120 if (!link) { 121 return; 122 } 123 124 var url = link.href; 125 if (!url) { 126 return; 127 } 128 copyToClipboard(url).then(function(success) { 129 if (success) { 130 showNotification(link, 'Link copied!', false); 131 } else { 132 showNotification(link, 'Copy failed', true); 133 } 134 }); 135 }); 136 } 137 138 return { 139 copyToClipboard: copyToClipboard, 140 showNotification: showNotification, 141 setupSectionLinkClipboard: setupSectionLinkClipboard 142 }; 143})();
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.