HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux bsx-1-dev 6.8.0-101-generic #101-Ubuntu SMP PREEMPT_DYNAMIC Mon Feb 9 10:15:05 UTC 2026 x86_64
User: www-data (33)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/plugins/memberpress/js/tel_input.js
// Ensure meprTel.i18n exists with fallback translations
if (typeof meprTel === 'undefined') {
  var meprTel = {};
}
if (typeof meprTel.i18n === 'undefined') {
  meprTel.i18n = {
    selectCountryCode: 'Select country code',
    countryCodeOptions: 'Country code options',
    countryChangedTo: 'Country changed to',
    countryCode: 'country code',
    phoneNumberInput: 'Phone number input'
  };
}

var telInputs = document.querySelectorAll(".mepr-tel-input");
telInputs.forEach(input => {
  var iti = window.intlTelInput(input, {
    separateDialCode: true,
    initialCountry: meprTel.defaultCountry,
    utilsScript: meprTel.utilsUrl,
    onlyCountries: meprTel.onlyCountries ? meprTel.onlyCountries : [],
    i18n: 'fr',
  });

  adjustPadding(input); // On load
  input.addEventListener('countrychange', () => adjustPadding(input)); // On country change
  input.addEventListener('keyup', () => adjustPadding(input)); // To fix padding conflict with WPForms

  // Fix accessibility issues with the intl-tel-input library - apply after initialization
  enhanceAccessibility(input, iti);
});

function enhanceAccessibility(input, iti) {
  // Add a delay to ensure intl-tel-input has finished initialization
  setTimeout(function() {
    try {
      // Get the container created by intl-tel-input
      var itiContainer = input.parentElement;
      if (!itiContainer || !itiContainer.classList.contains('iti')) {
        return; // Not an intl-tel-input container
      }

      // Find the selected flag element that's causing accessibility issues
      var selectedFlag = itiContainer.querySelector('.iti__selected-flag');

      if (selectedFlag && selectedFlag.nodeType === Node.ELEMENT_NODE) {
        // Only add attributes if they don't already exist (avoid conflicts)
        if (!selectedFlag.getAttribute('role')) {
          selectedFlag.setAttribute('role', 'button');
        }
        if (!selectedFlag.getAttribute('aria-haspopup')) {
          selectedFlag.setAttribute('aria-haspopup', 'listbox');
        }
        if (!selectedFlag.getAttribute('aria-expanded')) {
          selectedFlag.setAttribute('aria-expanded', 'false');
        }
        if (!selectedFlag.getAttribute('aria-label')) {
          selectedFlag.setAttribute('aria-label', meprTel.i18n.selectCountryCode);
        }
        if (!selectedFlag.getAttribute('tabindex')) {
          selectedFlag.setAttribute('tabindex', '0');
        }

        // Add unique IDs for ARIA relationships
        var inputId = input.getAttribute('id') || 'phone-input-' + Math.random().toString(36).substring(2, 11);
        var listboxId = inputId + '-listbox';

        // Set aria-controls immediately to satisfy validation requirements
        // The referenced element will be created when dropdown is opened
        if (!selectedFlag.getAttribute('aria-controls')) {
          selectedFlag.setAttribute('aria-controls', listboxId);

          // Create a temporary placeholder element to satisfy ARIA validation
          // This will be replaced when the actual dropdown is created
          createPlaceholderDropdown(itiContainer, listboxId);
        }

        // Use a less intrusive approach - only observe existing elements
        enhanceDropdownAccessibility(itiContainer, listboxId, selectedFlag);

        // Use passive event listeners to avoid conflicts
        setupAccessibilityObserver(itiContainer, selectedFlag);

        // Add safe keyboard navigation
        addKeyboardNavigation(selectedFlag);
      }

      // Enhance the phone input itself safely
      enhancePhoneInput(input);

      // Add live region for announcements
      setupLiveRegion(input, iti);

    } catch (e) {
      console.warn('MemberPress phone accessibility: Error enhancing accessibility', e);
    }
  }, 200); // Increased delay to avoid conflicts
}

function createPlaceholderDropdown(itiContainer, listboxId) {
  // Check if placeholder already exists
  var existingPlaceholder = document.getElementById(listboxId);
  if (existingPlaceholder) {
    return; // Already exists
  }

  // Create a hidden placeholder element to satisfy ARIA validation
  var placeholder = document.createElement('div');
  placeholder.id = listboxId;
  placeholder.style.display = 'none';
  placeholder.setAttribute('role', 'listbox');
  placeholder.setAttribute('aria-label', meprTel.i18n.countryCodeOptions);
  placeholder.setAttribute('data-placeholder', 'true');

  // Append to container but keep hidden
  itiContainer.appendChild(placeholder);
}

