Skip to content

selection: install resize pointer listeners once#49

Merged
avanelsas merged 3 commits into
mainfrom
feature/audit-refactors-pass-1
May 12, 2026
Merged

selection: install resize pointer listeners once#49
avanelsas merged 3 commits into
mainfrom
feature/audit-refactors-pass-1

Conversation

@avanelsas
Copy link
Copy Markdown
Owner

@avanelsas avanelsas commented May 12, 2026

Summary

Single behaviour-preserving refactor from the audit's lowest-risk findings.

  • `selection` — the resize-drag `pointermove` / `pointerup` listeners are now installed once in `install!` (mirroring `dnd/drag`'s pattern) instead of being attached on every handle pointerdown and detached on pointerup. Both handlers already early-exit on `resize-active?`, so they are inert until a drag begins.

Inline-edit change reverted

This branch originally also contained an `inline-edit` refactor that converted its `defonce #js {}` cell to a Clojure atom. That change failed the manual smoke test ("text disappears after Esc / blur"). It is reverted on this branch — see commits `95a8b45` (original) and `c3f2750` (revert) for the audit trail. Suspected cause is the `defonce` hot-reload trap (the var is bound to the old JS-object shape when the dev server reloads the new file, so `@edit-state` runs against a JS object), but until that is confirmed with a deterministic reproduction I'd rather not re-land this piece. The selection change is independent and unaffected.

Test plan

  • `clj-kondo --lint src test scripts` — 0 errors, 0 warnings
  • `cljfmt check` — clean
  • `npx shadow-cljs compile test` — 813 tests, 2404 assertions, 0 failures, 0 errors
  • `npx shadow-cljs release app` — 0 warnings
  • Manual smoke: resize a free-placement node from any of the 8 handles, multiple drags in one session, hot reload mid-app
  • Manual smoke: double-click a text node, type, Esc / blur exits cleanly; selection survives reload (regression check — should match `main` exactly after the revert)

🤖 Generated with Claude Code

avanelsas and others added 3 commits May 12, 2026 11:34
The edit-state was a defonce #js {} accessed via unchecked-get/set —
a second state cell outside app-state, invisible to devtools and
indistinguishable from PLOP. Promotes it to a defonce atom holding a
Clojure map; live DOM element refs ride in the map values. The
serializable slice (:text-editing-id) is still mirrored to
state/app-state under :ui, unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
start-resize! attached pointermove / pointerup on every drag and
finish-resize! removed them — that worked but meant the listeners
were churned per gesture, and a missed cleanup (hot reload, exception)
would silently leak handlers. The pattern mirrors dnd/drag.cljs
already: install once at mount, the handlers themselves early-exit on
resize-active? until a drag begins. No behaviour change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avanelsas avanelsas changed the title Audit pass 1: drop two mutable-cell smells selection: install resize pointer listeners once May 12, 2026
@avanelsas avanelsas merged commit e020282 into main May 12, 2026
1 check passed
@avanelsas avanelsas deleted the feature/audit-refactors-pass-1 branch May 12, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant