Skip to content

FetLife configurable editor + /sandbox/fetlife - #4

Draft
shved270189 wants to merge 12 commits into
mainfrom
configurable-fetlife
Draft

FetLife configurable editor + /sandbox/fetlife#4
shved270189 wants to merge 12 commits into
mainfrom
configurable-fetlife

Conversation

@shved270189

Copy link
Copy Markdown
Collaborator

What this is

A FetLife-tailored Lexxy integration branch that combines the configurable-feature work with a FetLife editor preset and a dedicated sandbox page.

Included

Brings together the configurable feature branches:

FetLife editor preset

New /sandbox/fetlife page (modeled on /sandbox/empty) configured with:

  • code: disabled
  • highlight: disabled
  • tables: disabled
  • marks: bold, italic, strikethrough (no underline)
  • headings: h1, h2, h3, h4 (H1 enabled)

Disabled features are removed from the toolbar and reduced to plain text on every import path (initial value, setValue, HTML paste, and cross-editor Lexical-clipboard paste).

Testing

  • vitest: 106 passing (includes new headings config tests)
  • Playwright (chromium): full suite green; added regression tests for disabled tables/highlight/code/marks and the highlight cross-editor-paste fix
  • Manual: verified in the dummy app that disabled features strip on import (including cross-editor paste) and that H1 works from the toolbar on /sandbox/fetlife

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.
Make table insertion disablable via Lexxy.configure (tables: false) or a tables element attribute. The default stays true, preserving current behavior.

When disabled: the TablesExtension is not registered (dropping the table nodes, table commands, and the figure/tbody import allow-list), the table toolbar button is hidden via the data-tables attribute, the lexxy-table-tools controls are not created, and insertTable no-ops. Table markup is reduced to plain text on import.
Make color highlighting disablable via Lexxy.configure (highlight: { enabled: false }) or a highlight element attribute. The default stays enabled, preserving current behavior. Both the object form { enabled: false } and a bare highlight: false are accepted.

