FIX: Allow for nested chat transcripts (#19572)
The way our markdown raw_html hoisting worked, we only supported one level of hoisting the HTML content. However when nesting [chat] transcript BBCode we need to allow for multiple levels of it. This commit changes opts.discourse.hoisted to be more constant, and the GUID keys that have the hoisted content are only deleted by unhoistForCooked rather than the cook function itself, which prematurely deletes them when they are needed further down the line.
This commit is contained in:
parent
788bcb7736
commit
641a1a6b44
|
@ -423,6 +423,7 @@ function unhoistForCooked(hoisted, cooked) {
|
|||
found = true;
|
||||
return hoisted[key];
|
||||
});
|
||||
delete hoisted[key];
|
||||
};
|
||||
|
||||
while (found) {
|
||||
|
@ -578,14 +579,16 @@ export function setup(opts, siteSettings, state) {
|
|||
|
||||
export function cook(raw, opts) {
|
||||
// we still have to hoist html_raw nodes so they bypass the allowlister
|
||||
// this is the case for oneboxes
|
||||
let hoisted = {};
|
||||
opts.discourse.hoisted = hoisted;
|
||||
// this is the case for oneboxes and also certain plugins that require
|
||||
// raw HTML rendering within markdown bbcode rules
|
||||
opts.discourse.hoisted ??= {};
|
||||
|
||||
const rendered = opts.engine.render(raw);
|
||||
let cooked = opts.discourse.sanitizer(rendered).trim();
|
||||
cooked = unhoistForCooked(hoisted, cooked);
|
||||
delete opts.discourse.hoisted;
|
||||
|
||||
// opts.discourse.hoisted guid keys will be deleted within here to
|
||||
// keep the object empty
|
||||
cooked = unhoistForCooked(opts.discourse.hoisted, cooked);
|
||||
|
||||
return cooked;
|
||||
}
|
||||
|
|
|
@ -211,4 +211,52 @@ martin</div>
|
|||
ensure
|
||||
InlineOneboxer.invalidate("https://en.wikipedia.org/wiki/Hyperlink")
|
||||
end
|
||||
|
||||
it "handles nested chat transcripts in posts" do
|
||||
SiteSetting.external_system_avatars_enabled = false
|
||||
freeze_time
|
||||
|
||||
channel = Fabricate(:chat_channel)
|
||||
message1 = Fabricate(:chat_message, chat_channel: channel, user: post.user)
|
||||
message2 = Fabricate(:chat_message, chat_channel: channel, user: post.user)
|
||||
md = ChatTranscriptService.new(channel, message2.user, messages_or_ids: [message2.id]).generate_markdown
|
||||
message1.update!(message: md)
|
||||
md_for_post = ChatTranscriptService.new(channel, message1.user, messages_or_ids: [message1.id]).generate_markdown
|
||||
post.update!(raw: md_for_post)
|
||||
expect(post.cooked.chomp).to eq(<<~COOKED.chomp)
|
||||
<div class="chat-transcript" data-message-id="#{message1.id}" data-username="#{message1.user.username}" data-datetime="#{message1.created_at.iso8601}" data-channel-name="#{channel.name}" data-channel-id="#{channel.id}">
|
||||
<div class="chat-transcript-user">
|
||||
<div class="chat-transcript-user-avatar">
|
||||
<img loading="lazy" alt="" width="20" height="20" src="//test.localhost#{post.user.avatar_template.gsub("{size}", "40")}" class="avatar">
|
||||
</div>
|
||||
<div class="chat-transcript-username">
|
||||
#{message1.user.username}</div>
|
||||
<div class="chat-transcript-datetime">
|
||||
<a href="/chat/channel/#{channel.id}/-?messageId=#{message1.id}" title="#{message1.created_at.iso8601}"></a>
|
||||
</div>
|
||||
<a class="chat-transcript-channel" href="/chat/channel/#{channel.id}/-">
|
||||
##{channel.name}</a>
|
||||
</div>
|
||||
<div class="chat-transcript-messages">
|
||||
<div class="chat-transcript" data-message-id="#{message2.id}" data-username="#{message2.user.username}" data-datetime="#{message2.created_at.iso8601}" data-channel-name="#{channel.name}" data-channel-id="#{channel.id}">
|
||||
<div class="chat-transcript-user">
|
||||
<div class="chat-transcript-user-avatar">
|
||||
<img loading="lazy" alt="" width="20" height="20" src="//test.localhost#{post.user.avatar_template.gsub("{size}", "40")}" class="avatar">
|
||||
</div>
|
||||
<div class="chat-transcript-username">
|
||||
#{message2.user.username}</div>
|
||||
<div class="chat-transcript-datetime">
|
||||
<a href="/chat/channel/#{channel.id}/-?messageId=#{message2.id}" title="#{message1.created_at.iso8601}"></a>
|
||||
</div>
|
||||
<a class="chat-transcript-channel" href="/chat/channel/#{channel.id}/-">
|
||||
##{channel.name}</a>
|
||||
</div>
|
||||
<div class="chat-transcript-messages">
|
||||
<p>#{message2.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
COOKED
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue