diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 3c207619adf3c88a535ee8ffbcdbbc96d2dac172..2777944fc9d753e1bb46da49c892e79fc577f348 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -41,29 +41,26 @@ module GitlabMarkdownHelper fragment.to_html.html_safe end + MARKDOWN_OPTIONS = { + no_intra_emphasis: true, + tables: true, + fenced_code_blocks: true, + strikethrough: true, + lax_spacing: true, + space_after_headers: true, + superscript: true, + footnotes: true + }.freeze + def markdown(text, options={}) unless @markdown && options == @options @options = options - options.merge!( - # Handled further down the line by Gitlab::Markdown::SanitizationFilter - escape_html: false - ) - # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, options) # see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use - @markdown = Redcarpet::Markdown.new(rend, - no_intra_emphasis: true, - tables: true, - fenced_code_blocks: true, - strikethrough: true, - lax_spacing: true, - space_after_headers: true, - superscript: true, - footnotes: true - ) + @markdown = Redcarpet::Markdown.new(rend, MARKDOWN_OPTIONS) end @markdown.render(text).html_safe diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index e35f848fa6e5f60701b4427a7d40ac97bd6d732f..80b8ab8cbcc3d51c9eb3c408401c89c11fa9b538 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -1,7 +1,7 @@ module Gitlab # Extract possible GFM references from an arbitrary String for further processing. class ReferenceExtractor - attr_accessor :project, :current_user, :references + attr_accessor :project, :current_user def initialize(project, current_user = nil) @project = project @@ -9,48 +9,31 @@ module Gitlab end def analyze(text) - @_text = text.dup + references.clear + @text = markdown.render(text.dup) end - def users - result = pipeline_result(:user) - result.uniq + %i(user label issue merge_request snippet commit commit_range).each do |type| + define_method("#{type}s") do + references[type] + end end - def labels - result = pipeline_result(:label) - result.uniq - end - - def issues - # TODO (rspeicher): What about external issues? - - result = pipeline_result(:issue) - result.uniq - end - - def merge_requests - result = pipeline_result(:merge_request) - result.uniq - end + private - def snippets - result = pipeline_result(:snippet) - result.uniq + def markdown + @markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, GitlabMarkdownHelper::MARKDOWN_OPTIONS) end - def commits - result = pipeline_result(:commit) - result.uniq - end + def references + @references ||= Hash.new do |references, type| + type = type.to_sym + return references[type] if references.has_key?(type) - def commit_ranges - result = pipeline_result(:commit_range) - result.uniq + references[type] = pipeline_result(type).uniq + end end - private - # Instantiate and call HTML::Pipeline with a single reference filter type, # returning the result # @@ -69,7 +52,7 @@ module Gitlab } pipeline = HTML::Pipeline.new([filter], context) - result = pipeline.call(@_text) + result = pipeline.call(@text) result[:references][filter_type] end diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index 7dcecc2ecf6743756b1b968b32095f717d34b5ec..133798852ee17ef1eaca466942b0629aac4b3bb3 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -10,6 +10,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML @options = options.dup @options.reverse_merge!( + # Handled further down the line by Gitlab::Markdown::SanitizationFilter + escape_html: false project: @template.instance_variable_get("@project") ) diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index c14f4ac6bf676dee063f28f46ec7aa6f616b482b..951e738cb67cbcdef399b002418271d58deede7b 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -16,6 +16,26 @@ describe Gitlab::ReferenceExtractor do expect(subject.users).to eq([@u_foo, @u_bar, @u_offteam]) end + it 'ignores user mentions inside specific elements' do + @u_foo = create(:user, username: 'foo') + @u_bar = create(:user, username: 'bar') + @u_offteam = create(:user, username: 'offteam') + + project.team << [@u_foo, :reporter] + project.team << [@u_bar, :guest] + + subject.analyze(%Q{ + Inline code: `@foo` + + Code block: + + ``` + @bar + ``` + }) + expect(subject.users).to eq([]) + end + it 'accesses valid issue objects' do @i0 = create(:issue, project: project) @i1 = create(:issue, project: project)