(function () { if (document.__checkoutModalStreetValidatorInstalled) { return; } document.__checkoutModalStreetValidatorInstalled = true; const overlaySelector = "lightning-overlay-container"; const modalSelector = "lightning-modal"; const modalBodySelector = "lightning-modal-body"; let currentModalBody = null; let inputListenerAttached = false; let focusoutListenerAttached = false; function streetHasHouseNumber(streetValue) { if (streetValue == null || streetValue.trim() === "") { return true; // empty street: don't block } const houseNumberOk = streetValue.match(/[1-9]\d*[-/ ]*\d*[A-Za-z]?$/); return !!houseNumberOk; } function getModalBodyIfOpen() { const overlayContainer = document.querySelector(overlaySelector); if (!overlayContainer) return null; const modalElement = overlayContainer.querySelector(modalSelector); if (!modalElement) return null; const modalBody = modalElement.querySelector(modalBodySelector); return modalBody || null; } function findStreetInput(modalBody) { const streetHost = modalBody.querySelector('lightning-lookup-address[data-field="street"]') || modalBody.querySelector("lightning-lookup-address"); if (streetHost) { const inputInsideHost = streetHost.querySelector("input"); if (inputInsideHost) return inputInsideHost; } return ( modalBody.querySelector('input[name*="street" i]') || modalBody.querySelector('input[autocomplete*="street" i]') || modalBody.querySelector("input") ); } function findLastActionButton(modalBody) { const footerDiv = modalBody.querySelector("div.footer"); if (!footerDiv) return null; const actionButtons = footerDiv.querySelectorAll("commerce-action-button"); if (!actionButtons.length) return null; return actionButtons[actionButtons.length - 1]; } function setActionButtonDisabled(actionButton, shouldDisable) { if (!actionButton) return; if (shouldDisable) { actionButton.setAttribute("disabled", ""); actionButton.disabled = true; } else { actionButton.removeAttribute("disabled"); actionButton.disabled = false; } const innerButton = actionButton.querySelector("button"); if (innerButton) { innerButton.disabled = shouldDisable; if (shouldDisable) innerButton.setAttribute("disabled", ""); else innerButton.removeAttribute("disabled"); } } // Button-only update: silent, no reportValidity function updateButtonOnly(modalBody, streetInput) { const streetValue = streetInput.value || ""; const isValid = streetHasHouseNumber(streetValue); // Clear stale error silently when valid again try { if (isValid) { streetInput.setCustomValidity(""); } } catch (e) { } const lastActionButton = findLastActionButton(modalBody); if (!isValid) { setActionButtonDisabled(lastActionButton, true); } else { setActionButtonDisabled(lastActionButton, false); } } function getErrorMessage() { return ( window.missingHouseNumberErrorMessage || "Please enter a house number in the street field." ); } // Full validation with message: only on focusout function validateWithMessage(modalBody, streetInput) { const message = String(getErrorMessage() || ""); const streetValue = streetInput.value || ""; const isValid = streetHasHouseNumber(streetValue); try { if (!isValid) { streetInput.setCustomValidity(message); streetInput.reportValidity(); } else { streetInput.setCustomValidity(""); } } catch (e) { } const lastActionButton = findLastActionButton(modalBody); if (!isValid) { setActionButtonDisabled(lastActionButton, true); } else { setActionButtonDisabled(lastActionButton, false); } } function attachModalListeners(modalBody) { if (currentModalBody === modalBody) return; detachModalListeners(); currentModalBody = modalBody; const streetInput = findStreetInput(modalBody); if (!streetInput) return; // Silent button updates while typing if (!inputListenerAttached) { inputListenerAttached = true; modalBody.addEventListener( "input", function () { const inputNow = findStreetInput(modalBody); if (inputNow) { updateButtonOnly(modalBody, inputNow); } }, true ); } // Validation + message only when leaving the street input if (!focusoutListenerAttached) { focusoutListenerAttached = true; modalBody.addEventListener( "focusout", function (event) { const inputNow = findStreetInput(modalBody); if (!inputNow) return; const path = event.composedPath ? event.composedPath() : [ ]; if (!path.includes(inputNow)) return; validateWithMessage(modalBody, inputNow); }, true ); } // Initial state (silent) updateButtonOnly(modalBody, streetInput); } function detachModalListeners() { if (!currentModalBody) return; currentModalBody = null; inputListenerAttached = false; focusoutListenerAttached = false; } function validateWithRetries(retriesLeft) { const modalBody = getModalBodyIfOpen(); if (modalBody) { attachModalListeners(modalBody); return; } detachModalListeners(); if (retriesLeft > 0) { setTimeout(function () { validateWithRetries(retriesLeft - 1); }, 120); } } const bodyStyleObserver = new MutationObserver(function (mutations) { for (const mutation of mutations) { if (mutation.type === "attributes" && mutation.attributeName === "style") { validateWithRetries(6); } } }); bodyStyleObserver.observe(document.body, { attributes: true, attributeFilter: ["style"] }); validateWithRetries(6); })();