Skip to content

Guard focus() against an uninitialized editor - #1177

Open
MatheusRich wants to merge 2 commits into
basecamp:mainfrom
MatheusRich:mr-guard-focus-uninitialized-editor
Open

Guard focus() against an uninitialized editor#1177
MatheusRich wants to merge 2 commits into
basecamp:mainfrom
MatheusRich:mr-guard-focus-uninitialized-editor

Conversation

@MatheusRich

Copy link
Copy Markdown
Contributor

focus() reads this.editor, which is only assigned in connectedCallback. When focus() runs before the editor is initialized, the #isContentFocused guard evaluates to false and execution falls through to this.editor.focus(), throwing "undefined is not an object (evaluating 'this.editor.focus')".

This can happen when using Lexxy alongside Turbo and autofocus. Turbo can call focus() on the element before the editor is initialized, leading to an error.

This commit makes Lexxy return early when this.editor is not set. Autofocus still works through the element's own #handleAutofocus, which runs after the editor is created.

`focus()` reads `this.editor`, which is only assigned in connectedCallback.
When `focus()` runs before the editor is initialized, the `#isContentFocused`
guard evaluates to false and execution falls through to
`this.editor.focus()`, throwing "undefined is not an object (evaluating
'this.editor.focus')".

This can happen when using Lexxy alongside Turbo and autofocus. Turbo can call
`focus()` on the element before the editor is initialized, leading to an error.

This commit makes Lexxy return early when `this.editor` is not set. Autofocus
still works through the element's own `#handleAutofocus`, which runs after the
editor is created.
Copilot AI review requested due to automatic review settings July 2, 2026 17:57

@claude claude 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.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Prevents lexxy-editor’s focus() override from throwing when invoked before connectedCallback() initializes this.editor (e.g., Turbo + autofocus calling focus() early). Adds a Playwright regression test ensuring early focus() is a safe no-op while preserving the existing autofocus behavior via #handleAutofocus() after initialization.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Changes:

  • Guard focus() with if (!this.editor || this.#isContentFocused) return to avoid calling .focus() on an uninitialized editor instance.
  • Add a browser test asserting editor.focus() on a newly-created (unconnected) <lexxy-editor> does not throw.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/elements/editor.js Adds an early return in focus() when this.editor hasn’t been created yet.
test/browser/tests/editor/focus.test.js Adds a regression test verifying focus() is a safe no-op before initialization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@samuelpecher samuelpecher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's the tradeoff in making this a no-op vs storing the focus intent and focusing the editor on eventual load?

Comment thread src/elements/editor.js Outdated
@MatheusRich

Copy link
Copy Markdown
Contributor Author

What's the tradeoff in making this a no-op vs storing the focus intent and focusing the editor on eventual load?

I think there's no need to do that for my use-case, at least. Lexxy's own #handleAutofocus runs in the requestAnimationFrame at the end of connectedCallback, so once the editor is created it gets focused anyway. Turbo's early focus() is just a redundant, premature duplicate of that, so dropping it changes nothing observable.

Co-authored-by: Samuel Péchèr <samp@hey.com>
Copilot AI review requested due to automatic review settings July 2, 2026 18:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

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.

3 participants