Skip to content

Conversation

@zoltanhosszu
Copy link
Contributor

@zoltanhosszu zoltanhosszu commented Dec 3, 2025

Editor bugfixes

This PR fixes a few small issues:

  • a small edge case for a toolbar state inconsistency
  • a weird blockquote unwrapping behavior
  • a broken editor state
  • undo/redo were triggering twice if keyboard shortcuts were used

More details in each commit.

@zoltanhosszu zoltanhosszu force-pushed the bugfix+editor-fixes branch 4 times, most recently from e1f9f84 to c2196d4 Compare December 9, 2025 10:18
Copy link
Contributor

@samuelpecher samuelpecher left a comment

Choose a reason for hiding this comment

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

Some nice QoL improvements. Great find on Undo/Redo. Maybe we can get the node generation a little tighter and delegate node unwrapping to Lexical?

Comment on lines 146 to 177
if (!html) html = "<p></p>"
const nodes = $generateNodesFromDOM(this.editor, parseHtml(`<div>${html}</div>`))
const defaultHtml = "<p></p>"
if (!html) html = defaultHtml
let nodes = $generateNodesFromDOM(this.editor, parseHtml(`<div>${html}</div>`))

if (nodes.length === 0) {
nodes = $generateNodesFromDOM(this.editor, parseHtml(defaultHtml))
}

Copy link
Contributor

Choose a reason for hiding this comment

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

From the caller in set value=on L30 and its caller in #loadInitialValue on L267, there's varying levels where a default is applied. #parseHtmlIntoLexicalNodes isn't even called if html === "".

I'd be up for avoiding a double call to $generateNodesFromDOM if we can.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @samuelpecher ! Would this change make more sense?

Copy link
Contributor Author

@zoltanhosszu zoltanhosszu Dec 15, 2025

Choose a reason for hiding this comment

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

Scratch that, I found a better solution. We needed to check every toolbar action if it was performed on the root element, and handle it just by inserting the required element. I think this is a much better solution.

Copy link
Contributor Author

@zoltanhosszu zoltanhosszu Jan 9, 2026

Choose a reason for hiding this comment

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

@samuelpecher went back to forcing a <p> on empty state. How's this? :)

@zoltanhosszu zoltanhosszu force-pushed the bugfix+editor-fixes branch 3 times, most recently from 8ab76cf to 33b90d7 Compare December 15, 2025 12:09
If the value contained a <pre>, the editor's set value() ended up placing the cursor within the <pre> tag. This caused a selected button state in the toolbar for <>.

A sleep function was added to a test to wait for async editor value updates.
Unwrapping a blockquote with simple TextNode (e.g. <blockquote>Hello</blockquote>), caused a Lexical error 99:  "Only element or decorator nodes can be inserted in to the root node"

This change wraps all TextNodes in a paragraph when unwrapping a blockquote.
Some initial editor values can result in an editor having no nodes inside. This can cause issues for trying to use the toolbar actions, which result in a Lexical error 51, causing a crash.

For these cases, we add an empty paragraph node as a default value.
The issue was that we were registering these commands with the toolbar hotkeys, which added a duplication for the built-in undo/redo action
@jorgemanrubia jorgemanrubia merged commit db74f05 into main Jan 9, 2026
5 checks passed
@jorgemanrubia jorgemanrubia deleted the bugfix+editor-fixes branch January 9, 2026 16:10
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.

4 participants