mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-01 19:48:08 +00:00
feat: support image height in markdown rendering of messages (#8177)
- This PR adds BaseMarkdownRenderer, it takes all the required attributes from the image node, parses the cw_image_height query and renders it.
This commit is contained in:
39
lib/base_markdown_renderer.rb
Normal file
39
lib/base_markdown_renderer.rb
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
class BaseMarkdownRenderer < CommonMarker::HtmlRenderer
|
||||||
|
def image(node)
|
||||||
|
src, title = extract_img_attributes(node)
|
||||||
|
height = extract_image_height(src)
|
||||||
|
|
||||||
|
render_img_tag(src, title, height)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_img_attributes(node)
|
||||||
|
[
|
||||||
|
escape_href(node.url),
|
||||||
|
escape_html(node.title)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract_image_height(src)
|
||||||
|
query_params = parse_query_params(src)
|
||||||
|
query_params['cw_image_height']&.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_query_params(url)
|
||||||
|
parsed_url = URI.parse(url)
|
||||||
|
CGI.parse(parsed_url.query || '')
|
||||||
|
rescue URI::InvalidURIError
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_img_tag(src, title, height = nil)
|
||||||
|
title_attribute = title.present? ? " title=\"#{title}\"" : ''
|
||||||
|
height_attribute = height ? " height=\"#{height}\" width=\"auto\"" : ''
|
||||||
|
|
||||||
|
plain do
|
||||||
|
# plain ensures that the content is not wrapped in a paragraph tag
|
||||||
|
out("<img src=\"#{src}\"#{title_attribute}#{height_attribute} />")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,7 +4,9 @@ class ChatwootMarkdownRenderer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_message
|
def render_message
|
||||||
html = CommonMarker.render_html(@content)
|
markdown_renderer = BaseMarkdownRenderer.new
|
||||||
|
doc = CommonMarker.render_doc(@content, :DEFAULT)
|
||||||
|
html = markdown_renderer.render(doc)
|
||||||
render_as_html_safe(html)
|
render_as_html_safe(html)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
33
spec/lib/base_markdown_renderer_spec.rb
Normal file
33
spec/lib/base_markdown_renderer_spec.rb
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe BaseMarkdownRenderer do
|
||||||
|
let(:renderer) { described_class.new }
|
||||||
|
|
||||||
|
def render_markdown(markdown)
|
||||||
|
doc = CommonMarker.render_doc(markdown, :DEFAULT)
|
||||||
|
renderer.render(doc)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#image' do
|
||||||
|
context 'when image has a height' do
|
||||||
|
it 'renders the img tag with the correct attributes' do
|
||||||
|
markdown = ''
|
||||||
|
expect(render_markdown(markdown)).to include('<img src="https://example.com/image.jpg?cw_image_height=100" height="100" width="auto" />')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when image does not have a height' do
|
||||||
|
it 'renders the img tag without the height attribute' do
|
||||||
|
markdown = ''
|
||||||
|
expect(render_markdown(markdown)).to include('<img src="https://example.com/image.jpg" />')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when image has an invalid URL' do
|
||||||
|
it 'renders the img tag without crashing' do
|
||||||
|
markdown = ''
|
||||||
|
expect { render_markdown(markdown) }.not_to raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -5,6 +5,7 @@ RSpec.describe ChatwootMarkdownRenderer do
|
|||||||
let(:doc) { instance_double(CommonMarker::Node) }
|
let(:doc) { instance_double(CommonMarker::Node) }
|
||||||
let(:renderer) { described_class.new(markdown_content) }
|
let(:renderer) { described_class.new(markdown_content) }
|
||||||
let(:markdown_renderer) { instance_double(CustomMarkdownRenderer) }
|
let(:markdown_renderer) { instance_double(CustomMarkdownRenderer) }
|
||||||
|
let(:base_markdown_renderer) { instance_double(BaseMarkdownRenderer) }
|
||||||
let(:html_content) { '<p>This is a <em>test</em> content with <sup>markdown</sup></p>' }
|
let(:html_content) { '<p>This is a <em>test</em> content with <sup>markdown</sup></p>' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@@ -31,6 +32,8 @@ RSpec.describe ChatwootMarkdownRenderer do
|
|||||||
|
|
||||||
before do
|
before do
|
||||||
allow(CommonMarker).to receive(:render_html).with(markdown_content).and_return(message_html_content)
|
allow(CommonMarker).to receive(:render_html).with(markdown_content).and_return(message_html_content)
|
||||||
|
allow(BaseMarkdownRenderer).to receive(:new).and_return(base_markdown_renderer)
|
||||||
|
allow(base_markdown_renderer).to receive(:render).with(doc).and_return(message_html_content)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the markdown message to html' do
|
it 'renders the markdown message to html' do
|
||||||
|
|||||||
Reference in New Issue
Block a user