Class: Banzai::Filter::References::ReferenceFilter

Inherits:
HTML::Pipeline::Filter
  • Object
show all
Includes:
OutputSafety, RequestStoreReferenceCache
Defined in:
lib/banzai/filter/references/reference_filter.rb

Overview

Base class for GitLab Flavored Markdown reference filters.

References within <pre>, <code>, <a>, and <style> elements are ignored.

Context options:

:project (required) - Current project, ignored if reference is cross-project.
:only_path          - Generate path-only links.

Constant Summary collapse

REFERENCE_TYPE_DATA_ATTRIBUTE =
'data-reference-type='

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OutputSafety

#escape_once

Methods included from RequestStoreReferenceCache

#cached_call, #get_or_set_cache

Constructor Details

#initialize(doc, context = nil, result = nil) ⇒ ReferenceFilter

Returns a new instance of ReferenceFilter.



34
35
36
37
38
39
# File 'lib/banzai/filter/references/reference_filter.rb', line 34

def initialize(doc, context = nil, result = nil)
  super

  @new_nodes = {}
  @nodes = self.result[:reference_filter_nodes]
end

Class Attribute Details

.object_classObject

Implement in child class Example: self.object_class = MergeRequest



27
28
29
# File 'lib/banzai/filter/references/reference_filter.rb', line 27

def object_class
  @object_class
end

.reference_typeObject

Implement in child class Example: self.reference_type = :merge_request



23
24
25
# File 'lib/banzai/filter/references/reference_filter.rb', line 23

def reference_type
  @reference_type
end

Class Method Details

.call(doc, context = nil, result = nil) ⇒ Object



29
30
31
# File 'lib/banzai/filter/references/reference_filter.rb', line 29

def call(doc, context = nil, result = nil)
  new(doc, context, result).call_and_update_nodes
end

Instance Method Details

#callObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/banzai/filter/references/reference_filter.rb', line 45

def call
  ref_pattern_start = /\A#{object_reference_pattern}\z/

  nodes.each_with_index do |node, index|
    if text_node?(node)
      replace_text_when_pattern_matches(node, index, object_reference_pattern) do |content|
        object_link_filter(content, object_reference_pattern)
      end
    elsif element_node?(node)
      yield_valid_link(node) do |link, inner_html|
        if link =~ ref_pattern_start
          replace_link_node_with_href(node, index, link) do
            object_link_filter(link, object_reference_pattern, link_content: inner_html)
          end
        end
      end
    end
  end

  doc
end

#call_and_update_nodesObject



41
42
43
# File 'lib/banzai/filter/references/reference_filter.rb', line 41

def call_and_update_nodes
  with_update_nodes { call }
end

#each_nodeObject

Iterates over all <a> and text() nodes in a document.

Nodes are skipped whenever their ancestor is one of the nodes returned by ‘ignore_ancestor_query`. Link tags are not processed if they have a “gfm” class or the “href” attribute is empty.



89
90
91
92
93
94
95
# File 'lib/banzai/filter/references/reference_filter.rb', line 89

def each_node
  return to_enum(__method__) unless block_given?

  doc.xpath(query).each do |node|
    yield node
  end
end

#groupObject



110
111
112
# File 'lib/banzai/filter/references/reference_filter.rb', line 110

def group
  context[:group]
end

#nodesObject

Returns an Array containing all HTML nodes.



98
99
100
# File 'lib/banzai/filter/references/reference_filter.rb', line 98

def nodes
  @nodes ||= each_node.to_a
end

#object_classObject



102
103
104
# File 'lib/banzai/filter/references/reference_filter.rb', line 102

def object_class
  self.class.object_class
end

#projectObject



106
107
108
# File 'lib/banzai/filter/references/reference_filter.rb', line 106

def project
  context[:project]
end

#references_in(text, pattern = object_reference_pattern) ⇒ Object

Public: Find references in text (like ‘!123` for merge requests)

references_in(text) do |match, id, project_ref, matches|
  object = find_object(project_ref, id)
  "<a href=...>#{object.to_reference}</a>"
end

text - String text to search.

Yields the String match, the Integer referenced object ID, an optional String of the external project reference, and all of the matchdata.

Returns a String replaced with the return of the block.

Raises:

  • (NotImplementedError)


80
81
82
# File 'lib/banzai/filter/references/reference_filter.rb', line 80

def references_in(text, pattern = object_reference_pattern)
  raise NotImplementedError, "#{self.class} must implement method: #{__callee__}"
end

#requires_unescaping?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/banzai/filter/references/reference_filter.rb', line 114

def requires_unescaping?
  false
end