webviews: the composer's caret plugin keeps its own window, so teardown never throws (base red)

Merged
TE
15d ago
+7-4

Base webview red: home-composer-menu and home-quote-selection have failed on every feat-cmux-next web run that ran the shards since ad3e9b65 (#22798), with ReferenceError: window is not defined between tests.

Cause

#22798's keep-caret plugin in MarkdownField.tsx adds blur and focus listeners on the global window and removes them in its plugin view's destroy. Milkdown destroys the editor asynchronously, after a test has unregistered its DOM, so destroy reads a global that no longer exists.

Change

The plugin keeps the editor's own window (editorView.dom.ownerDocument.defaultView) when it adds the listeners, and removes them from that same window. In the app this is the same window as before; only the lookup at teardown changes.

Changelog

none

Observed / Not run

  • Red on base db57fbc06d76 (local, bun 1.4.2): bun test test/home-composer-menu.test.tsx test/home-quote-selection.test.tsx reports ReferenceError: window is not defined (unhandled errors between tests, so the files fail).
  • Green on this head: the same command, plus #22798's composer-inbound-keeps-caret.test.tsx, gives 7 pass, 0 fail, no errors.
  • Base CI: in the last 15 base web runs that ran the react-apps-check shards, both files failed in every run from ad3e9b65 on (11 of 11) and passed in every run before it.
  • scripts/web-lint.sh: only check:text-focus fails, which is red on base db57fbc06d76 (run-board/variants/timeline/timeline.css:14, a file this PR does not touch).
  • Not run here: the Playwright browser lane (agent-pane-inbound-keeps-caret.test.ts); PR CI runs it.

Agent session: huge-blue

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes a teardown crash in the composer's caret plugin so home-composer-menu and home-quote-selection stop failing on every base web run.

#22798's keep-caret plugin adds blur/focus listeners on the global window and removes them in its destroy. Milkdown destroys the editor asynchronously, after a test has unregistered its DOM, so destroy reads a global that no longer exists and throws ReferenceError: window is not defined. The plugin now keeps the editor's own window (editorView.dom.ownerDocument.defaultView) and removes the listeners from that same window. In the app this is the same window as before; only the teardown lookup changes.