Slides: hit-test text-bearing shapes and pin ctx transform#330
Conversation
Two coupled bugs prevented selecting PPTX-imported placeholder shapes (type:'shape', kind:'rect', data.text set, no fill / no stroke). On the originally-reported deck every text click landed on the back-most full-bleed background image instead. 1. hitShape's visibility gate rejected any shape without fill or stroke. PR #321 folded inline text into ShapeElement.data.text but didn't update the hit-test side, so text-only shapes were silently unclickable on their visible body. 2. SlideRenderer leaves the canvas ctx with scale((hostWidth / SLIDE_WIDTH) * dpr) after each paint. Path2D variants of isPointInPath interpret the path commands through the active transform while the query (lx, ly) stays in canvas-pixel space, so interior clicks in logical coords landed well outside every shape's scaled-down footprint. The unit-test canvas stub ignores transforms entirely, which is why this latent bug went unnoticed. Add hasText to the gate (with the same OPEN_PATH_KINDS exclusion the fill branch carries, so bracket / brace shapes with text fall through to the stroke-band test instead of false-positive-ing across an auto- closed C / U interior), and wrap all four hitTestSlide call sites in a new hitTestAt helper that pins the ctx transform to identity for the duration of the hit-test. The wrapper also resets cleanly on the test stub, which exposes save / restore / setTransform as no-ops. Adds three regression tests in hit-test-elements.test.ts: text-only shape hits via bbox interior, empty shape misses, and OPEN_PATH_KINDS shape with text still does not hit on its auto-closed interior. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
GHSA-5xrq-8626-4rwp (Vitest UI server can read + execute arbitrary files when listening) hit vitest <4.1.0 across 22 transitive paths. `scripts/verify-entropy.mjs:267` fails the pre-push lane on any critical advisory, blocking unrelated work. Bump direct `vitest` and `@vitest/coverage-v8` deps in every package that pins them (`sheets`, `docs`, `slides`, `frontend`, `cli`) from ^3.1.x to ^4.1.8. pnpm hoist resolves transitive vitest to the new major across the lockfile. Two carry-over fixes for the v4 type changes: - `packages/{sheets,docs}/vite.config.ts` now import `defineConfig` from `vitest/config` instead of `vite`. Vite's own `UserConfigExport` no longer carries the `test:` key in @vitest/runtime v4, so the config-side import must come from vitest. - `packages/slides/src/view/canvas/ctx-spy.ts` swaps every `ReturnType<typeof vi.fn>` slot for a callable `Mock<(...args: any[]) => any>` alias. v4 widened the default `vi.fn()` return to `Mock<Procedure | Constructable>`, which TypeScript treats as a union of call + construct signatures and refuses to invoke without disambiguation. Other findings — high `tmp` (transitive via @nestjs/cli) and moderate `vite` (transitive via vitepress) — are not gated by the entropy threshold and remain to be addressed separately. verify:self green: 10 lanes pass in 107s. verify:entropy now reports "Vulnerabilities: 1 moderate, 1 high" only. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
|
Warning Review limit reached
More reviews will be available in 51 minutes and 58 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (15)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Verification: verify:selfResult: ✅ PASS in 151.4s
Verification: verify:integrationResult: ✅ PASS |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Summary
Two coupled bugs prevented selecting PPTX-imported text placeholder shapes (
type:'shape',kind:'rect',data.textset, no fill / no stroke). On the originally-reported deck every text click landed on the back-most full-bleed background image instead.hitShapevisibility gate ignoreddata.text. PR Slides: edit text inside shapes (PowerPoint / Google Slides parity) #321 folded inline text intoShapeElement.data.textbut didn't update the hit-test side, so text-only shapes were silently unclickable. Fixed by extending the gate to includehasText(with the sameOPEN_PATH_KINDSexclusion the fill branch carries, so bracket / brace shapes with text fall through to the stroke-band test rather than false-positive-ing across an auto-closed C / U interior).SlideRendererleaves the ctx withscale((hostWidth / SLIDE_WIDTH) * dpr)after each paint.Path2Dvariants ofisPointInPath/isPointInStrokeinterpret the path through the active transform while the query (lx, ly) stays in canvas-pixel space, so interior clicks in logical coords landed outside every shape's scaled-down footprint. Browser instrumentation confirmed the running matrix wasa = d ≈ 0.267. The unit-test canvas stub ignores transforms, which masked it. Fixed by routing all fourhitTestSlidecall sites through a newSlidesEditorImpl.hitTestAthelper that pins the ctx to identity around the hit-test and restores on exit.Bundled in this PR: a vitest 3 → ^4.1.8 bump across the workspace to clear GHSA-5xrq-8626-4rwp (the vitest UI critical advisory).
scripts/verify-entropy.mjs:267fails the pre-push lane on any critical, so the bug fix and the dep bump have to ship together.Test plan
pnpm verify:fastgreen (slides 1,560 / docs 877 / sheets 1,279 / frontend 507 / backend 175 — all under vitest 4)pnpm verify:selfgreen (10 lanes, includingverify:entropynow showing only 1 moderate + 1 high — the residualtmp/ vitepress-viteadvisories that aren't gated by the entropy threshold)074860d4,9d9b4528,b3921eaa) — all three select correctly viaeditor.selection.get(). Pre-fix, all three clicks landed on the back-most full-bleed background image (7cb34fec).hits a text-only shape (no fill, no stroke, has data.text)does not hit an empty shape (no fill, no stroke, no text)does not hit OPEN_PATH_KINDS interior even when shape has text🤖 Generated with Claude Code