fix(js): honor the click in progress flag - #729
Conversation
A handler that called click() on its own element recursively dispatched click events until the stack was exhausted. dispatchEvent catches listener errors and logs them, so the overflow surfaced only as a console trace while the outer call returned normally. Track the flag per element and clear it after click processing, matching the click() algorithm in HTML. Sequential clicks are unaffected, and a cycle between two elements stops at the second dispatch because the flag belongs to the element rather than the call. Fixes h4ckf0r0day#726.
|
Merge note, since it is only visible from the other side: this and #728 both edit Verified on a locally merged tree: the element-level flag from this PR stops a handler that re-enters If both are taken, the correct resolution keeps this PR's flag check after the disabled early return and before #728's pre-click activation. Happy to push a pre-resolved branch if that is easier than resolving at merge time. |
Fixes #726.
HTMLElement.click()did not implement the HTML click in progress flag, so a handler that clicks its own element re-entered until the V8 stack was exhausted.dispatchEventwraps every listener intry { ... } catch(e) { console.error(e) }, so the resultingRangeErrorwas logged and did not propagate: the outerclick()returned normally and the overflow surfaced only as a console trace.Returned
2017on this host on v0.2.1 andmain; the depth is stack-size dependent. Chrome returns1.The flag is tracked per element in a closure-private
WeakSetand cleared infinally, so it survives a listener that throws and adds nothing page-observable.Verification
cargo nextest run --release --features render --no-fail-fast: 1486 run, 1485 passed. The single failure is a timing-sensitive test that also fails on unmodifiedmain.observer-intersectionidentically onmain.Note on merge order
This is independent of #721 and #722 and applies to
mainon its own. If it merges alongside #721, the flag check must stay after the disabled early return and before pre-click activation, otherwise a suppressed re-entrant call still flipscheckedbefore it returns. That ordering is not observable onmainalone, because pre-click activation does not exist yet.