Make Lexxy the default Action Text editor for new applications - #40
jorgemanrubia wants to merge 5 commits into
Conversation
New applications, and applications that set `config.load_defaults "8.2"`, render `rich_textarea` with Lexxy instead of Trix. Upgraded applications keep Trix until they opt in. The change builds on the editor adapter from rails#51238: * `config.action_text.editor` still defaults to `:trix`, and becomes `:lexxy` in `load_defaults "8.2"`, with a commented entry in `new_framework_defaults_8_2.rb`. * Action Text registers a Lexxy editor adapter next to the Trix one, so applications on the new defaults boot before the `lexxy` gem is added. * `bin/rails action_text:install` installs the configured editor, or the one passed with `--editor`. For Lexxy, it adds the `lexxy` gem, its JavaScript and stylesheet, and the `lexxy-content` layout class. * The Action Text dummy application pins Trix, which its forms and system tests exercise. Stored rich text needs no migration: Lexxy loads content saved by Trix.
There was a problem hiding this comment.
🟡 Changes recommended
The installer silently maps unsupported configured editors to Trix, and its config-driven selection lacks direct coverage.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Makes Lexxy the default Action Text editor for Rails 8.2 applications while preserving Trix for upgraded applications.
Changes:
- Adds and registers a Lexxy editor adapter.
- Updates installation to configure Lexxy or Trix assets and dependencies.
- Adds versioned defaults, tests, and documentation.
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
File summaries
| File | Description |
|---|---|
railties/test/generators/action_text_install_generator_test.rb |
Tests editor-specific installation. |
railties/test/application/configuration_test.rb |
Tests versioned editor defaults. |
railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_2.rb.tt |
Documents the 8.2 opt-in. |
railties/lib/rails/application/configuration.rb |
Sets Lexxy for 8.2 defaults. |
guides/source/upgrading_ruby_on_rails.md |
Documents migration between editors. |
guides/source/getting_started.md |
Updates generated import-map pins. |
guides/source/configuring.md |
Documents editor configuration. |
guides/source/action_text_overview.md |
Updates Action Text installation and usage guidance. |
guides/source/8_2_release_notes.md |
Announces the new default. |
actiontext/test/unit/editor/lexxy_editor_test.rb |
Tests the Lexxy adapter. |
actiontext/test/unit/editor/configurator_test.rb |
Tests Lexxy adapter construction. |
actiontext/test/dummy/config/application.rb |
Keeps the test application on Trix. |
actiontext/README.md |
Describes both supported editors. |
actiontext/lib/generators/action_text/install/templates/trix/actiontext.css |
Provides the Trix stylesheet template. |
actiontext/lib/generators/action_text/install/templates/lexxy/actiontext.css |
Imports Lexxy styles. |
actiontext/lib/generators/action_text/install/templates/layouts/action_text/contents/_content.html.erb.tt |
Generates editor-specific content classes. |
actiontext/lib/generators/action_text/install/install_generator.rb |
Selects and installs editor dependencies. |
actiontext/lib/action_text/engine.rb |
Registers Lexxy and Trix. |
actiontext/lib/action_text/editor/lexxy_editor.rb |
Implements Lexxy tag rendering. |
actiontext/lib/action_text/attribute.rb |
Generalizes editor documentation. |
actiontext/CHANGELOG.md |
Records the behavior change. |
actiontext/app/models/action_text/rich_text.rb |
Generalizes model documentation. |
actiontext/app/helpers/action_text/tag_helper.rb |
Documents editor-specific markup. |
Review details
- Files reviewed: 22/23 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| def editor | ||
| @editor ||= options[:editor] || (lexxy_configured? ? "lexxy" : "trix") |
There was a problem hiding this comment.
🤖 Fixed in a0b15e6. The installer now refuses an editor it can't set up, with a message pointing at --editor=lexxy or --editor=trix, instead of falling back to Trix. A generator test covers it.
| # Lexxy's JavaScript and stylesheets are provided by the `lexxy` gem, so add it | ||
| # and import it in your JavaScript entrypoint before enabling this setting. |
There was a problem hiding this comment.
🤖 Fixed in a0b15e6. The comment now says to set up Lexxy's JavaScript for import maps or a JavaScript bundler, and links Lexxy's installation instructions.
| test "adds the lexxy gem when installing Lexxy" do | ||
| run_generator_instance ["--editor=lexxy"] |
There was a problem hiding this comment.
🤖 Fixed in a0b15e6. New generator tests install the editor named by config.action_text.editor without --editor, and check that --editor=trix takes precedence over a configured :lexxy.
Action Text now depends on the lexxy gem, as it depends on action_text-trix. Until a Lexxy release depends on railties instead of rails, which would otherwise make the dependency circular, the Gemfile takes lexxy from basecamp/lexxy. Action Text doesn't require the gem: its engine sets config.action_text.editor to :lexxy when it loads, which would switch existing Trix applications. The installer keeps adding it to the Gemfile of applications that use Lexxy. Action Text's sanitizer keeps the elements and attributes Lexxy produces: tables, audio and video, strikethrough, code languages, and style attributes reduced to safe CSS, now including var(). fill_in_rich_textarea finds editors like Lexxy, whose editable content sits inside the editor element, by that element's attributes, and fills them in through its value. The dummy application serves Lexxy's JavaScript, and new system tests cover filling in, saving, and editing rich text with Lexxy. TrixEditorTest's with_editor now switches to the editor it names. The installer refuses an editor it can't set up, instead of falling back to Trix.
while_offline restored the previous network conditions with Object#with, which reads them back from Chrome with string keys. Selenium then adds its defaults as symbol keys, and json refuses to serialize the duplicate keys. The error left Chrome offline, so the system tests that ran after it failed with net::ERR_INTERNET_DISCONNECTED.
…secamp/rails#40 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
New applications get Lexxy only. Action Text no longer depends on action_text-trix, and it requires lexxy the way it used to require action_text/trix. On a Rails version that registers Lexxy, Lexxy leaves config.action_text.editor, the sanitizer lists, and blob JSON alone, so upgraded Trix applications keep Trix (basecamp/lexxy#1261 and rails#1262). Applications that use Trix add gem "action_text-trix". Rendering a Trix editor without it raises an error that says so, and the installer adds the gem for --editor=trix, mirroring how Sprockets became an optional dependency in Rails 7.0. The installer also sets config.action_text.editor when --editor differs from the configured editor, after config.load_defaults so it takes effect, and warns about other assignments that would take precedence. Until a Lexxy release includes basecamp/lexxy#1260, rails#1261, and rails#1262, the Gemfile takes lexxy from a branch that combines them.
New Ruby files in app/ and lib/ declare Markdown markup, as the Markdown API check requires.
e5806b2 to
683a708
Compare
Motivation / Background
New Rails applications still start with Trix as their rich text editor. Lexxy is a newer editor for Action Text, built on Meta's Lexical, with real
<p>paragraphs, Markdown shortcuts, code highlighting and attachment previews. It already plugs into Action Text through the editor adapter from ExtractActionText::Editorbase class andActionText::TrixEditoradapter, but only for applications that know to install it.This makes Lexxy the editor new applications start with, and the only editor Action Text installs by default. Applications that upgrade must not change under their feet, so the switch goes through the versioned defaults mechanism, and existing Trix applications keep a clear path to keep Trix.
Detail
Defaults.
config.action_text.editorstill defaults to:trix, and becomes:lexxyinconfig.load_defaults "8.2". There is a commented entry innew_framework_defaults_8_2.rb, a versioned table in the Configuring guide, and a release notes entry. The steps and the application tests for new and upgraded apps mirror Undeprecateconfig.active_job.enqueue_after_transaction_commitand flip it to true by default.Adapter. Action Text ships a Lexxy editor adapter next to the Trix one and registers both. Lexxy already emits Action Text's canonical HTML, so the adapter only renders
<lexxy-editor>with the content in itsvalueattribute.Dependencies. Action Text now depends on
lexxyand requires it, the way it used to depend on and requireaction_text-trix. It no longer depends onaction_text-trix. Three Lexxy changes make that work:actiontext→lexxy→railscycle, which Bundler refuses. It mirrorsaction_text-trix'srailtiesdependency.config.action_text.editoralone when Rails has already registered Lexxy. Without it, loading Lexxy would switch every upgraded Trix application to Lexxy.Blob#as_json, which raised without URL options.Until a Lexxy release includes all three, the Gemfile takes
lexxyfromrails-action-text-default, a basecamp/lexxy branch that combines them.Trix is optional. This mirrors Rails 7.0's "Sprockets is now an optional dependency":
gem "action_text-trix", including those that load Trix's JavaScript from npm or a vendored copy. The gem is small and only depends onrailties, so I chose a single rule over an adapter option to bypass the check.rails/alleager load Action Text even when they don't use rich text, and most upgraded applications keep:trix.Installer.
bin/rails action_text:installinstalls the editorconfig.action_text.editornames, or the one passed with--editor. It refuses an editor it can't set up.gem "action_text-trix". For Lexxy, there's no gem to add.--editordiffers from the configured editor, it writesconfig.action_text.editorintoconfig/application.rbafterconfig.load_defaults, replacing any plain assignment, so the choice takes effect.config/application.rb, initializers or environment files that would take precedence.--editorcame in with the adapter PR and hasn't shipped in a release.Sanitizer. Rendered content keeps the markup Lexxy produces: tables,
audio,video,source,embed,s,controls,poster,data-language,start,styleandvalue.stylevalues still go through Loofah's CSS scrubbing, which now allowsvar().System test helper.
fill_in_rich_textareaworks with Lexxy, whoserole="textbox"element sits inside<lexxy-editor>, and matches Trix exactly as before.Tests.
action_text-trixgem from Rails' Gemfile.Lexxy::Engineposition in the railtie order.Docs. The Action Text overview, Configuring, Upgrading and Getting Started guides, the 8.2 release notes, the helper docs, the Action Text README and CHANGELOG are updated.
Existing Trix applications
Add the gem. Add
gem "action_text-trix"to keep using Trix.The editor setting. While
config.load_defaultsstays below 8.2, the editor doesn't change. To move to 8.2 defaults and keep Trix, setconfig.action_text.editor = :trix.Apps already on Lexxy through the
lexxygem. Setconfig.action_text.editor = :lexxy, or move to 8.2 defaults. Otherwise they fall back to Trix, and the missing-gem error says so.Switching to Lexxy. There's no gem to add. Swap the JavaScript imports, uncomment the entry in
new_framework_defaults_8_2.rb, and changetrix-contenttolexxy-contentin the content layout. The Upgrading guide covers these steps.Stored rich text. It needs no migration. Rendering doesn't involve the editor, and Lexxy loads Trix's markup.
Changes for every application, whichever editor it uses.
previewableand a previewurlwhen URL options are available.Applications that set
ActionText::ContentHelper.allowed_tagsorallowed_attributeskeep their own lists.Relationship to the editor adapter PR
This builds on Sean Doyle's Extract
ActionText::Editorbase class andActionText::TrixEditoradapter, merged intomain. It uses that PR's editor registry, adapter base class andconfig.action_text.editorwithout reimplementing any of it.Prerequisites and open questions
actiontext.gemspecshould require that release, and the Gemfile's git source goes away. Until then, applications that use this branch have to pinrails-action-text-defaulttoo.rails-new-dockerand "Devcontainer smoke test" checks fail.rails new --devresolveslexxy ~> 0.9.31from RubyGems. That release still depends onrails, so Bundler refuses the cycle.:trixon Rails without Lexxy. Lexxy can't tell an explicitconfig.action_text.editor = :trixfrom Action Text's default on Rails versions that don't include Lexxy, because Rails doesn't record who set it. There,config.lexxy.override_action_text_defaults = falseis the explicit way to keep Trix while the gem is installed.var()is process-wide. It's added to Loofah's CSS function allowlist, which is shared by the whole process, so it also applies to Action View'ssanitize.trix-content. The installer writes the application's copy with the configured editor's class.Additional information
Tests run locally against
rails-action-text-default:rake test)rake test:system,RACK_ENV=testset)railties/test/generators/action_text_install_generator_test.rbrailties/test/application/configuration_test.rb, Action Text andenqueue_after_transaction_committestsrailties/test/railties/engine_test.rb, railtie orderJavascriptPackageTest, which needsrollupfromnode_modules, and it fails the same way onmain.RACK_ENVset, the system run's leak checker reportsRACK_ENVbeing added when the test server boots. That happens on untouchedmaintoo.json3.x gem.Checklist
[Fix #issue-number]