summaryrefslogtreecommitdiff
path: root/lib/banzai/filter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/banzai/filter')
-rw-r--r--lib/banzai/filter/emoji_filter.rb5
-rw-r--r--lib/banzai/filter/external_link_filter.rb36
-rw-r--r--lib/banzai/filter/issuable_state_filter.rb37
-rw-r--r--lib/banzai/filter/markdown_filter.rb2
-rw-r--r--lib/banzai/filter/plantuml_filter.rb8
-rw-r--r--lib/banzai/filter/redactor_filter.rb2
-rw-r--r--lib/banzai/filter/sanitization_filter.rb22
-rw-r--r--lib/banzai/filter/syntax_highlight_filter.rb2
8 files changed, 66 insertions, 48 deletions
diff --git a/lib/banzai/filter/emoji_filter.rb b/lib/banzai/filter/emoji_filter.rb
index d6138816e70..6255a611dbe 100644
--- a/lib/banzai/filter/emoji_filter.rb
+++ b/lib/banzai/filter/emoji_filter.rb
@@ -53,7 +53,10 @@ module Banzai
# Build a regexp that matches all valid :emoji: names.
def self.emoji_pattern
- @emoji_pattern ||= /:(#{Gitlab::Emoji.emojis_names.map { |name| Regexp.escape(name) }.join('|')}):/
+ @emoji_pattern ||=
+ /(?<=[^[:alnum:]:]|\n|^)
+ :(#{Gitlab::Emoji.emojis_names.map { |name| Regexp.escape(name) }.join('|')}):
+ (?=[^[:alnum:]:]|$)/x
end
# Build a regexp that matches all valid unicode emojis names.
diff --git a/lib/banzai/filter/external_link_filter.rb b/lib/banzai/filter/external_link_filter.rb
index d67d466bce8..d6327ef31cb 100644
--- a/lib/banzai/filter/external_link_filter.rb
+++ b/lib/banzai/filter/external_link_filter.rb
@@ -2,16 +2,17 @@ module Banzai
module Filter
# HTML Filter to modify the attributes of external links
class ExternalLinkFilter < HTML::Pipeline::Filter
+ SCHEMES = ['http', 'https', nil].freeze
+
def call
links.each do |node|
- href = href_to_lowercase_scheme(node["href"].to_s)
+ uri = uri(node['href'].to_s)
+ next unless uri
- unless node["href"].to_s == href
- node.set_attribute('href', href)
- end
+ node.set_attribute('href', uri.to_s)
- if href =~ %r{\A(https?:)?//[^/]} && external_url?(href)
- node.set_attribute('rel', 'nofollow noreferrer')
+ if SCHEMES.include?(uri.scheme) && external_url?(uri)
+ node.set_attribute('rel', 'nofollow noreferrer noopener')
node.set_attribute('target', '_blank')
end
end
@@ -21,27 +22,26 @@ module Banzai
private
+ def uri(href)
+ URI.parse(href)
+ rescue URI::Error
+ nil
+ end
+
def links
query = 'descendant-or-self::a[@href and not(@href = "")]'
doc.xpath(query)
end
- def href_to_lowercase_scheme(href)
- scheme_match = href.match(/\A(\w+):\/\//)
-
- if scheme_match
- scheme_match.to_s.downcase + scheme_match.post_match
- else
- href
- end
- end
+ def external_url?(uri)
+ # Relative URLs miss a hostname
+ return false unless uri.hostname
- def external_url?(url)
- !url.start_with?(internal_url)
+ uri.hostname != internal_url.hostname
end
def internal_url
- @internal_url ||= Gitlab.config.gitlab.url
+ @internal_url ||= URI.parse(Gitlab.config.gitlab.url)
end
end
end
diff --git a/lib/banzai/filter/issuable_state_filter.rb b/lib/banzai/filter/issuable_state_filter.rb
new file mode 100644
index 00000000000..327ea9449a1
--- /dev/null
+++ b/lib/banzai/filter/issuable_state_filter.rb
@@ -0,0 +1,37 @@
+module Banzai
+ module Filter
+ # HTML filter that appends state information to issuable links.
+ # Runs as a post-process filter as issuable state might change whilst
+ # Markdown is in the cache.
+ #
+ # This filter supports cross-project references.
+ class IssuableStateFilter < HTML::Pipeline::Filter
+ VISIBLE_STATES = %w(closed merged).freeze
+
+ def call
+ return doc unless context[:issuable_state_filter_enabled]
+
+ extractor = Banzai::IssuableExtractor.new(project, current_user)
+ issuables = extractor.extract([doc])
+
+ issuables.each do |node, issuable|
+ if VISIBLE_STATES.include?(issuable.state) && node.inner_html == issuable.reference_link_text(project)
+ node.content += " (#{issuable.state})"
+ end
+ end
+
+ doc
+ end
+
+ private
+
+ def current_user
+ context[:current_user]
+ end
+
+ def project
+ context[:project]
+ end
+ end
+ end
+end
diff --git a/lib/banzai/filter/markdown_filter.rb b/lib/banzai/filter/markdown_filter.rb
index ff580ec68f8..ee73fa91589 100644
--- a/lib/banzai/filter/markdown_filter.rb
+++ b/lib/banzai/filter/markdown_filter.rb
@@ -14,7 +14,7 @@ module Banzai
def self.renderer
@renderer ||= begin
- renderer = Redcarpet::Render::HTML.new
+ renderer = Banzai::Renderer::HTML.new
Redcarpet::Markdown.new(renderer, redcarpet_options)
end
end
diff --git a/lib/banzai/filter/plantuml_filter.rb b/lib/banzai/filter/plantuml_filter.rb
index b2537117558..5325819d828 100644
--- a/lib/banzai/filter/plantuml_filter.rb
+++ b/lib/banzai/filter/plantuml_filter.rb
@@ -7,14 +7,14 @@ module Banzai
#
class PlantumlFilter < HTML::Pipeline::Filter
def call
- return doc unless doc.at('pre.plantuml') && settings.plantuml_enabled
+ return doc unless doc.at('pre > code[lang="plantuml"]') && settings.plantuml_enabled
plantuml_setup
- doc.css('pre.plantuml').each do |el|
+ doc.css('pre > code[lang="plantuml"]').each do |node|
img_tag = Nokogiri::HTML::DocumentFragment.parse(
- Asciidoctor::PlantUml::Processor.plantuml_content(el.content, {}))
- el.replace img_tag
+ Asciidoctor::PlantUml::Processor.plantuml_content(node.content, {}))
+ node.parent.replace(img_tag)
end
doc
diff --git a/lib/banzai/filter/redactor_filter.rb b/lib/banzai/filter/redactor_filter.rb
index c59a80dd1c7..9f9882b3b40 100644
--- a/lib/banzai/filter/redactor_filter.rb
+++ b/lib/banzai/filter/redactor_filter.rb
@@ -7,7 +7,7 @@ module Banzai
#
class RedactorFilter < HTML::Pipeline::Filter
def call
- Redactor.new(project, current_user).redact([doc])
+ Redactor.new(project, current_user).redact([doc]) unless context[:skip_redaction]
doc
end
diff --git a/lib/banzai/filter/sanitization_filter.rb b/lib/banzai/filter/sanitization_filter.rb
index d5f9e252f62..522217deae4 100644
--- a/lib/banzai/filter/sanitization_filter.rb
+++ b/lib/banzai/filter/sanitization_filter.rb
@@ -24,10 +24,6 @@ module Banzai
# Only push these customizations once
return if customized?(whitelist[:transformers])
- # Allow code highlighting
- whitelist[:attributes]['pre'] = %w(class v-pre)
- whitelist[:attributes]['span'] = %w(class)
-
# Allow table alignment
whitelist[:attributes]['th'] = %w(style)
whitelist[:attributes]['td'] = %w(style)
@@ -52,9 +48,6 @@ module Banzai
# Remove `rel` attribute from `a` elements
whitelist[:transformers].push(self.class.remove_rel)
- # Remove `class` attribute from non-highlight spans
- whitelist[:transformers].push(self.class.clean_spans)
-
whitelist
end
@@ -84,21 +77,6 @@ module Banzai
end
end
end
-
- def clean_spans
- lambda do |env|
- node = env[:node]
-
- return unless node.name == 'span'
- return unless node.has_attribute?('class')
-
- unless node.ancestors.any? { |n| n.name.casecmp('pre').zero? }
- node.remove_attribute('class')
- end
-
- { node_whitelist: [node] }
- end
- end
end
end
end
diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb
index 9f09ca90697..7da565043d1 100644
--- a/lib/banzai/filter/syntax_highlight_filter.rb
+++ b/lib/banzai/filter/syntax_highlight_filter.rb
@@ -14,7 +14,7 @@ module Banzai
end
def highlight_node(node)
- language = node.attr('class')
+ language = node.attr('lang')
code = node.text
css_classes = "code highlight"
lexer = lexer_for(language)