1(function (Drupal, once) { 2 'use strict'; 3 4 Drupal.behaviors.aiGlobal = { 5 attach: function (context) { 6 const popoverShowDelay = 500; // ms 7 8 once('ai-tooltip', '[data-ai-tooltip]', context).forEach(popoverTrigger => { 9 let pendingShowTimer = null; 10 let pendingHideTimer = null; 11 12 const popoverId = 'ai-tooltip-' + Math.random().toString(36).substring(2, 15); 13 popoverTrigger.setAttribute('popovertarget', popoverId); 14 popoverTrigger.setAttribute('tabindex', '0'); 15 popoverTrigger.setAttribute('aria-describedby', popoverId); 16 17 const popover = document.createElement('div'); 18 popover.classList.add('ai-tooltip'); 19 popover.setAttribute('popover', 'hint'); 20 popover.setAttribute('id', popoverId); 21 popover.innerHTML = popoverTrigger.dataset.aiTooltip; 22 document.body.appendChild(popover); 23 24 const showTooltip = () => { 25 // If a hide timer is pending, cancel it. 26 if (pendingHideTimer) { 27 clearTimeout(pendingHideTimer); 28 pendingHideTimer = null; 29 } 30 // If a show timer is pending, cancel it. 31 if (pendingShowTimer) { 32 clearTimeout(pendingShowTimer); 33 } 34 // Set a new show timer. 35 pendingShowTimer = setTimeout(() => { 36 popover.showPopover({ source: popoverTrigger }); 37 pendingShowTimer = null; 38 }, popoverShowDelay); 39 } 40 41 const hideTooltip = () => { 42 // If a show timer is pending, cancel it. 43 if (pendingShowTimer) { 44 clearTimeout(pendingShowTimer); 45 pendingShowTimer = null; 46 } 47 // If a hide timer is pending, cancel it. 48 if (pendingHideTimer) { 49 clearTimeout(pendingHideTimer); 50 } 51 // Set a new hide timer. 52 pendingHideTimer = setTimeout(() => { 53 popover.hidePopover(); 54 pendingHideTimer = null; 55 }, popoverShowDelay); 56 }; 57 58 popoverTrigger.addEventListener('mouseenter', showTooltip); 59 popoverTrigger.addEventListener('mouseleave', hideTooltip); 60 popoverTrigger.addEventListener('focusin', showTooltip); 61 popoverTrigger.addEventListener('focusout', hideTooltip); 62 }); 63 } 64 } 65})(Drupal, once);
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.