1window.infoPopover = window.infoPopover || {}; 2 3window.infoPopover._handlers = window.infoPopover._handlers || new Map(); 4 5window.infoPopover.open = function (buttonElem, overlayElem, popoverElem, placeholder, dotNetHelper) { 6 if (!buttonElem || !overlayElem || !popoverElem) return; 7 8 Object.assign(overlayElem.style, { 9 position: 'fixed', 10 inset: '0', 11 backgroundColor: 'transparent', 12 zIndex: '999' 13 }); 14 15 Object.assign(popoverElem.style, { 16 position: 'fixed', 17 zIndex: '1000', 18 backgroundColor: 'white', 19 border: '1px solid var(--udb-slate-200, #dee2e6)', 20 boxShadow: '0 4px 8px rgba(0,0,0,0.1)', 21 padding: '1rem', 22 borderRadius: '0.25rem', 23 wordBreak: 'break-word', 24 opacity: '0', 25 transition: 'opacity 0.3s ease' 26 }); 27 28 document.body.appendChild(overlayElem); 29 document.body.appendChild(popoverElem); 30 31 const closeOnScroll = function () { 32 window.infoPopover.close(overlayElem, popoverElem, placeholder); 33 if (dotNetHelper) { 34 dotNetHelper.invokeMethodAsync('NotifyClosedFromJs'); 35 } 36 }; 37 38 window.addEventListener('scroll', closeOnScroll, { once: true, capture: true }); 39 window.infoPopover._handlers.set(popoverElem, closeOnScroll); 40 41 window.infoPopover.adjustPosition(buttonElem, popoverElem); 42 43 requestAnimationFrame(() => { 44 popoverElem.classList.add('show'); 45 popoverElem.style.opacity = '1'; 46 }); 47}; 48 49window.infoPopover.close = function (overlayElem, popoverElem, placeholder) { 50 const handler = window.infoPopover._handlers.get(popoverElem); 51 if (handler) { 52 window.removeEventListener('scroll', handler, true); 53 window.infoPopover._handlers.delete(popoverElem); 54 } 55 56 if (popoverElem) { 57 popoverElem.style.opacity = '0'; 58 popoverElem.style.transition = 'opacity 0.1s ease'; 59 popoverElem.classList.remove('show'); 60 popoverElem.classList.add('hide'); 61 } 62 63 setTimeout(function () { 64 if (placeholder) { 65 if (overlayElem) placeholder.appendChild(overlayElem); 66 if (popoverElem) { 67 placeholder.appendChild(popoverElem); 68 popoverElem.classList.remove('hide'); 69 } 70 } 71 }, 100); 72}; 73 74window.infoPopover.adjustPosition = function(buttonElem, popoverElem) { 75 if (!buttonElem || !popoverElem) return; 76 77 const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0); 78 const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0); 79 const maxWidth = Math.min(400, vw); 80 81 popoverElem.style.width = maxWidth + 'px'; 82 popoverElem.style.maxWidth = maxWidth + 'px'; 83 84 const rect = buttonElem.getBoundingClientRect(); 85 const popoverWidth = Math.min(maxWidth, popoverElem.offsetWidth); 86 const popoverHeight = popoverElem.offsetHeight; 87 const offset = 4; // roughly 0.25rem 88 89 const spaceRight = vw - rect.right; 90 const spaceLeft = rect.left; 91 92 let left; 93 if (spaceRight >= popoverWidth) { 94 left = rect.right + offset; 95 } else if (spaceLeft >= popoverWidth) { 96 left = rect.left - popoverWidth - offset; 97 } else { 98 left = rect.left + rect.width / 2 - popoverWidth / 2; 99 if (left < 0) left = 0; 100 if (left + popoverWidth > vw) left = vw - popoverWidth; 101 } 102 103 let top; 104 if (rect.bottom + offset + popoverHeight <= vh) { 105 top = rect.bottom + offset; 106 } else { 107 top = rect.top - popoverHeight - offset; 108 if (top < 0) top = 0; 109 } 110 111 popoverElem.style.left = left + 'px'; 112 popoverElem.style.top = top + 'px'; 113}; 114
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.