function enhanceDropdownAccessibility(itiContainer, listboxId, selectedFlag) {
  // Look for dropdown when it's actually created (lazy approach)
  var checkDropdown = function() {
    var dropdown = itiContainer.querySelector('.iti__country-list');
    if (dropdown && !dropdown.getAttribute('role')) {
      // Remove placeholder element if it exists
      var placeholder = itiContainer.querySelector('[data-placeholder="true"]');
      if (placeholder) {
        placeholder.remove();
      }

      dropdown.setAttribute('id', listboxId);
      dropdown.setAttribute('role', 'listbox');
      dropdown.setAttribute('aria-label', meprTel.i18n.countryCodeOptions);

      // aria-controls is already set, just ensure the dropdown has the correct ID
      // This ensures the ARIA relationship is valid

      // Enhance country items when dropdown is opened
      var countryItems = dropdown.querySelectorAll('.iti__country');
      countryItems.forEach((item, index) => {
        if (item && !item.getAttribute('role')) {
          item.setAttribute('role', 'option');
          item.setAttribute('id', listboxId + '-option-' + index);
          item.setAttribute('aria-selected', 'false');
        }
      });
    }
  };

  // Check immediately and also when container changes
  checkDropdown();

  // Set up observer for when dropdown gets created
  var dropdownObserver = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        checkDropdown();
      }
    });
  });

  dropdownObserver.observe(itiContainer, {
    childList: true,
    subtree: true
  });
}

function setupAccessibilityObserver(itiContainer, selectedFlag) {
  // Observe class changes for aria-expanded updates
  var classObserver = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
        try {
          var isOpen = itiContainer.classList.contains('iti__country-list-open');
          if (selectedFlag && selectedFlag.getAttribute && selectedFlag.setAttribute) {
            selectedFlag.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
          }
        } catch (e) {
          // Silently handle errors to avoid breaking functionality
        }
      }
    });
  });

  classObserver.observe(itiContainer, {
    attributes: true,
    attributeFilter: ['class']
  });
}

function addKeyboardNavigation(selectedFlag) {
  // Use passive event listener to avoid conflicts
  selectedFlag.addEventListener('keydown', function(e) {
    try {
      if (e.key === 'Enter' || e.key === ' ') {
        e.preventDefault();
        // Use a safer click simulation
        setTimeout(function() {
          if (selectedFlag.click) {
            selectedFlag.click();
          }
        }, 10);
      }
    } catch (e) {
      // Silently handle errors
    }
  }, { passive: false });
}

function enhancePhoneInput(input) {
  if (input && input.setAttribute) {
    if (!input.getAttribute('role')) {
      input.setAttribute('role', 'textbox');
    }

    // Add aria-label if not already present
    if (!input.getAttribute('aria-label') && !input.getAttribute('aria-labelledby')) {
      input.setAttribute('aria-label', meprTel.i18n.phoneNumberInput);
    }
  }
}

function setupLiveRegion(input, iti) {
  // Add live region for country code announcements
  var liveRegion = document.getElementById('phone-country-live-region');
  if (!liveRegion) {
    liveRegion = document.createElement('div');
    liveRegion.id = 'phone-country-live-region';
    liveRegion.setAttribute('aria-live', 'polite');
    liveRegion.setAttribute('aria-atomic', 'true');
    liveRegion.style.position = 'absolute';
    liveRegion.style.left = '-10000px';
    liveRegion.style.width = '1px';
    liveRegion.style.height = '1px';
    liveRegion.style.overflow = 'hidden';
    document.body.appendChild(liveRegion);
  }

  // Use one-time event listener to avoid multiple bindings
  var countryChangeHandler = function() {
    try {
      var selectedCountryData = iti.getSelectedCountryData();
      if (selectedCountryData && liveRegion) {
        liveRegion.textContent = meprTel.i18n.countryChangedTo + ' ' + selectedCountryData.name +
                                 ', ' + meprTel.i18n.countryCode + ' ' + selectedCountryData.dialCode;
      }
    } catch (e) {
      // Silently handle errors
    }
  };

  // Remove any existing listener and add new one
  input.removeEventListener('countrychange', countryChangeHandler);
  input.addEventListener('countrychange', countryChangeHandler);
}

function adjustPadding(input) {
  var flagContainer = input.parentElement.querySelector('.iti__flag-container'),
      flagWidth = window.getComputedStyle(flagContainer).getPropertyValue('width'),
      adjustedWidth = `${parseInt(flagWidth) + 10}px`;

  // Check if body has RTL class
  if (document.body.classList.contains('rtl')) {
    input.style.setProperty('padding-left', '10px', 'important');
    input.style.setProperty('padding-right', adjustedWidth, 'important');
  } else {
    input.style.setProperty('padding-left', adjustedWidth, 'important');
  }
}

// Handle phone field padding on ReadyLaunch Account
document.querySelectorAll('.mepr-profile-details__button').forEach(button => {
  button.addEventListener('click', () => {
    setTimeout(() => {
      telInputs.forEach(input => {
        adjustPadding(input);
        // Re-apply accessibility enhancements for dynamically loaded forms
        var iti = window.intlTelInputGlobals.getInstance(input);
        if (iti) {
          enhanceAccessibility(input, iti);
        }
      });
    }, 100); // Delay until open modal
  });
});