Skip to content

Keep the right radios checked when forms move, leave or are renamed - #185

Merged
joeldrapper merged 4 commits into
mainfrom
claude/project-thread-8meecr
Oct 7, 2026
Merged

joeldrapper merged 4 commits into
mainfrom
claude/project-thread-8meecr

Conversation

@joeldrapper

@joeldrapper joeldrapper commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Requested by Joel · project thread

Fixes #162. Fixes #180.

Before: when a morph moved a form holding a checked radio with a form attribute, the radio briefly joined another group and unchecked the radio there. That could be the user's pick in the moved form (under preserveChanges), or a formless radio outside it (in both modes, and in Firefox as well as Chromium). Removing such a form did the same (#162). Separately, without preserveChanges, a user-checked radio that a form id change moved into another group was checked again when the morph settled, which unchecked a later radio that the markup checks in that group (#180).

After: those radios stay checked, and the last radio the markup checks in a group wins, as when parsing.

How:

  • Chromium and Firefox briefly reset the form owner of a control with a form attribute while a form around it moves or leaves. So when a node holding a form moves (placing children or completing a cross-parent move) or is removed, the checked radios inside it that have a form attribute now go unchecked first. They are checked again straight after, back in the group they were in. This step only runs when the node holds a form, so moving ordinary rows costs the same as before.
  • For A checked radio that a form id change moves into another group unchecks that group's later radio #180, a radio that the morph checks again when it settles now also joins the settle-time radio sync. That sync already runs straight afterwards and leaves the last radio the markup checks as the one that's checked.

Tests: test/new/moved-form-radios.browser.test.ts covers the cases from #162 and its comments, including the Firefox default-mode seed 37617970929. It also covers removing a form, which the form-state fuzzer from #167 found on main (seed 9104741). All six fail on main in Chromium, and four of them fail in Firefox. test/new/renamed-form-radios.browser.test.ts covers #180 and fails on main. With the fix, 24,000 form-state fuzzer seeds from #167 pass in Chromium and Firefox, apart from one seed (9303793) that also fails on main. That seed involves a select's selection, not radios. The full suite passes at 100% coverage.

Benchmark (perf-sweep harness, 31 rounds, lower quartile vs main): every scenario is within noise of main, from −6% to +3% (keyed reverse +3%, shuffle +2%). The #180 change only runs at settle, for radios that were held back.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SZddej5CrkTfW4RWeFsvyU

… moves or is removed

Chromium and Firefox briefly reset the form of a radio with a form attribute while
a form around it moves or leaves, so a checked one unchecked a radio in another
group. Those radios now move or leave unchecked and are checked again straight after.

Fixes #162

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZddej5CrkTfW4RWeFsvyU
@joeldrapper joeldrapper self-assigned this Oct 7, 2026
… group

Without preserveChanges, a checked radio that a form id change moved into another
group was checked again when the morph settled, unchecking a later radio the
markup checks there. Its group is now synced, so the last checked radio wins as
when parsing.

Fixes #180

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZddej5CrkTfW4RWeFsvyU
@joeldrapper joeldrapper changed the title Keep radios checked when a form holding a radio with a form attribute moves or is removed Keep the right radios checked when forms move, leave or are renamed Oct 7, 2026
@joeldrapper
joeldrapper marked this pull request as ready for review October 7, 2026 12:55
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T13:10:17.781530Z e8f4b0b New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZddej5CrkTfW4RWeFsvyU

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6356c72af2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/morphlex.ts
Comment thread src/morphlex.ts
…e forms

Radios with a form attribute that are unchecked for a move and checked again
straight after now go through the attribute, so an untouched one keeps following
it without preserveChanges. Inserting a live target that holds a form protects
those radios too, even when the target's markup checks nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZddej5CrkTfW4RWeFsvyU
@joeldrapper
joeldrapper merged commit abac812 into main Oct 7, 2026
7 checks passed
@joeldrapper
joeldrapper deleted the claude/project-thread-8meecr branch October 7, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants