Class: Banzai::Filter::ReferenceFilter
- Inherits:
-
HTML::Pipeline::Filter
- Object
- HTML::Pipeline::Filter
- Banzai::Filter::ReferenceFilter
- Includes:
- OutputSafety, RequestStoreReferenceCache
- Defined in:
- lib/banzai/filter/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.
Direct Known Subclasses
AbstractReferenceFilter, ExternalIssueReferenceFilter, ProjectReferenceFilter, UserReferenceFilter
Class Attribute Summary collapse
-
.reference_type ⇒ Object
Returns the value of attribute reference_type.
Class Method Summary collapse
Instance Method Summary collapse
- #call_and_update_nodes ⇒ Object
-
#data_attribute(attributes = {}) ⇒ Object
Returns a data attribute String to attach to a reference link.
-
#each_node ⇒ Object
Iterates over all <a> and text() nodes in a document.
- #element_node?(node) ⇒ Boolean
- #group ⇒ Object
- #ignore_ancestor_query ⇒ Object
-
#initialize(doc, context = nil, result = nil) ⇒ ReferenceFilter
constructor
A new instance of ReferenceFilter.
-
#nodes ⇒ Object
Returns an Array containing all HTML nodes.
- #project ⇒ Object
- #reference_class(type, tooltip: true) ⇒ Object
- #replace_link_node_with_href(node, index, link) ⇒ Object
- #replace_link_node_with_text(node, index) ⇒ Object
- #replace_text_when_pattern_matches(node, index, pattern) ⇒ Object
- #skip_project_check? ⇒ Boolean
- #text_node?(node) ⇒ Boolean
- #user ⇒ Object
-
#validate ⇒ Object
Ensure that a :project key exists in context.
-
#yield_valid_link(node) {|link, inner_html| ... } ⇒ Object
Yields the link's URL and inner HTML whenever the node is a valid <a> tag.
Methods included from OutputSafety
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.
25 26 27 28 29 30 |
# File 'lib/banzai/filter/reference_filter.rb', line 25 def initialize(doc, context = nil, result = nil) super @new_nodes = {} @nodes = self.result[:reference_filter_nodes] end |
Class Attribute Details
.reference_type ⇒ Object
Returns the value of attribute reference_type
18 19 20 |
# File 'lib/banzai/filter/reference_filter.rb', line 18 def reference_type @reference_type end |
Class Method Details
.call(doc, context = nil, result = nil) ⇒ Object
20 21 22 |
# File 'lib/banzai/filter/reference_filter.rb', line 20 def call(doc, context = nil, result = nil) new(doc, context, result).call_and_update_nodes end |
Instance Method Details
#call_and_update_nodes ⇒ Object
32 33 34 |
# File 'lib/banzai/filter/reference_filter.rb', line 32 def call_and_update_nodes with_update_nodes { call } end |
#data_attribute(attributes = {}) ⇒ Object
Returns a data attribute String to attach to a reference link
attributes - Hash, where the key becomes the data attribute name and the
value is the data attribute value
Examples:
data_attribute(project: 1, issue: 2)
# => "data-reference-type=\"SomeReferenceFilter\" data-project=\"1\" data-issue=\"2\""
data_attribute(project: 3, merge_request: 4)
# => "data-reference-type=\"SomeReferenceFilter\" data-project=\"3\" data-merge-request=\"4\""
Returns a String
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/banzai/filter/reference_filter.rb', line 50 def data_attribute(attributes = {}) attributes = attributes.reject { |_, v| v.nil? } attributes[:reference_type] ||= self.class.reference_type attributes[:container] ||= 'body' attributes[:placement] ||= 'top' attributes.delete(:original) if context[:no_original_data] attributes.map do |key, value| %Q(data-#{key.to_s.dasherize}="#{escape_once(value)}") end.join(' ') end |
#each_node ⇒ Object
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.
107 108 109 110 111 112 113 |
# File 'lib/banzai/filter/reference_filter.rb', line 107 def each_node return to_enum(__method__) unless block_given? doc.xpath(query).each do |node| yield node end end |
#element_node?(node) ⇒ Boolean
155 156 157 |
# File 'lib/banzai/filter/reference_filter.rb', line 155 def element_node?(node) node.is_a?(Nokogiri::XML::Element) end |
#group ⇒ Object
75 76 77 |
# File 'lib/banzai/filter/reference_filter.rb', line 75 def group context[:group] end |
#ignore_ancestor_query ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/banzai/filter/reference_filter.rb', line 62 def ignore_ancestor_query @ignore_ancestor_query ||= begin parents = %w(pre code a style) parents << 'blockquote' if context[:ignore_blockquotes] parents.map { |n| "ancestor::#{n}" }.join(' or ') end end |
#nodes ⇒ Object
Returns an Array containing all HTML nodes.
116 117 118 |
# File 'lib/banzai/filter/reference_filter.rb', line 116 def nodes @nodes ||= each_node.to_a end |
#project ⇒ Object
71 72 73 |
# File 'lib/banzai/filter/reference_filter.rb', line 71 def project context[:project] end |
#reference_class(type, tooltip: true) ⇒ Object
87 88 89 90 91 92 93 |
# File 'lib/banzai/filter/reference_filter.rb', line 87 def reference_class(type, tooltip: true) gfm_klass = "gfm gfm-#{type}" return gfm_klass unless tooltip "#{gfm_klass} has-tooltip" end |
#replace_link_node_with_href(node, index, link) ⇒ Object
145 146 147 148 149 |
# File 'lib/banzai/filter/reference_filter.rb', line 145 def replace_link_node_with_href(node, index, link) html = yield replace_text_with_html(node, index, html) unless html == link end |
#replace_link_node_with_text(node, index) ⇒ Object
139 140 141 142 143 |
# File 'lib/banzai/filter/reference_filter.rb', line 139 def replace_link_node_with_text(node, index) html = yield replace_text_with_html(node, index, html) unless html == node.text end |
#replace_text_when_pattern_matches(node, index, pattern) ⇒ Object
130 131 132 133 134 135 136 137 |
# File 'lib/banzai/filter/reference_filter.rb', line 130 def replace_text_when_pattern_matches(node, index, pattern) return unless node.text =~ pattern content = node.to_html html = yield content replace_text_with_html(node, index, html) unless html == content end |
#skip_project_check? ⇒ Boolean
83 84 85 |
# File 'lib/banzai/filter/reference_filter.rb', line 83 def skip_project_check? context[:skip_project_check] end |
#text_node?(node) ⇒ Boolean
151 152 153 |
# File 'lib/banzai/filter/reference_filter.rb', line 151 def text_node?(node) node.is_a?(Nokogiri::XML::Text) end |
#user ⇒ Object
79 80 81 |
# File 'lib/banzai/filter/reference_filter.rb', line 79 def user context[:user] end |
#validate ⇒ Object
Ensure that a :project key exists in context
Note that while the key might exist, its value could be nil!
98 99 100 |
# File 'lib/banzai/filter/reference_filter.rb', line 98 def validate needs :project unless skip_project_check? end |
#yield_valid_link(node) {|link, inner_html| ... } ⇒ Object
Yields the link's URL and inner HTML whenever the node is a valid <a> tag.
121 122 123 124 125 126 127 128 |
# File 'lib/banzai/filter/reference_filter.rb', line 121 def yield_valid_link(node) link = CGI.unescape(node.attr('href').to_s) inner_html = node.inner_html return unless link.force_encoding('UTF-8').valid_encoding? yield link, inner_html end |