Class: Banzai::Filter::References::MilestoneReferenceFilter
- Inherits:
-
AbstractReferenceFilter
- Object
- HTML::Pipeline::Filter
- ReferenceFilter
- AbstractReferenceFilter
- Banzai::Filter::References::MilestoneReferenceFilter
- Defined in:
- lib/banzai/filter/references/milestone_reference_filter.rb
Overview
HTML filter that replaces milestone references with links.
Constant Summary
Constants included from Concerns::TimeoutFilterHandler
Concerns::TimeoutFilterHandler::COMPLEX_MARKDOWN_MESSAGE, Concerns::TimeoutFilterHandler::RENDER_TIMEOUT, Concerns::TimeoutFilterHandler::SANITIZATION_RENDER_TIMEOUT
Constants included from Concerns::PipelineTimingCheck
Concerns::PipelineTimingCheck::MAX_PIPELINE_SECONDS
Constants inherited from ReferenceFilter
ReferenceFilter::REFERENCE_TYPE_ATTRIBUTE, ReferenceFilter::REFERENCE_TYPE_DATA_ATTRIBUTE_NAME
Constants included from Concerns::TextReplacer
Concerns::TextReplacer::REFERENCE_PLACEHOLDER, Concerns::TextReplacer::REFERENCE_PLACEHOLDER_PATTERN
Instance Method Summary collapse
- #data_attributes_for(original, parent, object, link_content: false, link_reference: false) ⇒ Object
- #find_milestones(parent, find_by_iid = false, absolute_path: false) ⇒ Object
- #find_object(parent_object, id) ⇒ Object
- #group_and_ancestors_ids(parent, absolute_path) ⇒ Object
- #group_context?(parent) ⇒ Boolean
- #milestone_finder_params(parent, find_by_iid, absolute_path) ⇒ Object
- #object_link_content_html(object, matches) ⇒ Object
- #object_link_title(object, matches) ⇒ Object
- #parent ⇒ Object
- #parent_records(parent, ids) ⇒ Object
-
#parse_symbol(symbol, match_data) ⇒ Object
Transform a symbol extracted from the text to a meaningful value.
- #project_context?(parent) ⇒ Boolean
-
#record_identifier(record) ⇒ Object
This method has the contract that if a string
refrefers to a recordrecord, then ‘class.parse_symbol(ref) == record_identifier(record)`. - #references_in(text, pattern = Milestone.reference_pattern) ⇒ Object
- #requires_unescaping? ⇒ Boolean
- #url_for_object(milestone, project) ⇒ Object
- #valid_context?(parent) ⇒ Boolean
Methods inherited from AbstractReferenceFilter
#call, #find_object_cached, #find_object_from_link, #find_object_from_link_cached, #from_ref_cached, #identifier, #initialize, #object_link_content_html_extras, #object_link_filter, #parent_type, #symbol_from_match_data, #url_for_object_cached, #wrap_link
Methods included from CrossProjectReference
Methods included from Concerns::TimeoutFilterHandler
Methods included from Concerns::PipelineTimingCheck
#call, #exceeded_pipeline_max?
Methods inherited from ReferenceFilter
call, #call, #call_and_update_nodes, #each_node, #group, #initialize, #nodes, #nodes?, #object_class, #project
Methods included from Concerns::TextReplacer
#replace_references_in_text_with_html
Methods included from Concerns::HtmlWriter
Methods included from Concerns::OutputSafety
Methods included from RequestStoreReferenceCache
#cached_call, #get_or_set_cache
Constructor Details
This class inherits a constructor from Banzai::Filter::References::AbstractReferenceFilter
Instance Method Details
#data_attributes_for(original, parent, object, link_content: false, link_reference: false) ⇒ Object
153 154 155 156 157 158 159 160 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 153 def data_attributes_for(original, parent, object, link_content: false, link_reference: false) object_parent = object.resource_parent return super unless object_parent.is_a?(Group) return super if object_parent.id == parent.id super.merge({ group: object_parent.id, namespace: object_parent.id, project: nil }) end |
#find_milestones(parent, find_by_iid = false, absolute_path: false) ⇒ Object
100 101 102 103 104 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 100 def find_milestones(parent, find_by_iid = false, absolute_path: false) finder_params = milestone_finder_params(parent, find_by_iid, absolute_path) MilestonesFinder.new(finder_params).execute end |
#find_object(parent_object, id) ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 37 def find_object(parent_object, id) key = reference_cache.records_per_parent[parent_object].keys.find do |k| k[:milestone_iid] == id[:milestone_iid] || k[:milestone_name] == id[:milestone_name] end reference_cache.records_per_parent[parent_object][key] if key end |
#group_and_ancestors_ids(parent, absolute_path) ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 116 def group_and_ancestors_ids(parent, absolute_path) if group_context?(parent) absolute_path ? parent.id : parent.self_and_ancestors.select(:id) elsif project_context?(parent) absolute_path ? nil : parent.group&.self_and_ancestors&.select(:id) end end |
#group_context?(parent) ⇒ Boolean
80 81 82 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 80 def group_context?(parent) parent.is_a?(Group) end |
#milestone_finder_params(parent, find_by_iid, absolute_path) ⇒ Object
106 107 108 109 110 111 112 113 114 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 106 def milestone_finder_params(parent, find_by_iid, absolute_path) { order: nil, state: 'all' }.tap do |params| params[:project_ids] = parent.id if project_context?(parent) # We don't support IID lookups because IIDs can clash between # group/project milestones and group/subgroup milestones. params[:group_ids] = group_and_ancestors_ids(parent, absolute_path) unless find_by_iid end end |
#object_link_content_html(object, matches) ⇒ Object
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 130 def object_link_content_html(object, matches) html = super reference = object.project&.to_reference_base(project) i = doc.document.create_element('i') i.content = "in #{reference}" html += " #{i.to_html}" if reference.present? html end |
#object_link_title(object, matches) ⇒ Object
141 142 143 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 141 def object_link_title(object, matches) nil end |
#parent ⇒ Object
145 146 147 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 145 def parent project || group end |
#parent_records(parent, ids) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 11 def parent_records(parent, ids) return Milestone.none unless valid_context?(parent) relation = [] # We need to handle relative and absolute paths separately milestones_absolute_indexed = ids.group_by { |id| id[:absolute_path] } milestones_absolute_indexed.each do |absolute_path, fitered_ids| milestone_iids = fitered_ids&.pluck(:milestone_iid)&.compact if milestone_iids.present? relation << find_milestones(parent, true, absolute_path: absolute_path).iid_in(milestone_iids) end milestone_names = fitered_ids&.pluck(:milestone_name)&.compact if milestone_names.present? relation << find_milestones(parent, false, absolute_path: absolute_path).where(name: milestone_names) end end relation.compact! return Milestone.none if relation.all?(Milestone.none) Milestone.from_union(relation).includes(:project, :group) end |
#parse_symbol(symbol, match_data) ⇒ Object
Transform a symbol extracted from the text to a meaningful value
This method has the contract that if a string ref refers to a record record, then ‘parse_symbol(ref) == record_identifier(record)`.
This contract is slightly broken here, as we only have either the milestone_iid or the milestone_name, but not both. But below, we have both pieces of information. But it’s accounted for in find_object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 53 def parse_symbol(symbol, match_data) absolute_path = !!match_data&.named_captures&.fetch('absolute_path') if symbol # when parsing links, there is no `match_data[:milestone_iid]`, but `symbol` # holds the iid { milestone_iid: symbol.to_i, milestone_name: nil, absolute_path: absolute_path } else { milestone_iid: match_data[:milestone_iid]&.to_i, milestone_name: match_data[:milestone_name]&.tr('"', ''), absolute_path: absolute_path } end end |
#project_context?(parent) ⇒ Boolean
84 85 86 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 84 def project_context?(parent) parent.is_a?(Project) end |
#record_identifier(record) ⇒ Object
This method has the contract that if a string ref refers to a record record, then ‘class.parse_symbol(ref) == record_identifier(record)`. See note in parse_symbol above
72 73 74 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 72 def record_identifier(record) { milestone_iid: record.iid, milestone_name: record.name } end |
#references_in(text, pattern = Milestone.reference_pattern) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 88 def references_in(text, pattern = Milestone.reference_pattern) # We'll handle here the references that follow the `reference_pattern`. # Other patterns (for example, the link pattern) are handled by the # default implementation. return super(text, pattern) if pattern != Milestone.reference_pattern replace_references_in_text_with_html(text.gsub(pattern)) do |match_data| ident = identifier(match_data) yield match_data[0], ident, match_data[:project], match_data[:namespace], match_data end end |
#requires_unescaping? ⇒ Boolean
149 150 151 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 149 def requires_unescaping? true end |
#url_for_object(milestone, project) ⇒ Object
124 125 126 127 128 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 124 def url_for_object(milestone, project) Gitlab::Routing .url_helpers .milestone_url(milestone, only_path: context[:only_path]) end |
#valid_context?(parent) ⇒ Boolean
76 77 78 |
# File 'lib/banzai/filter/references/milestone_reference_filter.rb', line 76 def valid_context?(parent) group_context?(parent) || project_context?(parent) end |