forked from openHPI/xikolo-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtml_truncator.rb
60 lines (47 loc) · 1.46 KB
/
html_truncator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# frozen_string_literal: true
class HtmlTruncator
require 'truncato'
require 'nokogiri/html5'
ALLOWED_TAGS = %w[br em hr p strong].freeze
ALLOWED_ATTRIBUTES = %w[class id].freeze
DEFAULT_TRUNCATO_OPTIONS = {
max_length: 200,
count_tags: false,
count_tail: true,
}.freeze
def initialize(**options)
@options = options
end
def truncate(html, **options)
# Truncato takes care of HTML-aware truncation.
# For example, it also adds closing tags when they are missing.
return if html.blank?
sanitize_opts = options.extract!(:tags)
Truncato.truncate \
sanitize(html, **sanitize_opts),
DEFAULT_TRUNCATO_OPTIONS.merge(options.except(:strip_lists))
end
private
def sanitizer
# Use Rails' default sanitizer, also used in
# the ActionView::Helpers::SanitizeHelper. It only permits a list
# of defined tags and attributes (see #sanitized_html).
@sanitizer ||= Rails::HTML5::SafeListSanitizer.new
end
def sanitize(html, **opts)
# Properly sanitize the HTML, only allow specified tags/attributes.
html = strip_lists! html if @options[:strip_lists]
sanitizer.sanitize \
html,
tags: opts.fetch(:tags, ALLOWED_TAGS),
attributes: ALLOWED_ATTRIBUTES
end
def strip_lists!(html)
content = Nokogiri::HTML5.fragment html
content.search('ul > li', 'ol > li').each do |li|
next unless li.element?
li.replace("#{li.content}<br/>")
end
content.to_html
end
end