Fix console errors in rich-text-mention-listbox#2919
Draft
vivinkrishna-ni wants to merge 1 commit intomainfrom
Draft
Fix console errors in rich-text-mention-listbox#2919vivinkrishna-ni wants to merge 1 commit intomainfrom
vivinkrishna-ni wants to merge 1 commit intomainfrom
Conversation
…t deferred binding updates - Guard slottedOptionsChanged to skip base class observable notifications when closed - Replace when-directive with hidden attribute for no-results label to avoid DOM marker teardown - Skip observable assignment in filterOptions when both old and new arrays are empty - Use backing field write for anchorElement to bypass requestReset() on subsequent anchoring - Clear filteredOptions via backing field in setOpen to avoid deferred binding crash Closes #2744
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Pull Request
🤨 Rationale
#2744
Rich text editor mention listbox throws multiple
TypeErrorconsole errors in Firefox (and occasionally Chrome) when using the@mentionfeature:"can't access property 'insertBefore', node.parentNode is null""can't access property 'nextSibling', current is null""can't access property 'hasChildNodes', this.fragment is undefined"These errors break the UI — the mention popup fails to render or behaves incorrectly.
👩💻 Implementation
FAST Element's
@observablesystem usesDOM.queueUpdate(requestAnimationFrame-based) to execute deferred binding updates. When the mention listbox closes or repositions, the anchored-region'srequestReset()setsinitialLayoutComplete = false, causing thewhen(initialLayoutComplete)directive to tear down its<slot>and detach DOM marker nodes. When the deferred binding update fires (next rAF), it tries toinsertBeforeon a detached marker whoseparentNodeisnull, causing the crash.Solution
Applied multiple targeted workarounds in the
RichTextMentionListboxcomponent to prevent FAST's deferred binding updates from encountering detached DOM markers:slottedOptionsChanged— conditional base class call: When the listbox is closed, skipsuper.slottedOptionsChanged()which triggers observable notifications (options,selectedIndex,selectedOptions) that queue deferred DOM updates. Instead, silently update the internal_optionslist directly.filterOptions— skip redundant empty-array assignment: When both old and new filtered options are empty (different array references), skip the@observableassignment to avoid queuing a deferred binding update for thewhen-directive that can crash with detached markers.anchorElementChanged— bypassrequestReset()on re-anchoring: When the anchored region already has an anchor element, write to the backing field_anchorElementdirectly and callupdate()instead of going through the observable setter. This avoidsrequestReset()→initialLayoutComplete = false→ DOM marker teardown cycle.setOpen— clear filteredOptions via backing field: When closing the listbox, write to_filteredOptionsbacking field directly instead of using the observable setter, to avoid queuing a deferred binding update that can crash during teardown.whendirective with?hiddenattribute for no-results label: Thewhendirective creates/destroys DOM fragments, which involves marker node manipulation vulnerable to the timing issue. Using?hiddenkeeps the element in the DOM and toggles visibility, avoiding the marker lifecycle entirely.Known Limitations
@invalid, clear, type@invalidagain), the no-results label may not appear in Firefox. This is because thefilterOptionsoptimization skips the@observableassignment when both old and new arrays are empty.@tag: When inserting a mention via the@trigger, the popup briefly appears at the top-left corner of the page before repositioning to the correct anchor location. This is caused by theanchorElementChangedworkaround that bypassesrequestReset()— the initial positioning is delayed untilupdate()completes.🧪 Testing
✅ Checklist