diff --git a/app/helpers/rich_text_helper.rb b/app/helpers/rich_text_helper.rb
index 67c6d99..306c3db 100644
--- a/app/helpers/rich_text_helper.rb
+++ b/app/helpers/rich_text_helper.rb
@@ -1,6 +1,4 @@
module RichTextHelper
- LEGACY_EMBED_SELECTOR = "action-text-attachment[content-type='#{ActionText::Attachment::OpengraphEmbed::OPENGRAPH_EMBED_CONTENT_TYPE}'][href]"
-
def rich_text_data_actions
# submitByKeyboard runs in the capture phase so it can submit on Enter
# before the editor turns the keystroke into a newline
@@ -12,14 +10,22 @@ module RichTextHelper
"remote-filtering": true, "empty-results": "No matches"
end
- # Trix-era opengraph embeds carry their details as node attributes, which
- # the editor doesn't round-trip. Rendering them into the content attribute
- # lets the editor preserve them like any embed it created itself.
+ # The editor keeps an attachment's content as it finds it, so every
+ # attachment is rebuilt from its attachable before editing: a Trix-era
+ # embed carries its details as node attributes the editor doesn't
+ # round-trip, a mention edited under Trix carries the generic content type
+ # the editor doesn't permit, and a hand-written embed carries whatever
+ # markup the author put there.
def editable_body(message)
fragment = ActionText::Fragment.wrap(message.body.body_before_type_cast)
- transformed = fragment.replace(LEGACY_EMBED_SELECTOR) do |node|
- node.tap { |n| n["content"] = render_action_text_attachment(ActionText::Attachment.from_node(n)) }
+ transformed = fragment.replace(ActionText::Attachment.tag_name) do |node|
+ attachment = ActionText::Attachment.from_node(node)
+
+ node.tap do |n|
+ n["content-type"] = attachment.attachable.attachable_content_type
+ n["content"] = render_action_text_attachment(attachment)
+ end
end
ActionText::RichText.new(body: transformed.to_html)
diff --git a/app/models/user/mentionable.rb b/app/models/user/mentionable.rb
index bb763f2..b028284 100644
--- a/app/models/user/mentionable.rb
+++ b/app/models/user/mentionable.rb
@@ -1,6 +1,12 @@
module User::Mentionable
include ActionText::Attachable
+ MENTION_CONTENT_TYPE = "application/vnd.campfire.mention"
+
+ def attachable_content_type
+ MENTION_CONTENT_TYPE
+ end
+
def to_attachable_partial_path
"users/mention"
end
diff --git a/test/helpers/rich_text_helper_test.rb b/test/helpers/rich_text_helper_test.rb
index bc72d33..21bce8b 100644
--- a/test/helpers/rich_text_helper_test.rb
+++ b/test/helpers/rich_text_helper_test.rb
@@ -15,7 +15,37 @@ class RichTextHelperTest < ActionView::TestCase
assert_equal "https://example.com/image.png", content.at_css(".og-embed__image img")["src"]
end
- test "editable_body leaves bodies without legacy embeds unchanged" do
+ test "editable_body rebuilds a hand-written embed from its validated details" do
+ content = <<~HTML.squish
+
Plain text
", client_message_id: "0018", creator: users(:jason) assert_equal message.body.body.to_html, editable_body(message).body.to_html diff --git a/test/system/composer_test.rb b/test/system/composer_test.rb index 315d899..764cbea 100644 --- a/test/system/composer_test.rb +++ b/test/system/composer_test.rb @@ -86,6 +86,34 @@ class ComposerTest < ApplicationSystemTestCase assert_equal [ users(:jason) ], message.reload.mentionees end + test "editing a message whose mention was saved under Trix keeps the mention" do + body = %(| Name | Points |
|---|---|
| Jason | 10 |