1// Ensure meprTel.i18n exists with fallback translations 2if (typeof meprTel === 'undefined') { 3 var meprTel = {}; 4} 5if (typeof meprTel.i18n === 'undefined') { 6 meprTel.i18n = { 7 selectCountryCode: 'Select country code', 8 countryCodeOptions: 'Country code options', 9 countryChangedTo: 'Country changed to', 10 countryCode: 'country code', 11 phoneNumberInput: 'Phone number input' 12 }; 13} 14 15var telInputs = document.querySelectorAll(".mepr-tel-input"); 16telInputs.forEach(input => { 17 var iti = window.intlTelInput(input, { 18 separateDialCode: true, 19 initialCountry: meprTel.defaultCountry, 20 utilsScript: meprTel.utilsUrl, 21 onlyCountries: meprTel.onlyCountries ? meprTel.onlyCountries : [], 22 i18n: 'fr', 23 }); 24 25 adjustPadding(input); // On load 26 input.addEventListener('countrychange', () => adjustPadding(input)); // On country change 27 input.addEventListener('keyup', () => adjustPadding(input)); // To fix padding conflict with WPForms 28 29 // Fix accessibility issues with the intl-tel-input library - apply after initialization 30 enhanceAccessibility(input, iti); 31}); 32 33function enhanceAccessibility(input, iti) { 34 // Add a delay to ensure intl-tel-input has finished initialization 35 setTimeout(function() { 36 try { 37 // Get the container created by intl-tel-input 38 var itiContainer = input.parentElement; 39 if (!itiContainer || !itiContainer.classList.contains('iti')) { 40 return; // Not an intl-tel-input container 41 } 42 43 // Find the selected flag element that's causing accessibility issues 44 var selectedFlag = itiContainer.querySelector('.iti__selected-flag'); 45 46 if (selectedFlag && selectedFlag.nodeType === Node.ELEMENT_NODE) { 47 // Only add attributes if they don't already exist (avoid conflicts) 48 if (!selectedFlag.getAttribute('role')) { 49 selectedFlag.setAttribute('role', 'button'); 50 } 51 if (!selectedFlag.getAttribute('aria-haspopup')) { 52 selectedFlag.setAttribute('aria-haspopup', 'listbox'); 53 } 54 if (!selectedFlag.getAttribute('aria-expanded')) { 55 selectedFlag.setAttribute('aria-expanded', 'false'); 56 } 57 if (!selectedFlag.getAttribute('aria-label')) { 58 selectedFlag.setAttribute('aria-label', meprTel.i18n.selectCountryCode); 59 } 60 if (!selectedFlag.getAttribute('tabindex')) { 61 selectedFlag.setAttribute('tabindex', '0'); 62 } 63 64 // Add unique IDs for ARIA relationships 65 var inputId = input.getAttribute('id') || 'phone-input-' + Math.random().toString(36).substring(2, 11); 66 var listboxId = inputId + '-listbox'; 67 68 // Set aria-controls immediately to satisfy validation requirements 69 // The referenced element will be created when dropdown is opened 70 if (!selectedFlag.getAttribute('aria-controls')) { 71 selectedFlag.setAttribute('aria-controls', listboxId); 72 73 // Create a temporary placeholder element to satisfy ARIA validation 74 // This will be replaced when the actual dropdown is created 75 createPlaceholderDropdown(itiContainer, listboxId); 76 } 77 78 // Use a less intrusive approach - only observe existing elements 79 enhanceDropdownAccessibility(itiContainer, listboxId, selectedFlag); 80 81 // Use passive event listeners to avoid conflicts 82 setupAccessibilityObserver(itiContainer, selectedFlag); 83 84 // Add safe keyboard navigation 85 addKeyboardNavigation(selectedFlag); 86 } 87 88 // Enhance the phone input itself safely 89 enhancePhoneInput(input); 90 91 // Add live region for announcements 92 setupLiveRegion(input, iti); 93 94 } catch (e) { 95 console.warn('MemberPress phone accessibility: Error enhancing accessibility', e); 96 } 97 }, 200); // Increased delay to avoid conflicts 98} 99 100function createPlaceholderDropdown(itiContainer, listboxId) { 101 // Check if placeholder already exists 102 var existingPlaceholder = document.getElementById(listboxId); 103 if (existingPlaceholder) { 104 return; // Already exists 105 } 106 107 // Create a hidden placeholder element to satisfy ARIA validation 108 var placeholder = document.createElement('div'); 109 placeholder.id = listboxId; 110 placeholder.style.display = 'none'; 111 placeholder.setAttribute('role', 'listbox'); 112 placeholder.setAttribute('aria-label', meprTel.i18n.countryCodeOptions); 113 placeholder.setAttribute('data-placeholder', 'true'); 114 115 // Append to container but keep hidden 116 itiContainer.appendChild(placeholder); 117} 118 119function enhanceDropdownAccessibility(itiContainer, listboxId, selectedFlag) { 120 // Look for dropdown when it's actually created (lazy approach) 121 var checkDropdown = function() { 122 var dropdown = itiContainer.querySelector('.iti__country-list'); 123 if (dropdown && !dropdown.getAttribute('role')) { 124 // Remove placeholder element if it exists 125 var placeholder = itiContainer.querySelector('[data-placeholder="true"]'); 126 if (placeholder) { 127 placeholder.remove(); 128 } 129 130 dropdown.setAttribute('id', listboxId); 131 dropdown.setAttribute('role', 'listbox'); 132 dropdown.setAttribute('aria-label', meprTel.i18n.countryCodeOptions); 133 134 // aria-controls is already set, just ensure the dropdown has the correct ID 135 // This ensures the ARIA relationship is valid 136 137 // Enhance country items when dropdown is opened 138 var countryItems = dropdown.querySelectorAll('.iti__country');
139 countryItems.forEach((item, index) => { 140 if (item && !item.getAttribute('role')) { 141 item.setAttribute('role', 'option'); 142 item.setAttribute('id', listboxId + '-option-' + index); 143 item.setAttribute('aria-selected', 'false'); 144 } 145 }); 146 } 147 }; 148 149 // Check immediately and also when container changes 150 checkDropdown(); 151 152 // Set up observer for when dropdown gets created 153 var dropdownObserver = new MutationObserver(function(mutations) { 154 mutations.forEach(function(mutation) { 155 if (mutation.type === 'childList') { 156 checkDropdown(); 157 } 158 }); 159 }); 160 161 dropdownObserver.observe(itiContainer, { 162 childList: true, 163 subtree: true 164 }); 165} 166 167function setupAccessibilityObserver(itiContainer, selectedFlag) { 168 // Observe class changes for aria-expanded updates 169 var classObserver = new MutationObserver(function(mutations) { 170 mutations.forEach(function(mutation) { 171 if (mutation.type === 'attributes' && mutation.attributeName === 'class') { 172 try { 173 var isOpen = itiContainer.classList.contains('iti__country-list-open'); 174 if (selectedFlag && selectedFlag.getAttribute && selectedFlag.setAttribute) { 175 selectedFlag.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); 176 } 177 } catch (e) { 178 // Silently handle errors to avoid breaking functionality 179 } 180 } 181 }); 182 }); 183 184 classObserver.observe(itiContainer, { 185 attributes: true, 186 attributeFilter: ['class'] 187 }); 188} 189 190function addKeyboardNavigation(selectedFlag) { 191 // Use passive event listener to avoid conflicts 192 selectedFlag.addEventListener('keydown', function(e) { 193 try { 194 if (e.key === 'Enter' || e.key === ' ') { 195 e.preventDefault(); 196 // Use a safer click simulation 197 setTimeout(function() { 198 if (selectedFlag.click) { 199 selectedFlag.click(); 200 } 201 }, 10); 202 } 203 } catch (e) { 204 // Silently handle errors 205 } 206 }, { passive: false }); 207} 208 209function enhancePhoneInput(input) { 210 if (input && input.setAttribute) { 211 if (!input.getAttribute('role')) { 212 input.setAttribute('role', 'textbox'); 213 } 214 215 // Add aria-label if not already present 216 if (!input.getAttribute('aria-label') && !input.getAttribute('aria-labelledby')) { 217 input.setAttribute('aria-label', meprTel.i18n.phoneNumberInput); 218 } 219 } 220} 221 222function setupLiveRegion(input, iti) { 223 // Add live region for country code announcements 224 var liveRegion = document.getElementById('phone-country-live-region'); 225 if (!liveRegion) { 226 liveRegion = document.createElement('div'); 227 liveRegion.id = 'phone-country-live-region'; 228 liveRegion.setAttribute('aria-live', 'polite'); 229 liveRegion.setAttribute('aria-atomic', 'true'); 230 liveRegion.style.position = 'absolute'; 231 liveRegion.style.left = '-10000px'; 232 liveRegion.style.width = '1px'; 233 liveRegion.style.height = '1px'; 234 liveRegion.style.overflow = 'hidden'; 235 document.body.appendChild(liveRegion); 236 } 237 238 // Use one-time event listener to avoid multiple bindings 239 var countryChangeHandler = function() { 240 try { 241 var selectedCountryData = iti.getSelectedCountryData(); 242 if (selectedCountryData && liveRegion) { 243 liveRegion.textContent = meprTel.i18n.countryChangedTo + ' ' + selectedCountryData.name + 244 ', ' + meprTel.i18n.countryCode + ' ' + selectedCountryData.dialCode; 245 } 246 } catch (e) { 247 // Silently handle errors 248 } 249 }; 250 251 // Remove any existing listener and add new one 252 input.removeEventListener('countrychange', countryChangeHandler); 253 input.addEventListener('countrychange', countryChangeHandler); 254} 255 256function adjustPadding(input) { 257 var flagContainer = input.parentElement.querySelector('.iti__flag-container'), 258 flagWidth = window.getComputedStyle(flagContainer).getPropertyValue('width'), 259 adjustedWidth = `${parseInt(flagWidth) + 10}px`; 260 261 // Check if body has RTL class 262 if (document.body.classList.contains('rtl')) { 263 input.style.setProperty('padding-left', '10px', 'important'); 264 input.style.setProperty('padding-right', adjustedWidth, 'important'); 265 } else { 266 input.style.setProperty('padding-left', adjustedWidth, 'important'); 267 } 268} 269 270// Handle phone field padding on ReadyLaunch Account 271document.querySelectorAll('.mepr-profile-details__button').forEach(button => { 272 button.addEventListener('click', () => { 273 setTimeout(() => {
274 telInputs.forEach(input => { 275 adjustPadding(input); 276 // Re-apply accessibility enhancements for dynamically loaded forms 277 var iti = window.intlTelInputGlobals.getInstance(input); 278 if (iti) { 279 enhanceAccessibility(input, iti); 280 } 281 }); 282 }, 100); // Delay until open modal 283 }); 284});
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.