1/** 2 * Compass Copy-to-Clipboard 3 * Copies data-copy value to clipboard and flashes a .c-tooltip for 1.5s. 4 * 5 * Markup expected: 6 * <button class="c-copy" data-copy="VALUE" aria-label="Copy â¦"> 7 * <img ⦠/> 8 * <span class="c-tooltip" role="status" aria-live="polite">Copied!</span> 9 * </button> 10 */ 11(function () { 12 'use strict'; 13 14 var SHOW_CLASS = 'is-visible'; 15 var DURATION = 1500; // ms the tooltip stays visible 16 17 // Track active timers per button so rapid clicks don't stack 18 var timers = new Map(); 19 20 function handleClick(e) { 21 var btn = e.currentTarget; 22 var text = btn.getAttribute('data-copy'); 23 if (!text) return; 24 25 var tooltip = btn.querySelector('.c-tooltip'); 26 27 // Copy to clipboard (modern API with fallback) 28 if (navigator.clipboard && navigator.clipboard.writeText) { 29 navigator.clipboard.writeText(text); 30 } else { 31 // Fallback for older browsers / insecure contexts 32 var ta = document.createElement('textarea'); 33 ta.value = text; 34 ta.style.position = 'fixed'; 35 ta.style.opacity = '0'; 36 document.body.appendChild(ta); 37 ta.select(); 38 document.execCommand('copy'); 39 document.body.removeChild(ta); 40 } 41 42 // Show tooltip 43 if (tooltip) { 44 // Clear any existing timer for this button 45 if (timers.has(btn)) { 46 clearTimeout(timers.get(btn)); 47 } 48 49 tooltip.classList.add(SHOW_CLASS); 50 51 var timer = setTimeout(function () { 52 tooltip.classList.remove(SHOW_CLASS); 53 timers.delete(btn); 54 }, DURATION); 55 56 timers.set(btn, timer); 57 } 58 } 59 60 // Bind all copy buttons on the page 61 function init() { 62 var buttons = document.querySelectorAll('.c-copy[data-copy]'); 63 buttons.forEach(function (btn) { 64 btn.addEventListener('click', handleClick); 65 }); 66 67 document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => new bootstrap.Tooltip(el)); 68 } 69 70 // Init on DOM ready 71 if (document.readyState === 'loading') { 72 document.addEventListener('DOMContentLoaded', init); 73 } else { 74 init(); 75 } 76})();
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.