1(function () { 2 class BreakdanceHeaderBuilder { 3 /** 4 * @type {Element} 5 */ 6 element = null; 7 stickyScrollHideAfter = false; 8 stickyHideUntilScrollDistance = false; 9 stickyRevealOnScrollUp = false; 10 isBuilder = false; 11 lastScroll = 0; 12 timeout = null; 13 14 initialHiddenClass = "bde-header-builder--sticky-scroll-start-off-hidden"; 15 hiddenClass = "bde-header-builder--sticky-scroll-hide"; 16 stylesClass = "bde-header-builder--sticky-styles"; 17 18 /** 19 * @param {string} selector 20 * @param {string} id 21 * @param {boolean} isBuilder 22 */ 23 constructor(selector, id, isBuilder) { 24 this.handleScroll = this.handleScroll.bind(this); 25 26 this.isBuilder = isBuilder; 27 this.element = document.querySelector(selector); 28 this.stickyScrollHideAfter = this.getProp("stickyScrollHideAfter"); 29 this.stickyHideUntilScrollDistance = this.getProp( 30 "stickyHideUntilScrollDistance" 31 ); 32 this.stickyRevealOnScrollUp = this.getBooleanProp( 33 "stickyRevealOnScrollUp" 34 ); 35 36 this.handleScroll(); 37 this.setupListeners(); 38 this.createMarkers(); 39 } 40 41 refresh() { 42 this.handleSticky(); 43 } 44 45 destroy() { 46 this.unbindListeners(); 47 48 document 49 .querySelectorAll(".bde-header-builder-marker") 50 .forEach((marker) => marker.remove()); 51 } 52 53 // DOM 54 getProp(key) { 55 return parseInt(this.element.dataset[key]) || false; 56 } 57 58 getBooleanProp(key) { 59 return !!this.element.dataset[key]; 60 } 61 62 // Listeners 63 setupListeners() { 64 if (!this.isSticky()) { 65 this.clearStickyStyles(); 66 return; 67 } 68 69 window.addEventListener("scroll", this.handleScroll, { passive: true }); 70 } 71 72 unbindListeners() { 73 window.removeEventListener("scroll", this.handleScroll); 74 } 75 76 clearStickyStyles() { 77 this.removeClass(this.initialHiddenClass); 78 this.removeClass(this.hiddenClass); 79 this.removeClass("bde-header-builder--sticky-styles"); 80 this.removeClass("is-animating"); 81 this.removeClass("is-before"); 82 } 83 84 // Class Methods 85 addClass(x) { 86 this.element.classList.add(x); 87 } 88 89 hasClass(x) { 90 return this.element.classList.contains(x); 91 } 92 93 removeClass(x) { 94 this.element.classList.remove(x); 95 } 96 97 // Sticky Methods 98 isSticky() { 99 return this.hasClass("bde-header-builder--sticky"); 100 } 101 102 isHidden() { 103 return this.hasClass(this.hiddenClass); 104 } 105 106 shouldHide(scrollTop) { 107 const hideAfterDistance = 108 this.stickyScrollHideAfter != false && 109 scrollTop > this.stickyScrollHideAfter; 110 const hideUntilDistance = 111 this.stickyHideUntilScrollDistance != false && 112 scrollTop < this.stickyHideUntilScrollDistance; 113 return hideAfterDistance || hideUntilDistance; 114 } 115 116 shouldShowAfterACertainDistance(scrollTop) { 117 return ( 118 this.stickyHideUntilScrollDistance != false && 119 scrollTop > this.stickyHideUntilScrollDistance 120 ); 121 } 122 123 shouldShowOnScrollUp(scrollTop) { 124 if (!this.stickyRevealOnScrollUp) { 125 return false; 126 } 127 128 if (this.stickyHideUntilScrollDistance > scrollTop) return false; 129 130 return scrollTop < this.lastScroll; 131 } 132 133 handleScroll() { 134 this.removeClass(this.initialHiddenClass); 135 this.handleSticky(); 136 this.handleBuilderBehaviorOnScroll(); 137 } 138 139 handleSticky() { 140 const scrollTop = document.documentElement.scrollTop; 141 142 if (scrollTop > 0) { 143 this.addClass(this.stylesClass); 144 } else if (this.stickyHideUntilScrollDistance == false) { 145 this.removeClass(this.stylesClass); 146 } 147 148 if (this.shouldShowAfterACertainDistance(scrollTop)) { 149 this.removeClass(this.hiddenClass); 150 } 151 152 if (this.shouldHide(scrollTop)) { 153 this.addClass(this.hiddenClass); 154 } else if (this.isHidden()) { 155 this.removeClass(this.hiddenClass); 156 } 157 158 if (this.shouldShowOnScrollUp(scrollTop)) { 159 this.removeClass(this.hiddenClass); 160 } 161 162 this.lastScroll = scrollTop; 163 } 164 165 handleBuilderBehaviorOnScroll() { 166 const scrollTop = document.documentElement.scrollTop; 167 168 if (!this.isBuilder) return; 169 170 if (this.shouldHide(scrollTop)) { 171 this.addClass("is-before"); 172 this.removeClass("is-animating"); 173 } else { 174 this.addClass("is-animating"); 175 this.removeClass("is-before"); 176 } 177 178 // Detecting when the user has stopped scrolling 179 window.clearTimeout(this.timeout); 180 181 this.timeout = setTimeout(() => { 182 this.removeClass("is-animating"); 183 }, 200); 184 } 185 186 // Markers 187 createMarkers() { 188 if (!this.isBuilder) return; 189 190 if ( 191 this.stickyScrollHideAfter && 192 this.stickyHideUntilScrollDistance && 193 this.stickyScrollHideAfter < this.stickyHideUntilScrollDistance 194 ) { 195 this.createMarker( 196 this.stickyScrollHideAfter, 197 `Error: 'Hide' must be higher than 'Show'` 198 ); 199 } else if (this.stickyScrollHideAfter) { 200 this.createMarker( 201 this.stickyScrollHideAfter, 202 `Hide (${this.stickyScrollHideAfter}px)` 203 ); 204 } 205 206 if (this.stickyHideUntilScrollDistance) { 207 this.createMarker( 208 this.stickyHideUntilScrollDistance, 209 `Show (${this.stickyHideUntilScrollDistance}px)` 210 ); 211 } 212 } 213 214 createMarker(position, text) { 215 const marker = document.createElement("span"); 216 217 marker.style.top = `${position}px`;
218 marker.classList.add("bde-header-builder-marker"); 219 220 const textNode = document.createTextNode(text); 221 222 marker.append(textNode); 223 document.body.append(marker); 224 } 225 } 226 227 window.BreakdanceHeaderBuilder = BreakdanceHeaderBuilder; 228})();
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.