html.html_safe # rubocop:disable Rails/OutputSafety
end
+ def format_markdown(html)
+ html = markdown_formatter.render(html)
+ html.delete("\r").delete("\n")
+ end
+
def reformat(html)
sanitize(html, Sanitize::Config::MASTODON_STRICT)
+ rescue ArgumentError
+ ''
end
def plaintext(status)
node['class'] = class_list.join(' ')
end
- UNSUPPORTED_ELEMENTS_TRANSFORMER = lambda do |env|
- return unless %w(h1 h2 h3 h4 h5 h6 blockquote pre ul ol li).include?(env[:node_name])
-
- current_node = env[:node]
-
- case env[:node_name]
- when 'li'
- current_node.traverse do |node|
- next unless %w(p ul ol li).include?(node.name)
-
- node.add_next_sibling('<br>') if node.next_sibling
- node.replace(node.children) unless node.text?
- end
- else
- current_node.name = 'p'
- end
- end
-
+ IMG_TAG_TRANSFORMER = lambda do |env|
+ node = env[:node]
+
+ return unless env[:node_name] == 'img'
+
+ node.name = 'a'
+
+ node['href'] = node['src']
+ if node['alt'].present?
+ node.content = "[🖼 #{node['alt']}]"
+ else
+ url = node['href']
+ prefix = url.match(/\Ahttps?:\/\/(www\.)?/).to_s
+ text = url[prefix.length, 30]
+ text = text + "…" if url[prefix.length..-1].length > 30
+ node.content = "[🖼 #{text}]"
+ end
+ end
+
+ UNSUPPORTED_HREF_TRANSFORMER = lambda do |env|
+ return unless env[:node_name] == 'a'
+
+ current_node = env[:node]
+
+ scheme = begin
+ if current_node['href'] =~ Sanitize::REGEX_PROTOCOL
+ Regexp.last_match(1).downcase
+ else
+ :relative
+ end
+ end
+
+ current_node.replace(current_node.text) unless LINK_PROTOCOLS.include?(scheme)
+ end
+
MASTODON_STRICT ||= freeze_config(
- elements: %w(p br span a),
+ elements: %w(p br span a abbr del pre blockquote code b strong u sub sup i em h1 h2 h3 h4 h5 ul ol li),
attributes: {
- 'a' => %w(href rel class),
- 'span' => %w(class),
+ 'a' => %w(href rel class title),
+ 'span' => %w(class),
+ 'abbr' => %w(title),
+ 'blockquote' => %w(cite),
},
add_attributes: {
},
},
- protocols: {},
+ protocols: {
- 'a' => { 'href' => HTTP_PROTOCOLS },
- 'blockquote' => { 'cite' => HTTP_PROTOCOLS },
++ 'a' => { 'href' => LINK_PROTOCOLS },
++ 'blockquote' => { 'cite' => LINK_PROTOCOLS },
+ },
transformers: [
CLASS_WHITELIST_TRANSFORMER,
- UNSUPPORTED_ELEMENTS_TRANSFORMER,
+ IMG_TAG_TRANSFORMER,
+ UNSUPPORTED_HREF_TRANSFORMER,
]
)
setting_noindex: Nie indeksuj mojego profilu w wyszukiwarkach internetowych
setting_reduce_motion: Ogranicz ruch w animacjach
setting_show_application: Informuj o aplikacji z której wysłano wpisy
+ setting_skin: Motyw
setting_system_font_ui: Używaj domyślnej czcionki systemu
+ setting_theme: Motyw strony
+ setting_trends: Pokazuj dzisiejsze „Na czasie”
setting_unfollow_modal: Pytaj o potwierdzenie przed cofnięciem śledzenia
setting_use_blurhash: Pokazuj kolorowe gradienty dla ukrytej zawartości multimedialnej
+ setting_use_pending_items: Tryb spowolniony
severity: Priorytet
type: Importowane dane
username: Nazwa użytkownika
describe '::MASTODON_STRICT' do
subject { Sanitize::Config::MASTODON_STRICT }
- it 'converts h1 to p' do
- expect(Sanitize.fragment('<h1>Foo</h1>', subject)).to eq '<p>Foo</p>'
+ it 'keeps h1' do
+ expect(Sanitize.fragment('<h1>Foo</h1>', subject)).to eq '<h1>Foo</h1>'
end
- it 'converts ul to p' do
- expect(Sanitize.fragment('<p>Check out:</p><ul><li>Foo</li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p>Foo<br>Bar</p>'
- end
-
- it 'converts p inside ul' do
- expect(Sanitize.fragment('<ul><li><p>Foo</p><p>Bar</p></li><li>Baz</li></ul>', subject)).to eq '<p>Foo<br>Bar<br>Baz</p>'
- end
-
- it 'converts ul inside ul' do
- expect(Sanitize.fragment('<ul><li>Foo</li><li><ul><li>Bar</li><li>Baz</li></ul></li></ul>', subject)).to eq '<p>Foo<br>Bar<br>Baz</p>'
- end
-
- it 'keep links in lists' do
- expect(Sanitize.fragment('<p>Check out:</p><ul><li><a href="https://joinmastodon.org" rel="nofollow noopener noreferrer" target="_blank">joinmastodon.org</a></li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p><a href="https://joinmastodon.org" rel="nofollow noopener noreferrer" target="_blank">joinmastodon.org</a><br>Bar</p>'
+ it 'keeps ul' do
+ expect(Sanitize.fragment('<p>Check out:</p><ul><li>Foo</li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><ul><li>Foo</li><li>Bar</li></ul>'
end
+
+ it 'removes a without href' do
+ expect(Sanitize.fragment('<a>Test</a>', subject)).to eq 'Test'
+ end
+
+ it 'removes a without href and only keeps text content' do
+ expect(Sanitize.fragment('<a><span class="invisible">foo&</span><span>Test</span></a>', subject)).to eq 'foo&Test'
+ end
+
+ it 'removes a with unsupported scheme in href' do
+ expect(Sanitize.fragment('<a href="foo://bar">Test</a>', subject)).to eq 'Test'
+ end
+
+ it 'keeps a with href' do
+ expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
+ end
end
end