Repository navigation
1.14.2
Overview
This release improves submit reliability and modal keyboard behavior. The main focus is on resolving edge cases where form submission silently fails due to third-party listener interference, and on preventing keyboard events from escaping the address correction modal.
Key improvements in 1.14.2:
- Flexible target selector with resolver support and configurable insert position
- Fixed form submission failing when clicking nested elements inside submit buttons
- Fixed Enter key escaping the modal focus trap and triggering implicit form submission
- Fixed third-party click listeners interfering with submit resumption
New Features
Flexible Target Selector Configuration
- Feature: The
targetSelectoroption now supports dynamic resolution via a resolver function, and a newinsertPositionoption controls where inside the target element the modal is placed - Problem Solved: Static CSS selectors are insufficient when the injection target depends on runtime state (e.g., dynamically created modals, multiple forms on one page)
- Configuration:
insertPositionoption oninitAMS(), accepts standardinsertAdjacentHTMLpositions:'beforebegin','afterbegin','beforeend'(default),'afterend'resolvers.targetSelectorResolve(selector, addressObject), a resolver function that receives the configured selector and address object, and returns the actual selector to use. Falsy return values fall back to the original selector
- Reference: GitHub #23
Using the Resolver
EnderecoIntegrator.resolvers.targetSelectorResolve = function(selector, addressObject) {
// Dynamically determine the target based on runtime state
const activeModal = document.querySelector('.modal.show');
if (activeModal) {
return '#' + activeModal.id;
}
return selector; // fall back to configured selector
};Using Insert Position
EnderecoIntegrator.initAMS({
countryCode: '[name="country"]',
postalCode: '[name="zipcode"]',
locality: '[name="city"]',
streetFull: '[name="street"]'
}, {
targetSelector: '.my-modal-container',
insertPosition: 'afterbegin'
});Bug Fixes
Form Submit with Nested Button Elements
- Bug: Clicking on a nested element inside a submit button (e.g.,
<span>or<svg>icon) would cause the resumed submission to silently fail - Root Cause: After validation,
resumeFormSubmission()dispatched the synthetic click event onoriginalEvent.target, which was the inner element (span, svg), not the submit button itself. The inner element has no submit behavior - Solution: Use
originalEvent.target.closest('button, input[type="submit"]')to resolve to the actual submit control regardless of where inside the button the click occurred
Enter Key Escaping Modal Focus Trap
- Bug: Pressing Enter inside the address correction modal could trigger implicit form submission of the underlying page form, or propagate to parent handlers
- Root Cause: Two issues , (1) Enter keydown events inside the modal were not stopped from propagating, and (2) modal buttons had no explicit
typeattribute, defaulting totype="submit"inside forms - Solution:
- Added an Enter key handler to the modal that calls
stopPropagation()on all Enter presses andpreventDefault()on input elements (radio buttons, checkboxes) to block implicit form submission - Added explicit
type="button"to all modal button templates
- Added an Enter key handler to the modal that calls
- Behavior: Buttons and links inside the modal still activate normally via Enter; only propagation to the parent form is blocked
Third-Party Listeners Blocking Form Submission
- Bug: Form submission silently fails when third-party plugins register click listeners on the same submit button
- Root Cause:
blockSubmit()usedstopPropagation(), which only prevents bubbling to parent elements. Other listeners registered on the same button still fired during the blocking phase. A third-party multi-click preventer would see the original click, add a loading state, and then callpreventDefault()on the resumed synthetic click , silently preventing form submission - Solution: Use
stopImmediatePropagation()instead, which prevents all subsequent listeners on the same element from firing during the blocking phase. Third-party listeners still participate normally on the resumed event, since the resumed event is a newEventobject unaffected by the originalstopImmediatePropagation() - Behavior: Third-party listeners see exactly one click event , the resumed one after validation , instead of two (one blocked, one resumed)
External Modal Removal Leaves System in Broken State
- Bug: When the endereco modal is injected inside a dynamically-rendered parent (e.g. a third-party checkout overlay) via
targetSelector, closing that parent leaves the page in a broken state — scroll locked, future modals blocked - Root Cause: All Promise resolve paths lived exclusively in DOM event handlers attached to elements inside the modal. When an external actor removed the parent (and with it the endereco modal), no events could fire, so the Promise never resolved,
endereco-no-scrollstayed on the body, andpopupQueuecounters remained incremented - Solution: A
MutationObserverwatches for the modal element being disconnected from the document. When triggered, it performs the same cleanup asremovePopup()and resolves the Promise. In the normal flow, each handler disconnects the observer before resolving to prevent double cleanup - Ref: DEV-331
Update Notes
This is a drop-in replacement for 1.14.1. No configuration changes are required unless you want to use the new insertPosition or targetSelectorResolve features.