require 'html/pipeline/filter' module Banzai module Filter # HTML filter that gathers all referenced records that the current user has # permission to view. # # Expected to be run in its own post-processing pipeline. # class ReferenceGathererFilter < HTML::Pipeline::Filter def initialize(*) super result[:references] ||= Hash.new { |hash, type| hash[type] = [] } end def call Querying.css(doc, 'a.gfm').each do |node| gather_references(node) end load_lazy_references unless ReferenceExtractor.lazy? doc end private def gather_references(node) return unless node.has_attribute?('data-reference-filter') reference_type = node.attr('data-reference-filter') reference_filter = Banzai::Filter.const_get(reference_type) return if context[:reference_filter] && reference_filter != context[:reference_filter] return if author && !reference_filter.user_can_reference?(author, node, context) return unless reference_filter.user_can_see_reference?(current_user, node, context) references = reference_filter.referenced_by(node) return unless references references.each do |type, values| Array.wrap(values).each do |value| result[:references][type] << value end end end def load_lazy_references refs = result[:references] refs.each do |type, values| refs[type] = ReferenceExtractor.lazily(values) end end def current_user context[:current_user] end def author context[:author] end end end end