Trix's `<trix-editor>` doesn't support the [form][] property like
`<textarea>` or other form fields.
For example, consider the following HTML and event listener:
```html
<form action="/articles" method="post">
<textarea name="content"></textarea>
<button type="submit">Save</button>
</form>
<script>
addEventListener("keydown", ({ key, metaKey, target }) => {
if (target.form && key == "Enter" && (metaKey || ctrlKey)) {
form.requestSubmit()
}
})
</script>
```
The `target` (an instance of `HTMLTextAreaElement` relies on the
[HTMLTextAreaElement.form][] property for access to its associated
`<form>`. While it's usually equivalent to `target.closest("form")`,
that isn't always the case. Declaring a `[form]` attribute with another
`<form>` element's `[id]` value can associate a field to a `<form>` that
is _not an ancestor_. That means that the event listener from above
would continue to work with this HTML:
```html
<textarea name="content" form="new_article"></textarea>
<!-- elsewhere -->
<form id="new_article" action="/articles" method="post">
<button type="submit">Save</button>
</form>
```
Unfortunately, if the `<textarea>` element were replaced with a
`<trix-editor>`, the event listener's reliance on accessing the form as
a property would break, since the `<trix-editor>` custom element doesn't
declare that property. There is currently a pull request
([basecamp/trix#899][]) to add support for accessing the `form` as a
property of the `<trix-editor>` element.
The [feedback][] provided on that pull request suggests that we
implement the `form` property by delegating to the `<input
type="hidden">` element. Currently, `<input type="hidden">` elements
constructed by Action Text helpers cannot declare the `[form]`
attribute.
This commit adds support by special-casing the `options[:form]` key
within `ActionText::TagHelper#rich_text_area_tag`.
[form]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement#properties
[basecamp/trix#899]: https://github.com/basecamp/trix/pull/899#discussion_r618543357
[feedback]: https://github.com/basecamp/trix/pull/899#discussion_r618543357
Extensible layout
---
Expose how we render the HTML _surrounding_ rich text content as an
extensible `layouts/action_text/contents/_content.html.erb` template to
encourage user-land customizations, while retaining private API control
over how the rich text itself is rendered by moving the
`#render_action_text_content` helper invocation to the
`action_text/contents/_content.html.erb` partial.
Extensible Attachable `#to_attachable_partial_path`
---
When an application declares a canonical partial for a record, there is
no way to override which partial is used when transformed to Rich Text.
For example, a default `Person < ApplicationRecord` instance returns
`"people/person"` from calls to `#to_partial_path`, resulting in the
`app/views/people/_person.html.erb` partial being rendered.
Prior to this change, when encountering an `<action-text-attachment
sgid="...">` element, ActionText retrieved the corresponding
`Attachable` instance (usually an `ActiveRecord::Base` instance) and
transformed it to rich text HTML by rendering the partial that
corresponds to its `#to_partial_path`.
This proposed change instead invokes
`Attachable#to_attachable_partial_path`. By default,
`#to_attachable_partial_path` is an alias for `#to_partial_path`.
Guides
---
Extend the `guides/action_text_overview` document to
describe how to customize these templates, and to better illustrate how
ActionText::Attachable instances are rendered into HTML.
This commit allows Action Text to be used without having an
ApplicationController defined. In doing so, it also fixes Action Text
attachments to render the correct URL host in mailers.
It also avoids allocating an ActionController::Renderer per request.
Fixes#37183.
Fixes#35578.
Fixes#36963.
Closes#38714.
Co-authored-by: Jeremy Daer <jeremydaer@gmail.com>
Permit applications to hack in custom DB config for ActionText::RichText until AT has first-class multi-DB support:
ActiveSupport.on_load(:action_text_record) do
connects_to reading: :action_text_replica, writing: :action_text_primary
end
In most cases it works now without explicit require because it's accidentally required through
active_support/core_ext/date_and_time/calculations.rb where we still call `try`,
but that would stop working if we changed the Calculations implementation and remove the require call there.
If the [`action_text.helper` initializer][0] runs after
`ActionController::Base` has been loaded, but before the
`rails-html-sanitizer` gem has been `require`d, then the reference to
the constant `Rails::Html` in the body of the
`ActionText::ContentHelper` module raises an `uninitialized constant`
exception.
[0]: 2170338239/actiontext/lib/action_text/engine.rb (L31-L35)
Failing test before the ActionText::RichText change:
```
Error:
ActionText::ModelTest#test_embed_extraction_only_extracts_file_attachments:
ArgumentError: Could not find or build blob: expected attachable, got #<ActionText::Attachables::RemoteImage:0x00007fb0259fef70 @url="http://example.com/cat.jpg", @content_type="image", @width=nil, @height=nil>
```