-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
fix(core): add reentrancy guard to focus patch #32655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Conversation
- add a reentrancy protection mechanism to the patched getter - use a Set to track active elements within the current call stack and setTimeout to defer cleanup, preventing recursive focus calls. Fixes storybookjs#32603
📝 WalkthroughWalkthroughAdds a runtime safeguard in Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Test as Test code
participant Elem as HTMLElement instance
participant Patch as preview.ts patch
participant Orig as originalFocus
Note over Patch: installs guarded getter on HTMLElement.prototype.focus (guarded by patchedFocus)
Test->>Elem: call focus()
activate Patch
Patch->>Patch: check focusingElements.has(Elem)?
alt Not in Set
Patch->>Patch: focusingElements.add(Elem)
Patch->>Orig: invoke originalFocus.call(Elem, ...)
Note right of Patch: schedule focusingElements.delete(Elem) on next tick (setTimeout 0)
Orig-->>Patch: return
Patch-->>Test: return result
else In Set (reentrant)
Patch-->>Test: return originalFocus (avoid re-entry)
end
deactivate Patch
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
code/core/src/test/preview.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Adhere to ESLint and Prettier rules across all JS/TS source files
Files:
code/core/src/test/preview.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Fix type errors and prefer precise typings instead of using any or suppressions, consistent with strict mode
Files:
code/core/src/test/preview.ts
🔇 Additional comments (2)
code/core/src/test/preview.ts (2)
126-142: LGTM! Reentrancy guard correctly prevents recursive focus calls.The getter logic properly implements the reentrancy protection:
- Detects recursive calls by checking Set membership (lines 128-131)
- Returns
originalFocusto break the cycle when recursion is detected- Defers cleanup via
setTimeout(..., 0)(line 138) to ensure the protection marker persists throughout the entire synchronous call chain- The arrow function correctly captures the lexical
thisfrom the getter contextThis approach aligns with the PR objective of fixing the "Maximum call stack size exceeded" error in the Cally date picker.
111-112: LGTM! Correctly preserves the original focus method.Capturing the original
focusreference before any patching is essential for the reentrancy guard to function correctly. The comment clearly documents this requirement.
|
View your CI Pipeline Execution ↗ for commit 4f8575b
☁️ Nx Cloud last updated this comment at |
Closes #32603
What I did
Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
There is an error:
Manual testing
Created a sandbox and added stories for the Cally, Chakra, and React Aria Components libraries.
After testing the pages, everything worked as expected with no errors.
Sandbox link:https://github.com/ia319/storybook-react-vite-focus-sandbox
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>Summary by CodeRabbit