Support Autosuggest on dynamic elements. Addresses #2387. #2404
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description of the Change
Refactors parts of the Autosuggest script to support Autosuggest on dynamic elements, i.e. elements inserted into the DOM after page load.
This is achieved by implementing a Mutation Observer that watches the document for new elements, and adds Autosuggest to any new inputs that match the selectors used for Autosuggest.
This required rearranging some logic so that matching inputs could be found and prepared within arbitrary nodes.
Alternate Designs
As mentioned in #2387, one option considered was just listening for inputs on the document body and performing Autosuggest queries when the triggering element matched the Autosuggest selectors. By binding the event listener to the document this meant that input events from dynamic elements would trigger Autosuggest without needing to bind the events directly to the dynamic element.
The problem with this approach is that Autosuggest also requires some HTML attribute changes, and the insertion of a container for Autosuggest results. This could not be done by listening to events on the body. The Mutation Observer approach allows us to spot any inputs that were inserted dynamically and bind the events as well as make the necessary HTML changes.
Benefits
The Autosuggest functionality will now work on search inputs that are dynamically inserted after page load.
Possible Drawbacks
One potential source of dynamic input elements is from a JavaScript application on the page that uses a library like React or Vue which takes full responsibility for managing the DOM within the scope of the application. By responding to elements inserted by activity in these applications, the DOM could be modified in ways the application does not expect, which could lead to unexpected results.
Additionally, in cases where such an application is present on the page, there could possibly be a performance impact from observing the entire document for mutations throughout the life of the page, although I have not measured this.
In these cases a site may want to opt out of the observer, so that this behaviour does not cause unintended side effects. Alternatively the observer could be made opt-in for sites that expect to need it, but aren't using an incompatible library. Another alternative could be to simply make the function for adding Autosuggest globally available, so developers could either implement an observer themselves, or apply Autosuggest to dynamic elements on their own terms.
Verification Process
This code snippet will insert an Autosuggest-compatible search input into the DOM 10 seconds after page load:
Without the changes from this PR this input will not have Autosuggest functionality. With the changes from this PR applied Autosuggest will be enabled for this input.
Checklist:
Applicable Issues
#2387
Changelog Entry
Adds support for Autosuggest to dynamically inserted search inputs.