69 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			1.7 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
 | |
| 
 | |
|     MASTODON_STRICT ||= freeze_config(
 | |
|       elements: %w(p br span a),
 | |
| 
 | |
|       attributes: {
 | |
|         'a'    => %w(href rel class),
 | |
|         'span' => %w(class),
 | |
|       },
 | |
| 
 | |
|       add_attributes: {
 | |
|         'a' => {
 | |
|           'rel' => 'nofollow noopener',
 | |
|           'target' => '_blank',
 | |
|         },
 | |
|       },
 | |
| 
 | |
|       protocols: {
 | |
|         'a' => { 'href' => HTTP_PROTOCOLS },
 | |
|       },
 | |
| 
 | |
|       transformers: [
 | |
|         CLASS_WHITELIST_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
 |