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:
Shivam Mishra
2023-11-03 02:21:54 +05:30
committed by GitHub
parent 16c36a78f0
commit 36b6c0cb9c
4 changed files with 78 additions and 1 deletions

View 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

View File

@@ -4,7 +4,9 @@ class ChatwootMarkdownRenderer
end
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)
end

View 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 = '![Sample Title](https://example.com/image.jpg?cw_image_height=100)'
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 = '![Sample Title](https://example.com/image.jpg)'
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 = '![Sample Title](invalid_url)'
expect { render_markdown(markdown) }.not_to raise_error
end
end
end
end

View File

@@ -5,6 +5,7 @@ RSpec.describe ChatwootMarkdownRenderer do
let(:doc) { instance_double(CommonMarker::Node) }
let(:renderer) { described_class.new(markdown_content) }
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>' }
before do
@@ -31,6 +32,8 @@ RSpec.describe ChatwootMarkdownRenderer do
before do
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
it 'renders the markdown message to html' do