Skip to content

Highlight config and sanitization#549

Merged
samuelpecher merged 5 commits intomainfrom
highlight-config-sanitization
Jan 12, 2026
Merged

Highlight config and sanitization#549
samuelpecher merged 5 commits intomainfrom
highlight-config-sanitization

Conversation

@samuelpecher
Copy link
Collaborator

This PR implements configuration for the highlighter for both the provided buttons as well as pasted style sanitization and canonicalization.

Highlighter's lexical functions have been packaged into a Lexical extension, registering the components according the the lifecycle phases according to the passed configuration. Highlighter remains to apply the configuration from the editor to the extensions and expose the light interface to the command dispatcher. Commands are routed to the editor via the new TOGGLE_HIGHLIGHT_COMMAND.

This suggests a three part structure to layer functionality:

  • A high-level controller: Highlighter
  • Low-level Lexical operations: highlight_extension
  • UI in the toolbar and drop-downs.

The extension structure allows collapsing the fake HighlightNode into just a html.import configuration. Particularly, the change TrixContentExtension highlights this transition from fake Lexical node to basic extension. Low-level Lexical operations are then moved into highlight_extension.

Since html configuration is defined before non-global config is available, the sanitization step is deferred to a Node Transform through the use of Node State marking the node with a hasPastedStyles state. This has the double advantage that any node subsequently marked by other code leveraging $applyHighlight will benefit from the sanitization (such as TrixContentExtension).

Styles are sanitizes and canonicalized through an extension-scoped persistant StyleCanonicalizer. This optimization avoids repeating DOM element creation for calculating base RGB(A) values of the allowed styles, which is necessary as pastes have computed RGB(A) values. Lexical's CSS object cache is also leveraged for speed.

The config shape (by button/preset) was chosen as it is most likely users will simply want to change the buttons or permit additional colors rather than change both settings for color or background-color.

Copy link
Member

@jorgemanrubia jorgemanrubia left a comment

Choose a reason for hiding this comment

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

Superb work @samuelpecher. The suite is failing but good to go from my side 👏

@samuelpecher samuelpecher force-pushed the highlight-config-sanitization branch from c64d998 to b300b4b Compare January 10, 2026 00:59
@samuelpecher
Copy link
Collaborator Author

suite is failing

I suspect this is a difference with GH action's environment. I'll see if I can make it work before mocking it out.

* Allow configuration of highlighting
* Filter for PASTE_TAG during node generation
* StyleCanonicalizer object caches canonical style for speed
Requires lazy-loading the buttons on first toggle if the dropdown
connects before the editor is connected
Now that the first interaction called on the editor, the selection is at
the end.
@samuelpecher samuelpecher force-pushed the highlight-config-sanitization branch from b300b4b to 63fd7bd Compare January 12, 2026 21:27
Comment on lines +76 to +82
def highlight_1_rgb
dark_mode? ? "rgb(240, 200, 22)" : "rgb(136, 118, 38)"
end

def dark_mode?
page.evaluate_script "window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches"
end
Copy link
Collaborator Author

@samuelpecher samuelpecher Jan 12, 2026

Choose a reason for hiding this comment

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

@jorgemanrubia This was fun: the headless Chrome instance was picking-up the machine's dark mode setting. Local Omarchy is in dark mode, GH Actions is in light mode. Rather than depart from the pre-configured :selenium_chrome_headless I judo'd and made the test value dynamic.

cc @zoltanhosszu

Copy link
Member

Choose a reason for hiding this comment

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

OH LOL debugging that must have been fun!

@samuelpecher samuelpecher merged commit 9e40556 into main Jan 12, 2026
5 checks passed
@samuelpecher samuelpecher deleted the highlight-config-sanitization branch January 12, 2026 21:35
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.

2 participants