diff options
Diffstat (limited to 'lib/banzai/filter/reference_gatherer_filter.rb')
-rw-r--r-- | lib/banzai/filter/reference_gatherer_filter.rb | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/banzai/filter/reference_gatherer_filter.rb b/lib/banzai/filter/reference_gatherer_filter.rb new file mode 100644 index 00000000000..855f238ac1e --- /dev/null +++ b/lib/banzai/filter/reference_gatherer_filter.rb @@ -0,0 +1,62 @@ +require 'banzai' +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 + doc.css('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 unless reference_filter.user_can_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 + end + end +end |