Add configurable code support - #1
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new code configuration flag (default true) that allows host apps to fully disable code blocks and inline code across all import/insert paths, preserving existing behavior unless explicitly turned off.
Changes:
- Introduces
codepreset/attribute support and asupportsCodecapability check on the editor element. - When disabled: filters out markdown CODE/INLINE_CODE transformers, skips CodeNode/CodeHighlightNode registration, removes code UI behaviors (toolbar button + insert command no-op), and strips
pre/codeHTML conversions to ensure imports reduce to plain text. - Adds Playwright + Capybara system coverage for “code disabled” behavior and round-trip persistence.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/config/lexxy.js |
Adds code: true to default preset to keep current behavior unless disabled. |
src/elements/editor.js |
Implements supportsCode, conditional node/feature registration, markdown transformer filtering, toolbar removal, and conversion stripping. |
src/editor/command_dispatcher.js |
No-ops dispatchInsertCodeBlock when code is disabled. |
src/extensions/format_escape_extension.js |
Avoids declaring CodeNode replacement when CodeNode isn’t registered. |
src/extensions/highlight_extension.js |
Gates code-dependent converters/transforms/mutation listeners behind supportsCode. |
test/browser/fixtures/code-disabled.html |
Adds a browser fixture with code="false". |
test/browser/tests/formatting/code_disabled.test.js |
Adds Playwright coverage for disabled code UI, markdown suppression, and import stripping. |
test/dummy/app/views/posts/_form.html.erb |
Wires code_disabled param to the editor code="false" attribute for system testing. |
test/system/code_disabled_test.rb |
Adds Capybara system tests validating no <pre> persistence and stripping on load. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #createDefaultToolbar() { | ||
| const toolbar = createElement("lexxy-toolbar") | ||
| toolbar.innerHTML = LexicalToolbar.defaultTemplate | ||
| toolbar.setAttribute("data-attachments", this.supportsAttachments) // Drives toolbar CSS styles | ||
| if (!this.supportsCode) toolbar.querySelector("[name='code']")?.remove() |
There was a problem hiding this comment.
This mirrors the existing data-attachments behavior: attachment buttons are likewise only hidden on the auto-created default toolbar, so a host-supplied toolbar (via toolbar="id" or an inline <lexxy-toolbar>) is treated as the host responsibility. When reached, the control is harmless — insertCodeBlock no-ops and the extension is gated, so there is no crash, just a dead button.
To stay consistent with that established pattern (and with the sibling tables option, which has the same property), I am leaving it as-is in this PR. The cleaner fix is a shared mechanism that applies the data-* feature attributes to whichever toolbar is resolved (default, external, or inline), so CSS hides disabled-feature buttons regardless of source — that would also close the same long-standing gap for attachments, so it is best done once across all features rather than per-feature here.
Make code blocks and inline code disablable via Lexxy.configure (code: false) or a code element attribute. The default stays true, preserving current behavior. When disabled: CodeNode/CodeHighlightNode are not registered, the code toolbar button and the CODE/INLINE_CODE markdown shortcuts are removed, insertCodeBlock no-ops, and the code/pre HTML conversions are dropped so code markup is reduced to plain text on every import path. Guards the CodeNode replacement in FormatEscapeExtension and the code-coupled registrations in HighlightExtension to avoid build-time crashes.
6e819df to
51322c8
Compare
What
Make code (code blocks and inline code) disablable via
Lexxy.configureor acodeelement attribute. The default iscode: true, so current behavior is unchanged.Why
Host apps want to opt out of code entirely (not just CSS-hide the toolbar button — markdown shortcuts, hotkeys, and paste/import can otherwise re-introduce it). This extends the existing
Lexxy.configurepreset/attribute mechanism with one flag.How it works when disabled
CodeNode/CodeHighlightNodeare not registered.insertCodeBlockno-ops.CODE(```) andINLINE_CODE(`) transformers are filtered out.code/preHTML conversions are dropped fromeditor._htmlConversions, so code markup is reduced to plain text on every import path (initial value,setValue, paste) and excluded from the sanitizer allow-list.Two coupling points are guarded to avoid build-time crashes:
FormatEscapeExtensiononly declares the{ replace: CodeNode }node entry when code is enabled (declaring a replacement for an unregistered node throws).HighlightExtensiononly registers its<pre>converter,CodeNodemutation listener, andCodeHighlightNodetransform when code is enabled.Testing
test/browser/tests/formatting/code_disabled.test.js(+ fixture): button absence, markdown fence/inline blocked, import stripping, and a no-crash/no-console-error guard.test/system/code_disabled_test.rb: Action Text round-trip (edit → save → render → re-edit) confirming no<pre>is persisted, plus existing-content stripping.yarn test:browser(chromium/firefox/webkit) green;yarn lintclean; existingcode_highlighting/color_highlightersystem tests still pass (code-enabled defaults preserved).