summaryrefslogtreecommitdiff
path: root/lib/banzai
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2018-02-28 20:06:12 +0100
committerKamil Trzciński <ayufan@ayufan.eu>2018-02-28 20:06:12 +0100
commit5a69b51bc870f5b42ee3406ba77de02f44ef8d32 (patch)
treec2a6e5b2c171826236b5d0f5e1ed8d02bd1554d2 /lib/banzai
parentb1f8d8a1739ff48412c8205f0007a2af8399d097 (diff)
parentb39d0c318921bae2e3a11df9ee6828291dad9864 (diff)
downloadgitlab-ce-5a69b51bc870f5b42ee3406ba77de02f44ef8d32.tar.gz
Merge commit 'b39d0c318921bae2e3a11df9ee6828291dad9864' into object-storage-ee-to-ce-backport
Diffstat (limited to 'lib/banzai')
-rw-r--r--lib/banzai/commit_renderer.rb11
-rw-r--r--lib/banzai/filter/external_issue_reference_filter.rb4
-rw-r--r--lib/banzai/filter/image_lazy_load_filter.rb4
-rw-r--r--lib/banzai/filter/table_of_contents_filter.rb90
-rw-r--r--lib/banzai/object_renderer.rb4
-rw-r--r--lib/banzai/pipeline/base_pipeline.rb2
-rw-r--r--lib/banzai/renderer.rb8
7 files changed, 96 insertions, 27 deletions
diff --git a/lib/banzai/commit_renderer.rb b/lib/banzai/commit_renderer.rb
new file mode 100644
index 00000000000..f5ff95e3eb3
--- /dev/null
+++ b/lib/banzai/commit_renderer.rb
@@ -0,0 +1,11 @@
+module Banzai
+ module CommitRenderer
+ ATTRIBUTES = [:description, :title].freeze
+
+ def self.render(commits, project, user = nil)
+ obj_renderer = ObjectRenderer.new(project, user)
+
+ ATTRIBUTES.each { |attr| obj_renderer.render(commits, attr) }
+ end
+ end
+end
diff --git a/lib/banzai/filter/external_issue_reference_filter.rb b/lib/banzai/filter/external_issue_reference_filter.rb
index 53a229256a5..ed01a72ff9f 100644
--- a/lib/banzai/filter/external_issue_reference_filter.rb
+++ b/lib/banzai/filter/external_issue_reference_filter.rb
@@ -95,10 +95,10 @@ module Banzai
private
def external_issues_cached(attribute)
- return project.public_send(attribute) unless RequestStore.active?
+ return project.public_send(attribute) unless RequestStore.active? # rubocop:disable GitlabSecurity/PublicSend
cached_attributes = RequestStore[:banzai_external_issues_tracker_attributes] ||= Hash.new { |h, k| h[k] = {} }
- cached_attributes[project.id][attribute] = project.public_send(attribute) if cached_attributes[project.id][attribute].nil?
+ cached_attributes[project.id][attribute] = project.public_send(attribute) if cached_attributes[project.id][attribute].nil? # rubocop:disable GitlabSecurity/PublicSend
cached_attributes[project.id][attribute]
end
end
diff --git a/lib/banzai/filter/image_lazy_load_filter.rb b/lib/banzai/filter/image_lazy_load_filter.rb
index 7a81d583b82..bcb4f332267 100644
--- a/lib/banzai/filter/image_lazy_load_filter.rb
+++ b/lib/banzai/filter/image_lazy_load_filter.rb
@@ -6,9 +6,9 @@ module Banzai
doc.xpath('descendant-or-self::img').each do |img|
img['class'] ||= '' << 'lazy'
img['data-src'] = img['src']
- img['src'] = LazyImageTagHelper.placeholder_image
+ img['src'] = LazyImageTagHelper.placeholder_image
end
-
+
doc
end
end
diff --git a/lib/banzai/filter/table_of_contents_filter.rb b/lib/banzai/filter/table_of_contents_filter.rb
index 8e7084f2543..47151626208 100644
--- a/lib/banzai/filter/table_of_contents_filter.rb
+++ b/lib/banzai/filter/table_of_contents_filter.rb
@@ -22,40 +22,94 @@ module Banzai
result[:toc] = ""
headers = Hash.new(0)
+ header_root = current_header = HeaderNode.new
doc.css('h1, h2, h3, h4, h5, h6').each do |node|
- text = node.text
+ if header_content = node.children.first
+ id = node
+ .text
+ .downcase
+ .gsub(PUNCTUATION_REGEXP, '') # remove punctuation
+ .tr(' ', '-') # replace spaces with dash
+ .squeeze('-') # replace multiple dashes with one
- id = text.downcase
- id.gsub!(PUNCTUATION_REGEXP, '') # remove punctuation
- id.tr!(' ', '-') # replace spaces with dash
- id.squeeze!('-') # replace multiple dashes with one
+ uniq = headers[id] > 0 ? "-#{headers[id]}" : ''
+ headers[id] += 1
+ href = "#{id}#{uniq}"
- uniq = (headers[id] > 0) ? "-#{headers[id]}" : ''
- headers[id] += 1
+ current_header = HeaderNode.new(node: node, href: href, previous_header: current_header)
- if header_content = node.children.first
- # namespace detection will be automatically handled via javascript (see issue #22781)
- namespace = "user-content-"
- href = "#{id}#{uniq}"
- push_toc(href, text)
- header_content.add_previous_sibling(anchor_tag("#{namespace}#{href}", href))
+ header_content.add_previous_sibling(anchor_tag(href))
end
end
- result[:toc] = %Q{<ul class="section-nav">\n#{result[:toc]}</ul>} unless result[:toc].empty?
+ push_toc(header_root.children, root: true)
doc
end
private
- def anchor_tag(id, href)
- %Q{<a id="#{id}" class="anchor" href="##{href}" aria-hidden="true"></a>}
+ def anchor_tag(href)
+ %Q{<a id="user-content-#{href}" class="anchor" href="##{href}" aria-hidden="true"></a>}
end
- def push_toc(href, text)
- result[:toc] << %Q{<li><a href="##{href}">#{text}</a></li>\n}
+ def push_toc(children, root: false)
+ return if children.empty?
+
+ klass = ' class="section-nav"' if root
+
+ result[:toc] << "<ul#{klass}>"
+ children.each { |child| push_anchor(child) }
+ result[:toc] << '</ul>'
+ end
+
+ def push_anchor(header_node)
+ result[:toc] << %Q{<li><a href="##{header_node.href}">#{header_node.text}</a>}
+ push_toc(header_node.children)
+ result[:toc] << '</li>'
+ end
+
+ class HeaderNode
+ attr_reader :node, :href, :parent, :children
+
+ def initialize(node: nil, href: nil, previous_header: nil)
+ @node = node
+ @href = href
+ @children = []
+
+ @parent = find_parent(previous_header)
+ @parent.children.push(self) if @parent
+ end
+
+ def level
+ return 0 unless node
+
+ @level ||= node.name[1].to_i
+ end
+
+ def text
+ return '' unless node
+
+ @text ||= node.text
+ end
+
+ private
+
+ def find_parent(previous_header)
+ return unless previous_header
+
+ if level == previous_header.level
+ parent = previous_header.parent
+ elsif level > previous_header.level
+ parent = previous_header
+ else
+ parent = previous_header
+ parent = parent.parent while parent.level >= level
+ end
+
+ parent
+ end
end
end
end
diff --git a/lib/banzai/object_renderer.rb b/lib/banzai/object_renderer.rb
index 002a3341ccd..e40556e869c 100644
--- a/lib/banzai/object_renderer.rb
+++ b/lib/banzai/object_renderer.rb
@@ -37,8 +37,8 @@ module Banzai
objects.each_with_index do |object, index|
redacted_data = redacted[index]
- object.__send__("redacted_#{attribute}_html=", redacted_data[:document].to_html.html_safe)
- object.user_visible_reference_count = redacted_data[:visible_reference_count]
+ object.__send__("redacted_#{attribute}_html=", redacted_data[:document].to_html.html_safe) # rubocop:disable GitlabSecurity/PublicSend
+ object.user_visible_reference_count = redacted_data[:visible_reference_count] if object.respond_to?(:user_visible_reference_count)
end
end
diff --git a/lib/banzai/pipeline/base_pipeline.rb b/lib/banzai/pipeline/base_pipeline.rb
index 321fd5bbe14..3ae3bed570d 100644
--- a/lib/banzai/pipeline/base_pipeline.rb
+++ b/lib/banzai/pipeline/base_pipeline.rb
@@ -18,7 +18,7 @@ module Banzai
define_method(meth) do |text, context|
context = transform_context(context)
- html_pipeline.send(meth, text, context)
+ html_pipeline.__send__(meth, text, context) # rubocop:disable GitlabSecurity/PublicSend
end
end
end
diff --git a/lib/banzai/renderer.rb b/lib/banzai/renderer.rb
index ad08c0905e2..ceca9296851 100644
--- a/lib/banzai/renderer.rb
+++ b/lib/banzai/renderer.rb
@@ -36,6 +36,10 @@ module Banzai
# The context to use is managed by the object and cannot be changed.
# Use #render, passing it the field text, if a custom rendering is needed.
def self.render_field(object, field)
+ unless object.respond_to?(:cached_markdown_fields)
+ return cacheless_render_field(object, field)
+ end
+
object.refresh_markdown_cache!(do_update: update_object?(object)) unless object.cached_html_up_to_date?(field)
object.cached_html_for(field)
@@ -43,7 +47,7 @@ module Banzai
# Same as +render_field+, but without consulting or updating the cache field
def self.cacheless_render_field(object, field, options = {})
- text = object.__send__(field)
+ text = object.__send__(field) # rubocop:disable GitlabSecurity/PublicSend
context = object.banzai_render_context(field).merge(options)
cacheless_render(text, context)
@@ -156,7 +160,7 @@ module Banzai
# method.
def self.full_cache_multi_key(cache_key, pipeline_name)
return unless cache_key
- Rails.cache.send(:expanded_key, full_cache_key(cache_key, pipeline_name))
+ Rails.cache.__send__(:expanded_key, full_cache_key(cache_key, pipeline_name)) # rubocop:disable GitlabSecurity/PublicSend
end
# GitLab EE needs to disable updates on GET requests in Geo