1(function (Drupal, once) { 2 Drupal.behaviors.customDiscluseScrollbar = { 3 attach: function (context) { 4 once('customDiscluseScrollbar', '.discluse-block', context).forEach(function (block) { 5 var container = block.querySelector('.discluse-container'); 6 var content = block.querySelector('.discluse-content'); 7 var track = block.querySelector('.discluse-scrollbar'); 8 var thumb = block.querySelector('.discluse-scrollbar__thumb'); 9 if (!content || !track || !thumb) return; 10 11 function updateTrackLayout() { 12 13 var trackHeight = block.clientHeight; 14 track.style.top = '0px'; 15 track.style.height = trackHeight + 'px'; 16 } 17 18 function updateThumb() { 19 var contentHeight = content.scrollHeight; 20 var visibleHeight = content.clientHeight; 21 var scrollTop = content.scrollTop; 22 if (contentHeight <= visibleHeight) { 23 thumb.style.display = 'none'; 24 track.style.display = 'none'; 25 return; 26 } 27 thumb.style.display = 'block'; 28 track.style.display = 'block'; 29 var trackHeight = track.clientHeight; 30 var ratio = visibleHeight / contentHeight; 31 var thumbHeight = Math.max(40, Math.round(trackHeight * ratio)); 32 var maxThumbTop = trackHeight - thumbHeight; 33 var scrollRatio = scrollTop / (contentHeight - visibleHeight); 34 var thumbTop = Math.round(maxThumbTop * scrollRatio); 35 thumb.style.height = thumbHeight + 'px'; 36 thumb.style.transform = 'translateY(' + thumbTop + 'px)'; 37 } 38 39 var isDragging = false; 40 var dragStartY = 0; 41 var dragStartScroll = 0; 42 43 function onMouseDown(e) { 44 isDragging = true; 45 dragStartY = e.clientY; 46 dragStartScroll = content.scrollTop; 47 document.addEventListener('mousemove', onMouseMove); 48 document.addEventListener('mouseup', onMouseUp); 49 e.preventDefault(); 50 } 51 52 function onMouseMove(e) { 53 if (!isDragging) return; 54 var trackHeight = track.clientHeight; 55 var contentHeight = content.scrollHeight; 56 var visibleHeight = content.clientHeight; 57 var deltaY = e.clientY - dragStartY; 58 var maxScroll = contentHeight - visibleHeight; 59 var maxThumbTravel = trackHeight - thumb.clientHeight; 60 var scrollPerPixel = maxScroll / maxThumbTravel; 61 content.scrollTop = dragStartScroll + deltaY * scrollPerPixel; 62 } 63 64 function onMouseUp() { 65 isDragging = false; 66 document.removeEventListener('mousemove', onMouseMove); 67 document.removeEventListener('mouseup', onMouseUp); 68 } 69 70 function onTrackClick(e) { 71 if (e.target === thumb) return; 72 var rect = track.getBoundingClientRect(); 73 var clickY = e.clientY - rect.top; 74 var thumbHeight = thumb.clientHeight; 75 var newTop = clickY - thumbHeight / 2; 76 newTop = Math.max(0, Math.min(newTop, rect.height - thumbHeight)); 77 var ratio = newTop / (rect.height - thumbHeight); 78 var maxScroll = content.scrollHeight - content.clientHeight; 79 content.scrollTop = Math.round(maxScroll * ratio); 80 } 81 82 content.addEventListener('scroll', updateThumb); 83 thumb.addEventListener('mousedown', onMouseDown); 84 track.addEventListener('click', onTrackClick); 85 window.addEventListener('resize', function () { 86 updateTrackLayout(); 87 updateThumb(); 88 }); 89 90 if (window.ResizeObserver) { 91 var ro = new ResizeObserver(function () { 92 updateTrackLayout(); 93 updateThumb(); 94 }); 95 ro.observe(content); 96 ro.observe(block); 97 } 98 99 updateTrackLayout(); 100 updateThumb(); 101 }); 102 } 103 }; 104})(Drupal, once); 105 106
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.