# frozen_string_literal: true module Banzai module Filter # HTML filter that "fixes" links to pages/files in a wiki. # Rewrite rules are documented in the `WikiPipeline` spec. # # Context options: # :wiki class WikiLinkFilter < HTML::Pipeline::Filter include Gitlab::Utils::SanitizeNodeLink CSS_A = 'a:not(.gfm)' XPATH_A = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_A).freeze CSS_VA = 'video, audio' XPATH_VA = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_VA).freeze CSS_IMG = 'img' XPATH_IMG = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_IMG).freeze def call return doc unless wiki? doc.xpath(XPATH_A).each { |el| process_link(el.attribute('href'), el) } doc.xpath(XPATH_VA).each { |el| process_link(el.attribute('src'), el) } doc.xpath(XPATH_IMG).each do |el| attr = el.attribute('data-src') || el.attribute('src') process_link(attr, el) end doc end protected def process_link(link_attr, node) process_link_attr(link_attr) remove_unsafe_links({ node: node }, remove_invalid_links: false) end def wiki? !context[:wiki].nil? end def process_link_attr(html_attr) return if html_attr.blank? html_attr.value = apply_rewrite_rules(html_attr.value) rescue URI::Error, Addressable::URI::InvalidURIError # noop end def apply_rewrite_rules(link_string) Rewriter.new(link_string, wiki: context[:wiki], slug: context[:page_slug]).apply_rules end end end end