Skip to content

fix: guard Node.contains() against non-Node event targets (#101)#103

Merged
zacharias-ona merged 1 commit into
mainfrom
fix/101-node-contains-typeerror
Apr 16, 2026
Merged

fix: guard Node.contains() against non-Node event targets (#101)#103
zacharias-ona merged 1 commit into
mainfrom
fix/101-node-contains-typeerror

Conversation

@zacharias-ona
Copy link
Copy Markdown
Collaborator

Closes #101

What

TypeError: Failed to execute 'contains' on 'Node': parameter 1 is not of type 'Node' was thrown in editor event handlers when MouseEvent.relatedTarget or Event.target was a non-Node EventTarget (e.g. when the mouse leaves to a cross-origin iframe or the browser window). The code used unsafe as Node / as HTMLElement casts on these properties before passing them to Node.contains() and Element.closest().

How

Replaced all unsafe as casts on event.target and event.relatedTarget with instanceof Node / instanceof HTMLElement guards in three locations:

  • draggable-block-plugin.tsxhandleMouseMove, handleMouseLeave, and handleMenuMouseLeave
  • page-search.tsxhandleClickOutside

Added a DOM event target safety convention to .agents/conventions.md to prevent this class of bug from recurring.

Testing

Added node-contains-safety.test.ts — a static analysis test that scans all component source files for unsafe as Node or as HTMLElement casts on event.target / event.relatedTarget. The test fails if any such pattern is found, ensuring future code follows the instanceof guard convention.

Full CI passes: pnpm lint && pnpm typecheck && pnpm test (58 tests) and pnpm test:e2e (27 tests).

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
memo Ready Ready Preview, Comment Apr 16, 2026 7:07pm

Request Review

@zacharias-ona zacharias-ona merged commit e96940a into main Apr 16, 2026
6 checks passed
@zacharias-ona zacharias-ona deleted the fix/101-node-contains-typeerror branch April 16, 2026 19:12
@zacharias-ona
Copy link
Copy Markdown
Collaborator Author

✅ UI verification passed — design spec compliance confirmed.

All changes in this PR are runtime type-safety guards (instanceof checks replacing as casts on event targets). No visual output, styling, layout, or rendering behavior was modified. Screenshots skipped — changes are invisible to the user.

@zacharias-ona
Copy link
Copy Markdown
Collaborator Author

✅ Post-merge verification passed.

E2E suite: 27/27 tests passed against https://memo.software-factory.dev

Ad-hoc smoke tests — routes tested:

  • / — landing page loaded, title present
  • /sign-in — rendered with email input
  • /api/health — healthy
  • Authenticated login flow — redirected to workspace
  • Workspace page — fully loaded
  • Editor navigation via sidebar — page opened, editor rendered

Skipped: /dashboard (not yet built)

No console errors detected (unauthenticated or authenticated).

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.

bug: TypeError in Node.contains() from editor event handlers (Sentry MEMO-7)

1 participant