diff --git a/src/invidious/comments/links_util.cr b/src/invidious/comments/links_util.cr index f89b86d3..a28db740 100644 --- a/src/invidious/comments/links_util.cr +++ b/src/invidious/comments/links_util.cr @@ -73,4 +73,30 @@ module Invidious::Comments return html.to_xml(options: XML::SaveOptions::NO_DECL) end + + def replace_external_links(html) + # Check if the document is empty + # Prevents edge-case bug with Reddit comments, see issue #3115 + if html.nil? || html.empty? + return html + end + + html = XML.parse_html(html) + + html.xpath_nodes(%q(//a)).each do |anchor| + url = URI.parse(anchor["href"]) + + if !url.host.nil? && !url.host.not_nil!.ends_with?("youtube.com") && !url.host.not_nil!.ends_with?("youtu.be") + confirm_leave = "/confirm_leave?link=#{URI.encode_path(url.to_s)}" + anchor["href"] = confirm_leave + end + end + + html = html.xpath_node(%q(//body)).not_nil! + if node = html.xpath_node(%q(./p)) + html = node + end + + return html.to_xml(options: XML::SaveOptions::NO_DECL) + end end diff --git a/src/invidious/comments/youtube.cr b/src/invidious/comments/youtube.cr index 0716fcde..148f6cbe 100644 --- a/src/invidious/comments/youtube.cr +++ b/src/invidious/comments/youtube.cr @@ -303,6 +303,7 @@ module Invidious::Comments if format == "html" response = JSON.parse(response) content_html = Frontend::Comments.template_youtube(response, locale, thin_mode) + content_html = Comments.replace_external_links(content_html) response = JSON.build do |json| json.object do json.field "contentHtml", content_html diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 95fa3d79..cd11995f 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -316,6 +316,9 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any description_html = parse_description(video_secondary_renderer.try &.dig?("attributedDescription"), video_id) + # use comments link_utils to replace external links with the confirmation page + description_html = Invidious::Comments.replace_external_links(description_html) + # Video metadata metadata = video_secondary_renderer