1document.addEventListener('DOMContentLoaded', function () { 2 var userMenuButton = document.getElementById('user-menu-button'); 3 var profileMenuDropdown = 4 document.querySelector('.profile-menu__dropdown') || 5 document.querySelector('.wp-block-memberpress-pro-profile-menu__dropdown'); 6 var mobileMenuButton = 7 document.querySelector('.profile-menu__button.--is-mobile') || 8 document.querySelector('.wp-block-memberpress-pro-profile-menu__button.--is-mobile'); 9 var meprAccountNav = document.getElementById('mepr-account-nav'); 10 var clAccount = document.querySelector('.mepr-rl-account'); 11 var isClAccountDrawer = 12 clAccount && meprAccountNav && clAccount.contains(meprAccountNav); 13 14 var mobileOverlay = null; 15 16 function ensureMobileDrawerCloseIcon() { 17 if (!isClAccountDrawer || !mobileMenuButton) { 18 return; 19 } 20 if (mobileMenuButton.querySelector('.mepr-account-mobile-menu-close-icon')) { 21 return; 22 } 23 var ns = 'http://www.w3.org/2000/svg'; 24 var closeSvg = document.createElementNS(ns, 'svg'); 25 closeSvg.setAttribute('class', 'mepr-account-mobile-menu-close-icon mepr-rl-shell-mobile-menu-close-icon'); 26 closeSvg.setAttribute('fill', 'none'); 27 closeSvg.setAttribute('viewBox', '0 0 24 24'); 28 closeSvg.setAttribute('stroke', 'currentColor'); 29 closeSvg.setAttribute('stroke-width', '2'); 30 closeSvg.setAttribute('aria-hidden', 'true'); 31 var p1 = document.createElementNS(ns, 'path'); 32 p1.setAttribute('stroke-linecap', 'round'); 33 p1.setAttribute('stroke-linejoin', 'round'); 34 p1.setAttribute('d', 'M6 18L18 6M6 6l12 12'); 35 closeSvg.appendChild(p1); 36 mobileMenuButton.appendChild(closeSvg); 37 } 38 39 function toggleProfileDropdown() { 40 if (profileMenuDropdown) { 41 profileMenuDropdown.classList.toggle('is-open'); 42 } 43 } 44 45 function closeProfileDropdown() { 46 if (profileMenuDropdown) { 47 profileMenuDropdown.classList.remove('is-open'); 48 } 49 } 50 51 function ensureOverlay() { 52 if (!isClAccountDrawer || mobileOverlay) { 53 return mobileOverlay; 54 } 55 mobileOverlay = document.createElement('div'); 56 mobileOverlay.className = 'mepr-account-mobile-overlay mepr-rl-shell-mobile-overlay'; 57 mobileOverlay.setAttribute('aria-hidden', 'true'); 58 document.body.appendChild(mobileOverlay); 59 mobileOverlay.addEventListener('click', closeClAccountDrawer); 60 return mobileOverlay; 61 } 62 63 function mergeProfileQuicklinks() { 64 if (!isClAccountDrawer || !meprAccountNav) { 65 return; 66 } 67 if (meprAccountNav.querySelector('.mepr-account-mobile-quicklinks')) { 68 return; 69 } 70 var dropdown = 71 document.querySelector('.profile-menu__dropdown') || 72 document.querySelector('.wp-block-memberpress-pro-profile-menu__dropdown'); 73 if (!dropdown) { 74 return; 75 } 76 var links = dropdown.querySelectorAll('a[href]'); 77 if (!links.length) { 78 return; 79 } 80 var wrap = document.createElement('div'); 81 wrap.className = 'mepr-account-mobile-quicklinks mepr-rl-shell-mobile-quicklinks'; 82 wrap.setAttribute('role', 'group'); 83 84 links.forEach(function (a) { 85 wrap.appendChild(a.cloneNode(true)); 86 }); 87 88 var ul = meprAccountNav.querySelector('ul'); 89 if (ul) { 90 meprAccountNav.insertBefore(wrap, ul); 91 } else { 92 meprAccountNav.insertBefore(wrap, meprAccountNav.firstChild); 93 } 94 } 95 96 function removeMobileQuicklinks() { 97 if (!meprAccountNav) { 98 return; 99 } 100 var quick = meprAccountNav.querySelector('.mepr-account-mobile-quicklinks'); 101 if (quick) { 102 quick.remove(); 103 } 104 } 105 106 function openClAccountDrawer() { 107 if (!meprAccountNav) { 108 return; 109 } 110 mergeProfileQuicklinks(); 111 var ov = ensureOverlay(); 112 meprAccountNav.classList.add('open'); 113 document.body.classList.add('mepr-rl-account-mobile-nav-open', 'mepr-rl-shell-mobile-nav-open'); 114 if (ov) { 115 ov.classList.add('is-visible'); 116 } 117 if (mobileMenuButton) { 118 mobileMenuButton.setAttribute('aria-expanded', 'true'); 119 mobileMenuButton.setAttribute('aria-label', 'Close menu'); 120 } 121 } 122 123 function closeClAccountDrawer() { 124 if (!meprAccountNav) { 125 return; 126 } 127 var wasOpen = meprAccountNav.classList.contains('open'); 128 meprAccountNav.classList.remove('open'); 129 if (mobileOverlay) { 130 mobileOverlay.classList.remove('is-visible'); 131 } 132 if (mobileMenuButton) { 133 mobileMenuButton.setAttribute('aria-expanded', 'false'); 134 mobileMenuButton.setAttribute('aria-label', 'Open menu'); 135 } 136 137 /* Defer body-class removal + quicklinks cleanup until the slide-out 138 * transition completes. Removing them synchronously drops the header 139 * z-index (shell.css raises it to 100000 only while the body class is 140 * set) and pops the cloned profile links out of the DOM â both happen 141 * at frame 0 while the drawer is still at translateX(0), which is the 142 * "colored flicker at the top" during slide-out. */ 143 var doCleanup = function () { 144 if (meprAccountNav.classList.contains('open')) { 145 return; /* user re-opened mid-slide-out */ 146 } 147 document.body.classList.remove('mepr-rl-account-mobile-nav-open', 'mepr-rl-shell-mobile-nav-open'); 148 removeMobileQuicklinks(); 149 }; 150 151 if (wasOpen && window.innerWidth < 840) { 152 var onSlideOutEnd = function (ev) { 153 if (ev.target !== meprAccountNav || ev.propertyName !== 'transform') { 154 return; 155 } 156 meprAccountNav.removeEventListener('transitionend', onSlideOutEnd); 157 doCleanup(); 158 }; 159 meprAccountNav.addEventListener('transitionend', onSlideOutEnd); 160 } else { 161 /* Desktop resize handler or already-closed: nothing to animate. */ 162 doCleanup(); 163 } 164 } 165 166 function toggleClAccountDrawer() { 167 if (meprAccountNav.classList.contains('open')) { 168 closeClAccountDrawer(); 169 } else { 170 openClAccountDrawer(); 171 } 172 } 173 174 if (userMenuButton && profileMenuDropdown) { 175 userMenuButton.addEventListener('click', toggleProfileDropdown); 176 177 document.addEventListener('click', function (event) { 178 var isFromMenu = 179 userMenuButton.contains(event.target) || 180 profileMenuDropdown.contains(event.target) || 181 (mobileMenuButton && mobileMenuButton.contains(event.target)); 182 if (!isFromMenu) { 183 closeProfileDropdown(); 184 } 185 }); 186 } 187 188 if (mobileMenuButton) { 189 if (isClAccountDrawer && meprAccountNav) { 190 ensureMobileDrawerCloseIcon(); 191 mobileMenuButton.setAttribute('aria-label', 'Open menu'); 192 mobileMenuButton.addEventListener( 193 'click', 194 function (e) { 195 e.preventDefault(); 196 e.stopImmediatePropagation(); 197 toggleClAccountDrawer(); 198 }, 199 true 200 ); 201 202 document.addEventListener('keydown', function (e) { 203 if (e.key === 'Escape' && meprAccountNav.classList.contains('open')) { 204 closeClAccountDrawer(); 205 } 206 }); 207 208 meprAccountNav.addEventListener('click', function (e) { 209 var t = e.target; 210 if (t && t.closest && t.closest('a') && meprAccountNav.classList.contains('open')) { 211 closeClAccountDrawer(); 212 } 213 }); 214 215 window.addEventListener('resize', function () {
216 /* Always reset drawer state when returning to desktop (avoids stray body/overlay class). */ 217 if (window.innerWidth >= 840) { 218 closeClAccountDrawer(); 219 } 220 }); 221 } else if (meprAccountNav) { 222 mobileMenuButton.addEventListener('click', function () { 223 meprAccountNav.classList.toggle('open'); 224 }); 225 } else if (profileMenuDropdown) { 226 /* No drawer / no account nav (e.g. Courses, Login, or any FSE page 227 * that ships the profile-menu without an account or coaching drawer): 228 * the mobile button now shows the avatar, so reuse the desktop 229 * dropdown handler so users on these routes can still reach 230 * Account / Logout / etc. Coaching pages bind their own drawer 231 * handler in capture phase with stopImmediatePropagation, so this 232 * bubble-phase listener is naturally suppressed there. */ 233 mobileMenuButton.addEventListener('click', toggleProfileDropdown); 234 } 235 } 236});
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.