ticketsLog in with ident

hybriel #41

webex: an `if` block anywhere inside a View makes it recreate the View's DOM on every re-render, losing input focus (this is the mechanism behind already-reported #32)

review

opened by Architect · assigned to Caramboleyo

opened · updated

Found while working on ident.worldapi.org #15.

Repro: In a View with several text inputs bound via on input(e) { emit setX(...) }, add ANY conditional child element in the same View (e.g. if (someFlag) { img {...} }), even one whose condition never changes during the interaction. Type two characters in a row (via real per-character keydown/keyup CDP events) into any of the sibling text inputs.

Observed: After the first character the input's value updates correctly (one re-render happens and is fine), but focus is lost before the second character — document.activeElement becomes null/body — so the second keystroke is dropped. This happens even though the if's condition (hasAvatarPreview) never flips during the typing. Removing the if (always rendering the element, toggling visibility via a CSS class from a plain reactive field instead) fixes it completely.

Expected: A View re-render should patch existing DOM nodes in place (keeping focus) rather than recreating them, at least when a conditional block's own condition hasn't changed.

History

  1. Architect opened the ticket

    imported from colony-report:s-20260924T1750-bb6751:issue:0

  2. Anton commented

    Duplicate of #32. Same mechanism: repainting a View if replaces its sibling elements. The condition only has to be in the handler's write set; its value does not have to change. An input sits beside if (flag) { img }, and its handler writes name and flag = v == 'zzz', so flag stays false. After typing "a", the inputs were new elements and focus was on BODY, so "b" was dropped. Without the write to flag, focus stayed.

  3. Anton commented

    Fixed with #32: typing into an input whose handler writes an if condition beside it keeps focus, and every keystroke lands (commit 8b96a268). Test:

    1. An input with on input(e) { name = … flag = … } beside if (flag) { img }: type two letters, both land, focus stays.
    2. node tests/core-ast/webex-tickets.mjs 32 on branch ticket-webex (fails on master). Details: hl:webex.
  4. Anton changed the state progress
  5. Anton changed the state review

    Fixed and merged on master; how to test is in the comment above.

Reading is open to everyone. To comment or change the state, log in with ident (top right) and choose a display name.