Repository navigation
Conversation
|
Hi @Liuzikaii! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
Summary
Fragment refs keep the caller-owned listener options object and read it again later. Changing that object after registration can leave an event listener active after removeEventListener, once delivery or signal abort.
Fixes #37598
Root cause
StoredEventListener.optionsOrUseCapture aliases the caller object. indexOfEventListener and cleanup derive capture from the mutated object, although existing native listeners were attached using the original capture value.
Changes
Copy the supported option fields at registration time. Retain the snapshot for matching, once/abort cleanup and later children. Add regression tests for explicit removal, once and AbortSignal cleanup after capture mutation.
Before / after
Before: The listener remains active. A once listener may also fire again on another child, and abort cleanup can remove the registration record while leaving the original native listener attached.
After: Registration should keep the capture/options values read at addEventListener time, as the native API does. Removing the original non-capture listener should stop its callbacks.
How did you test this change?
Before: removal/later-child and once regressions each produce 2 calls instead of 0 and 1 respectively. After: both development and production Fragment suites pass 101/101 tests, including the new abort regression. ESLint, Prettier and Flow (dom-node-webpack configuration, which includes DOM bindings) pass.
Validation ran on Windows. Dependencies were installed with frozen yarn.lock using the available Node 24.19.0 runtime; targeted test runs used the repository Jest CLI. Flow was invoked via node node_modules/flow-bin/cli.js status with the generated renderer configuration (the equivalent Windows CLI path). ESLint and Prettier were run directly on changed files. The entire repository test/build matrix was not run.
Compatibility and risks
Boolean and omitted options retain their existing behavior. Snapshotting reads the supported dictionary fields once and preserves optional passive defaults. No public API is added.
Related work
Searched all Issue/PR states for Fragment capture/options/mutated/snapshot and examined recent Fragment commits. #36047 and #37251 normalize equivalent option forms; #37457 handles aborted registration cleanup. They do not snapshot caller-owned options, and the new regressions fail on main after those fixes. No equivalent issue or PR was found.