2019-08-13 19:09:23 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# Se encarga del contenido del artículo y quizás otros campos que
|
|
|
|
# requieran texto largo.
|
|
|
|
class MetadataContent < MetadataTemplate
|
|
|
|
def default_value
|
2020-11-11 18:29:12 +00:00
|
|
|
super || ''
|
2019-08-13 19:09:23 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def value
|
2021-02-24 19:57:20 +00:00
|
|
|
self[:value] || legacy_content || default_value
|
2019-08-13 19:09:23 +00:00
|
|
|
end
|
|
|
|
|
2019-08-13 23:33:57 +00:00
|
|
|
def front_matter?
|
|
|
|
false
|
|
|
|
end
|
2020-11-17 23:29:22 +00:00
|
|
|
|
2021-04-22 16:09:49 +00:00
|
|
|
def document_value
|
|
|
|
document.content
|
|
|
|
end
|
|
|
|
|
2021-05-06 15:33:28 +00:00
|
|
|
def indexable?
|
2021-05-09 15:25:16 +00:00
|
|
|
true && !private?
|
2021-05-06 15:33:28 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s
|
|
|
|
sanitizer.sanitize value, tags: [], attributes: []
|
|
|
|
end
|
|
|
|
|
2020-11-17 23:29:22 +00:00
|
|
|
private
|
|
|
|
|
2021-02-24 19:57:20 +00:00
|
|
|
# Detectar si el contenido estaba en Markdown y pasarlo a HTML
|
|
|
|
def legacy_content
|
2021-04-22 16:09:49 +00:00
|
|
|
return unless document_value
|
|
|
|
return document_value if /^\s*</ =~ document_value
|
2021-02-24 19:57:20 +00:00
|
|
|
|
2021-04-22 16:09:49 +00:00
|
|
|
CommonMarker.render_doc(document_value, %i[FOOTNOTES UNSAFE], %i[table strikethrough autolink]).to_html
|
2021-02-24 19:57:20 +00:00
|
|
|
end
|
|
|
|
|
2020-11-17 23:29:22 +00:00
|
|
|
# Limpiar el HTML que recibimos
|
|
|
|
#
|
|
|
|
# TODO: En lugar de comprobar el Content Type acá, restringir los
|
|
|
|
# tipos de archivo a aceptar en ActiveStorage.
|
|
|
|
def sanitize(html_string)
|
|
|
|
html = Nokogiri::HTML.fragment(super html_string)
|
|
|
|
elements = 'img,audio,video,iframe'
|
|
|
|
|
|
|
|
# Eliminar elementos sin src y comprobar su origen
|
|
|
|
html.css(elements).each do |element|
|
|
|
|
unless element['src']
|
|
|
|
element.remove
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
|
|
|
uri = URI element['src']
|
|
|
|
|
|
|
|
# No permitimos recursos externos
|
2021-08-11 13:25:05 +00:00
|
|
|
element.remove unless uri.scheme == 'https' && uri.hostname.end_with?(Site.domain)
|
2020-11-17 23:29:22 +00:00
|
|
|
rescue URI::Error
|
|
|
|
element.remove
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Eliminar figure sin contenido
|
|
|
|
html.css('figure').each do |figure|
|
|
|
|
figure.remove if figure.css(elements).empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
# Los videos y audios necesitan controles
|
|
|
|
html.css('audio,video').each do |resource|
|
|
|
|
resource['controls'] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
html.to_s.html_safe
|
|
|
|
end
|
2019-08-13 19:09:23 +00:00
|
|
|
end
|