When disabled: the HighlightExtension (toggle/remove commands, the <mark> import converter, paste canonicalizers) is not registered, the toolbar highlight dropdown is hidden via a data-highlight attribute, the dropdown setup is guarded, and highlight markup is reduced to plain text on import — both <mark> (by dropping the conversion) and legacy Trix styled elements (em/strong/span/del keep their bold/italic/strikethrough but lose the highlight color).
Make the inline marks (bold, italic, strikethrough, underline) configurable
via Lexxy.configure or a `marks` element attribute, as an allow-list. The
default enables all four, preserving current behavior. Accepts a JSON array
(marks='["bold","italic"]') or a whitespace-separated string (marks="bold
italic"); pass [] to disable every mark.

A disabled mark is inert everywhere, not just hidden from the toolbar: its
FORMAT_TEXT_COMMAND is swallowed by a high-priority interceptor (covering the
toolbar button, programmatic dispatch, and the native Cmd+B/I/U shortcuts), its
Markdown shortcut transformers are filtered out, its toolbar button is hidden
via a data-disabled-marks attribute, and its semantic tags are dropped from the
HTML import conversions so saved markup is reduced to plain text on load and
paste. A TextNode transform additionally clears any disabled-mark format bit
restored from pasted Lexical clipboard data.
# Conflicts:
#	app/assets/stylesheets/lexxy-editor.css
#	docs/configuration.md
#	src/elements/editor.js
#	test/dummy/app/views/posts/_form.html.erb
# Conflicts:
#	src/config/lexxy.js
#	src/elements/editor.js
#	test/dummy/app/views/posts/_form.html.erb
# Conflicts:
#	app/assets/stylesheets/lexxy-editor.css
#	src/config/lexxy.js
#	src/elements/editor.js
New sandbox template that mirrors /sandbox/empty but disables the features
FetLife does not use: code, highlight, and tables, and restricts inline marks
to bold, italic, and strikethrough (no underline).
Integrates the headings configuration option (basecamp#754) and wires it
into the editor, which the PR left unimplemented. A new headings.js holds the
canonical heading levels; the toolbar's format menu, active-state, and the
native editor-initialized event are driven by the configured "headings" array.
Adds an H1 ("Huge") heading level: toolbar button, icon, and the
setFormatHeadingHuge command. Defaults remain h2/h3/h4 so existing behavior is
unchanged. Markdown heading shortcuts stay unrestricted.
Copying between Lexxy editors carries an application/x-lexical-editor payload
whose styled text nodes are deserialized directly, bypassing the <mark> import
conversion that strips highlight from HTML. A disabled-highlight editor then
rendered the pasted color. Add a TextNode transform (registered only when
highlight is disabled) that clears color/background-color styles and the
highlight format bit, mirroring the disabled-mark stripper.
Copilot AI review requested due to automatic review settings June 11, 2026 09:16

Copilot AI 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.

Pull request overview

This PR adds per-feature configurability (tables, highlight, code, marks, headings) to the Lexxy editor, introduces an H1 (“Huge”) heading option, and adds a FetLife-specific sandbox preset/page that disables most rich-text features while ensuring disabled markup is stripped on all import paths (including cross-editor Lexical clipboard paste).

Changes:

  • Add feature flags/allowlists (tables, code, highlight.enabled, marks, headings) and wire them through editor initialization, toolbar rendering, commands, markdown transformers, and import/paste canonicalization.
  • Add an H1 heading level (“Huge”) and make toolbar heading levels configurable via headings.
  • Add /sandbox/fetlife in the dummy app plus extensive system + Playwright coverage for disabled-feature behavior and regression cases.

Reviewed changes

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

Show a summary per file
File Description
test/system/tables_disabled_test.rb System coverage for tables disabled (toolbar + import/round-trip stripping).
test/system/marks_disabled_test.rb System coverage for marks allowlist stripping on load + round-trip.
test/system/highlight_disabled_test.rb System coverage for highlight disabled stripping for <mark> + legacy styled elements.
test/system/code_disabled_test.rb System coverage for code disabled (markdown fence + import/round-trip stripping).
test/javascript/unit/editor/headings_configuration.test.js Unit tests for headings configuration resolution (default/preset/attribute).
test/javascript/native/attributes_change.test.js Updates attributes-change expectations (adds underline).
test/dummy/app/views/sandbox/show.html.erb Adds FetLife sandbox link and supports per-template editor options.
test/dummy/app/views/sandbox/_fetlife.html.erb FetLife sandbox partial (template target).
test/dummy/app/views/posts/_form.html.erb Wires query params into editor attributes for disabled-feature demos/tests.
test/dummy/app/controllers/sandbox_controller.rb Adds fetlife template and per-template editor option overrides.
test/browser/tests/tables/disabled.test.js Playwright coverage for tables disabled (UI, commands, import stripping).
test/browser/tests/formatting/marks_disabled.test.js Playwright coverage for marks allowlist (UI, commands/hotkeys, markdown, import, lexical paste).
test/browser/tests/formatting/highlight_disabled.test.js Playwright coverage for highlight disabled (UI, commands, import, lexical paste).
test/browser/tests/formatting/code_disabled.test.js Playwright coverage for code disabled (UI, markdown shortcuts, import stripping).
test/browser/fixtures/tables-false.html Fixture editor with tables="false".
test/browser/fixtures/marks-true.html Fixture for non-list marks="true" (fail-open).
test/browser/fixtures/marks-string.html Fixture for whitespace marks string parsing.
test/browser/fixtures/marks-none.html Fixture for marks='[]' (all marks disabled).
test/browser/fixtures/marks-limited.html Fixture for marks='["bold","italic"]'.
test/browser/fixtures/marks-empty.html Fixture for empty/bare marks attribute (fail-open).
test/browser/fixtures/highlight-false.html Fixture for highlight='{"enabled":false}'.
test/browser/fixtures/highlight-false-bare.html Fixture for highlight="false" shorthand.
test/browser/fixtures/code-disabled.html Fixture for code="false".
src/extensions/trix_content_extension.js Adjusts legacy Trix highlight import behavior when highlight is disabled.
src/extensions/tables_extension.js Gates table extension by supportsTables.
src/extensions/highlight_extension.js Gates code-dependent highlight wiring and <pre> conversion by supportsCode.
src/extensions/format_escape_extension.js Avoids replacing CodeNode when code support is disabled.
src/elements/toolbar.js Uses canonical HEADING_LEVELS for heading pressed-state; adds H1 menu entry.
src/elements/toolbar_icons.js Adds an H1 icon.
src/elements/editor.js Centralizes feature gating, strips disabled conversions, and adds lexical-paste stripping transforms.
src/elements/dropdown/highlight.js Guards highlight dropdown setup when highlight is disabled / buttons missing.
src/editor/marks.js Introduces mark constants + markdown transformer filtering helper.
src/editor/headings.js Introduces canonical heading level metadata used across toolbar/editor.
src/editor/command_dispatcher.js Adds H1 command, gates code/table insertion, and intercepts disabled marks at high priority.
src/config/lexxy.js Adds default preset options for tables/code/marks/headings and highlight.enabled.
docs/highlighting.md Documents disabling highlighting and boolean shorthand.
docs/configuration.md Documents new options (marks/tables/highlight/headings).
app/assets/stylesheets/lexxy-editor.css Hides toolbar controls via data-* attributes for disabled features/marks.
Files not reviewed (1)
  • src/elements/toolbar_icons.js: Language not supported

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

Comment thread src/elements/editor.js
Comment on lines +885 to 891
bold: { active: format.isBold, enabled: this.enabledMarks.includes("bold") },
italic: { active: format.isItalic, enabled: this.enabledMarks.includes("italic") },
strikethrough: { active: format.isStrikethrough, enabled: this.enabledMarks.includes("strikethrough") },
underline: { active: format.isUnderline, enabled: this.enabledMarks.includes("underline") },
code: { active: format.isInCode, enabled: true },
highlight: { active: format.isHighlight, enabled: true },
highlight: { active: this.supportsHighlight && format.isHighlight, enabled: this.supportsHighlight },
link: { active: format.isInLink, enabled: true },
Comment thread docs/configuration.md
Comment on lines 53 to +56
- `richText`: Pass `false` to disable rich text editing.
- `tables`: Pass `false` to disable tables entirely. Table insertion is removed, and any existing `<table>` markup is reduced to plain text (cell text preserved) when loaded. By default, tables are enabled.
- `highlight`: Color highlighting configuration. Pass `{ enabled: false }` (or simply `false`) to disable highlighting entirely (it is enabled by default). See [Highlighting](highlighting.md) for configuring the available colors.
- `headings`: Choose which heading levels the toolbar offers, as an array of heading tags. Defaults to `["h2", "h3", "h4"]`. Any of `h1`–`h4` listed gets a button in the format dropdown; levels left out are hidden. Pass `[]` to remove every heading button. Markdown shortcuts (`#`…`######`) still produce headings regardless of this setting. Example: `<lexxy-editor headings='["h1", "h2", "h3"]'></lexxy-editor>`.
@shved270189
shved270189 marked this pull request as draft June 11, 2026 09:30
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