There is a new [Trix.js][] release, bumping the version from `1.3.1` to
`2.0.4`.
Applications that consume Action Text through the `@rails/actiontext`
npm package can manage their own Trix dependency version.
Similarly, Importmaps users can `pin "trix", to: "..."` to a CDN serving
`2.0.4`.
For the sake of applications that depend on Trix through the
`action_text` gem, this commit updates the pre-bundled JS and CSS code.
These changes were generated by executing the following:
```sh
cd actiontext
yarn build
cp ../node_modules/trix/dist/trix.css app/assets/stylesheets/trix.css
cp ../node_modules/trix/dist/trix.esm.js app/assets/javascripts/trix.js
```
[Trix.js]: https://trix-editor.org
[v2.0.4]: https://github.com/basecamp/trix/releases/tag/v2.0.4
When a host is not specified for an `ActionController::Renderer`'s env,
the host and related options will now be derived from the routes'
`default_url_options` and `ActionDispatch::Http::URL.secure_protocol`.
For example, with:
```ruby
Rails.application.default_url_options = { host: "rubyonrails.org" }
Rails.application.config.force_ssl = true
```
Before:
```ruby
ApplicationController.renderer.render inline: "<%= blog_url %>"
# => "http://example.org/blog"
```
After:
```ruby
ApplicationController.renderer.render inline: "<%= blog_url %>"
# => "https://rubyonrails.org/blog"
```
As a consequence, Action Text attachment URLs rendered in a background
job (a la Turbo Streams) will now use `Rails.application.default_url_options`.
Fixes#41795.
Fixeshotwired/turbo-rails#54.
Fixeshotwired/turbo-rails#155.
When System Tests call `fill_in_rich_text_area`, they interact with
`<trix-editor>` elements by changing the contents programmatically.
This is unlike how end-users will interact with the element. Overhauling
the test helper to more accurately reflect Real World usage would
require a sizable effort.
With that being said, leaving the `<trix-editor>` with focus after
populating its contents is a minor change that makes it a more genuine
recreation.
Expand the `has_rich_text` signature to accept a `strict_loading:`
value. Forward that value along to the `has_one` declaration made under
the hood. When omitted, `strict_loading:` will be set to the value of
the `strict_loading_by_default` class attribute (false by default).
* Action Text JS should be available via the asset pipeline too
* Main was a module anyway, no need to reference that twice
* Fix rollup references
* Precompile action text JS for asset pipeline
* No JavaScript dependencies needed with the asset pipeline
* Stub Webpacker::Engine to trigger webpack path for testing
* Extract asset paths
* Exercise asset pipeline path
* Terser doesn't do anything useful on this small package
* Make trix directly available to the asset pipeline
* Indirect doesn't carry its worth
* Reminder for development about keeping things in sync for the asset pipeline
* Ensure this isn't turned into undefined while mirroring
* Mirror Trix CSS for asset pipeline
* Add the needed JS include tag automatically under the asset pipeline
* Please RuboCop
* Keep the peer dependency
Even though we also need it explicitly as a dev dependency in order to generate the mirror output for trix.
* Fix test
* Add CHANGELOG entry
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 change introduces a rich text object to make
it easier to confirm it context is existing or not.
If we have a class like below.
class Information < ApplicationRecord
has_rich_text :notes
end
Before:
i = Information.new
i.notes? => NoMethodError
i.notes = "Some sample text"
i.notes.present? => true
After:
i = Information.new
i.notes? => false
i.notes = "Some sample text"
i.notes? => true