hometown/app/lib/sanitize_config.rb
Thibaut Girka 10924fc580 Accept richer text from remote statuses
Support abbr, del, pre, blockquote, code, strong, b, em, i, ul, ol, li and
h1 to h5 tags in remote statuses.
2019-06-30 15:14:10 -07:00

87 lines
2.4 KiB
Ruby

# frozen_string_literal: true
class Sanitize
module Config
HTTP_PROTOCOLS ||= ['http', 'https', 'dat', 'dweb', 'ipfs', 'ipns', 'ssb', 'gopher', :relative].freeze
CLASS_WHITELIST_TRANSFORMER = lambda do |env|
node = env[:node]
class_list = node['class']&.split(/[\t\n\f\r ]/)
return unless class_list
class_list.keep_if do |e|
next true if e =~ /^(h|p|u|dt|e)-/ # microformats classes
next true if e =~ /^(mention|hashtag)$/ # semantic classes
next true if e =~ /^(ellipsis|invisible)$/ # link formatting classes
end
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])
case env[:node_name]
when 'li'
env[:node].traverse do |node|
node.add_next_sibling('<br>') if node.next_sibling
node.replace(node.children) unless node.text?
end
else
env[:node].name = 'p'
end
end
MASTODON_STRICT ||= freeze_config(
elements: %w(p br span a abbr del pre blockquote code b strong i em h1 h2 h3 h4 h5 ul ol li),
attributes: {
'a' => %w(href rel class title),
'span' => %w(class),
'abbr' => %w(title),
'blockquote' => %w(cite),
},
add_attributes: {
'a' => {
'rel' => 'nofollow noopener',
'target' => '_blank',
},
},
protocols: {
'a' => { 'href' => HTTP_PROTOCOLS },
'blockquote' => { 'cite' => HTTP_PROTOCOLS },
},
transformers: [
CLASS_WHITELIST_TRANSFORMER,
UNSUPPORTED_ELEMENTS_TRANSFORMER,
]
)
MASTODON_OEMBED ||= freeze_config merge(
RELAXED,
elements: RELAXED[:elements] + %w(audio embed iframe source video),
attributes: merge(
RELAXED[:attributes],
'audio' => %w(controls),
'embed' => %w(height src type width),
'iframe' => %w(allowfullscreen frameborder height scrolling src width),
'source' => %w(src type),
'video' => %w(controls height loop width),
'div' => [:data]
),
protocols: merge(
RELAXED[:protocols],
'embed' => { 'src' => HTTP_PROTOCOLS },
'iframe' => { 'src' => HTTP_PROTOCOLS },
'source' => { 'src' => HTTP_PROTOCOLS }
)
)
end
end