diff options
author | Robert Speicher <rspeicher@gmail.com> | 2015-04-14 18:34:01 -0400 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2015-04-20 13:01:45 -0400 |
commit | b3b8fc6c8a559b743d98577d07bc45a884e242a3 (patch) | |
tree | 72ffcac0405cbe78f90581f15010babc9e728f15 /lib | |
parent | 6189b24fddae66e1c2bb71c496301ff85701cb90 (diff) | |
download | gitlab-ce-b3b8fc6c8a559b743d98577d07bc45a884e242a3.tar.gz |
DRY up reference filters using ReferenceFilter base class
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/markdown/commit_range_reference_filter.rb | 44 | ||||
-rw-r--r-- | lib/gitlab/markdown/commit_reference_filter.rb | 44 | ||||
-rw-r--r-- | lib/gitlab/markdown/cross_project_reference.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/markdown/external_issue_reference_filter.rb | 44 | ||||
-rw-r--r-- | lib/gitlab/markdown/issue_reference_filter.rb | 48 | ||||
-rw-r--r-- | lib/gitlab/markdown/label_reference_filter.rb | 43 | ||||
-rw-r--r-- | lib/gitlab/markdown/merge_request_reference_filter.rb | 40 | ||||
-rw-r--r-- | lib/gitlab/markdown/reference_filter.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/markdown/snippet_reference_filter.rb | 40 | ||||
-rw-r--r-- | lib/gitlab/markdown/user_reference_filter.rb | 59 |
10 files changed, 55 insertions, 320 deletions
diff --git a/lib/gitlab/markdown/commit_range_reference_filter.rb b/lib/gitlab/markdown/commit_range_reference_filter.rb index 0d93bf4f280..ff85be8cb84 100644 --- a/lib/gitlab/markdown/commit_range_reference_filter.rb +++ b/lib/gitlab/markdown/commit_range_reference_filter.rb @@ -1,19 +1,9 @@ -require 'html/pipeline' - module Gitlab module Markdown - # HTML filter that replaces commit range references with links. References - # within <pre>, <code>, <a>, and <style> elements are ignored. + # HTML filter that replaces commit range references with links. # # This filter supports cross-project references. - # - # Context options: - # :project (required) - Current project, ignored when reference is - # cross-project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class CommitRangeReferenceFilter < HTML::Pipeline::Filter + class CommitRangeReferenceFilter < ReferenceFilter include CrossProjectReference # Public: Find commit range references in text @@ -42,26 +32,10 @@ module Gitlab # This pattern supports cross-project references. COMMIT_RANGE_PATTERN = /(#{PROJECT_PATTERN}@)?(?<commit_range>\h{6,40}\.{2,3}\h{6,40})/ - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next unless content.match(COMMIT_RANGE_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = commit_range_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(COMMIT_RANGE_PATTERN) do |content| + commit_range_link_filter(content) end - - doc end # Replace commit range references in text with links to compare the commit @@ -82,7 +56,7 @@ module Gitlab url = url_for_commit_range(project, from_id, to_id) title = "Commits #{from_id} through #{to_id}" - klass = "gfm gfm-commit_range #{context[:reference_class]}".strip + klass = reference_class(:commit_range) project_ref += '@' if project_ref @@ -95,10 +69,6 @@ module Gitlab end end - def validate - needs :project - end - def split_commit_range(range) from_id, to_id = range.split(/\.{2,3}/, 2) from_id << "^" if range !~ /\.{3}/ @@ -118,10 +88,6 @@ module Gitlab from: from_id, to: to_id, only_path: context[:only_path]) end - - def project - context[:project] - end end end end diff --git a/lib/gitlab/markdown/commit_reference_filter.rb b/lib/gitlab/markdown/commit_reference_filter.rb index 5697d7d97e7..914eb29dc0c 100644 --- a/lib/gitlab/markdown/commit_reference_filter.rb +++ b/lib/gitlab/markdown/commit_reference_filter.rb @@ -1,19 +1,9 @@ -require 'html/pipeline' - module Gitlab module Markdown - # HTML filter that replaces commit references with links. References within - # <pre>, <code>, <a>, and <style> elements are ignored. + # HTML filter that replaces commit references with links. # # This filter supports cross-project references. - # - # Context options: - # :project (required) - Current project, ignored when reference is - # cross-project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class CommitReferenceFilter < HTML::Pipeline::Filter + class CommitReferenceFilter < ReferenceFilter include CrossProjectReference # Public: Find commit references in text @@ -41,30 +31,10 @@ module Gitlab # This pattern supports cross-project references. COMMIT_PATTERN = /(#{PROJECT_PATTERN}@)?(?<commit>\h{6,40})/ - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next unless content.match(COMMIT_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = commit_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(COMMIT_PATTERN) do |content| + commit_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace commit references in text with links to the commit specified. @@ -81,7 +51,7 @@ module Gitlab url = url_for_commit(project, commit) title = commit.link_title - klass = "gfm gfm-commit #{context[:reference_class]}".strip + klass = reference_class(:commit) project_ref += '@' if project_ref @@ -99,10 +69,6 @@ module Gitlab h.namespace_project_commit_url(project.namespace, project, commit, only_path: context[:only_path]) end - - def project - context[:project] - end end end end diff --git a/lib/gitlab/markdown/cross_project_reference.rb b/lib/gitlab/markdown/cross_project_reference.rb index b2197432caa..c8ba9d1fa46 100644 --- a/lib/gitlab/markdown/cross_project_reference.rb +++ b/lib/gitlab/markdown/cross_project_reference.rb @@ -1,7 +1,7 @@ module Gitlab module Markdown - # Includes shared code for reference filters that support an optional - # cross-project reference. + # Common methods for ReferenceFilters that support an optional cross-project + # reference. module CrossProjectReference NAMING_PATTERN = Gitlab::Regex::NAMESPACE_REGEX_STR PROJECT_PATTERN = "(?<project>#{NAMING_PATTERN}/#{NAMING_PATTERN})" @@ -9,9 +9,9 @@ module Gitlab # Given a cross-project reference string, get the Project record # # Defaults to value of `context[:project]` if: - # - No reference is given - # - Reference given doesn't exist - # - Reference given can't be read by the current user + # * No reference is given OR + # * Reference given doesn't exist OR + # * Reference given can't be read by the current user # # ref - String reference. # diff --git a/lib/gitlab/markdown/external_issue_reference_filter.rb b/lib/gitlab/markdown/external_issue_reference_filter.rb index 87f58b1ae79..3ca8eb7e4a7 100644 --- a/lib/gitlab/markdown/external_issue_reference_filter.rb +++ b/lib/gitlab/markdown/external_issue_reference_filter.rb @@ -1,16 +1,7 @@ -require 'html/pipeline' - module Gitlab module Markdown # HTML filter that replaces external issue tracker references with links. - # References within <pre>, <code>, <a>, and <style> elements are ignored. - # - # Context options: - # :project (required) - Current project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class ExternalIssueReferenceFilter < HTML::Pipeline::Filter + class ExternalIssueReferenceFilter < ReferenceFilter # Public: Find `JIRA-123` issue references in text # # ExternalIssueReferenceFilter.references_in(text) do |match, issue| @@ -31,31 +22,10 @@ module Gitlab # Pattern used to extract `JIRA-123` issue references from text ISSUE_PATTERN = /(?<issue>([A-Z\-]+-)\d+)/ - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next if project.default_issues_tracker? - next unless content.match(ISSUE_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = issue_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(ISSUE_PATTERN) do |content| + issue_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace `JIRA-123` issue references in text with links to the referenced @@ -72,7 +42,7 @@ module Gitlab url = url_for_issue(issue, project, only_path: context[:only_path]) title = "Issue in #{project.external_issue_tracker.title}" - klass = "gfm gfm-issue #{context[:reference_class]}".strip + klass = reference_class(:issue) %(<a href="#{url}" title="#{title}" @@ -80,12 +50,6 @@ module Gitlab end end - # TODO (rspeicher): Duplicates IssueReferenceFilter - def project - context[:project] - end - - # TODO (rspeicher): Duplicates IssueReferenceFilter def url_for_issue(*args) IssuesHelper.url_for_issue(*args) end diff --git a/lib/gitlab/markdown/issue_reference_filter.rb b/lib/gitlab/markdown/issue_reference_filter.rb index ab0420da199..680daaf6a1d 100644 --- a/lib/gitlab/markdown/issue_reference_filter.rb +++ b/lib/gitlab/markdown/issue_reference_filter.rb @@ -1,20 +1,10 @@ -require 'html/pipeline' - module Gitlab module Markdown - # HTML filter that replaces issue references with links. References within - # <pre>, <code>, <a>, and <style> elements are ignored. References to issues - # that do not exist are ignored. + # HTML filter that replaces issue references with links. References to + # issues that do not exist are ignored. # # This filter supports cross-project references. - # - # Context options: - # :project (required) - Current project, ignored when reference is - # cross-project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class IssueReferenceFilter < HTML::Pipeline::Filter + class IssueReferenceFilter < ReferenceFilter include CrossProjectReference # Public: Find `#123` issue references in text @@ -40,31 +30,10 @@ module Gitlab # This pattern supports cross-project references. ISSUE_PATTERN = /#{PROJECT_PATTERN}?\#(?<issue>([a-zA-Z\-]+-)?\d+)/ - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next unless project.default_issues_tracker? - next unless content.match(ISSUE_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = issue_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(ISSUE_PATTERN) do |content| + issue_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace `#123` issue references in text with links to the referenced @@ -79,11 +48,10 @@ module Gitlab project = self.project_from_ref(project_ref) if project.issue_exists?(issue) - # FIXME: Ugly url = url_for_issue(issue, project, only_path: context[:only_path]) title = "Issue: #{title_for_issue(issue, project)}" - klass = "gfm gfm-issue #{context[:reference_class]}".strip + klass = reference_class(:issue) %(<a href="#{url}" title="#{title}" @@ -94,10 +62,6 @@ module Gitlab end end - def project - context[:project] - end - def url_for_issue(*args) IssuesHelper.url_for_issue(*args) end diff --git a/lib/gitlab/markdown/label_reference_filter.rb b/lib/gitlab/markdown/label_reference_filter.rb index 3bb84c50b93..f40b981ba60 100644 --- a/lib/gitlab/markdown/label_reference_filter.rb +++ b/lib/gitlab/markdown/label_reference_filter.rb @@ -1,16 +1,7 @@ -require 'html/pipeline' - module Gitlab module Markdown - # HTML filter that replaces label references with links. References within - # <pre>, <code>, <a>, and <style> elements are ignored. - # - # Context options: - # :project (required) - Current project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class LabelReferenceFilter < HTML::Pipeline::Filter + # HTML filter that replaces label references with links. + class LabelReferenceFilter < ReferenceFilter # Public: Find label references in text # # LabelReferenceFilter.references_in(text) do |match, id, name| @@ -42,30 +33,10 @@ module Gitlab ) }x - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next unless content.match(LABEL_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = label_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(LABEL_PATTERN) do |content| + label_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace label references in text with links to the label specified. @@ -83,7 +54,7 @@ module Gitlab if label = project.labels.find_by(params) url = url_for_label(project, label) - klass = "gfm gfm-label #{context[:reference_class]}".strip + klass = reference_class(:label) %(<a href="#{url}" class="#{klass}">#{render_colored_label(label)}</a>) else @@ -118,10 +89,6 @@ module Gitlab { name: name.tr('\'"', '') } end end - - def project - context[:project] - end end end end diff --git a/lib/gitlab/markdown/merge_request_reference_filter.rb b/lib/gitlab/markdown/merge_request_reference_filter.rb index 96a0c92942d..15f0c09ab00 100644 --- a/lib/gitlab/markdown/merge_request_reference_filter.rb +++ b/lib/gitlab/markdown/merge_request_reference_filter.rb @@ -1,20 +1,10 @@ -require 'html/pipeline' - module Gitlab module Markdown # HTML filter that replaces merge request references with links. References - # within <pre>, <code>, <a>, and <style> elements are ignored. References to - # merge requests that do not exist are ignored. + # to merge requests that do not exist are ignored. # # This filter supports cross-project references. - # - # Context options: - # :project (required) - Current project, ignored when reference is - # cross-project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class MergeRequestReferenceFilter < HTML::Pipeline::Filter + class MergeRequestReferenceFilter < ReferenceFilter include CrossProjectReference # Public: Find `!123` merge request references in text @@ -45,25 +35,9 @@ module Gitlab IGNORE_PARENTS = %w(pre code a style).to_set def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next unless content.match(MERGE_REQUEST_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = merge_request_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(MERGE_REQUEST_PATTERN) do |content| + merge_request_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace `!123` merge request references in text with links to the @@ -79,7 +53,7 @@ module Gitlab if merge_request = project.merge_requests.find_by(iid: id) title = "Merge Request: #{merge_request.title}" - klass = "gfm gfm-merge_request #{context[:reference_class]}".strip + klass = reference_class(:merge_request) url = url_for_merge_request(merge_request, project) @@ -92,10 +66,6 @@ module Gitlab end end - def project - context[:project] - end - # TODO (rspeicher): Cleanup def url_for_merge_request(mr, project) h = Rails.application.routes.url_helpers diff --git a/lib/gitlab/markdown/reference_filter.rb b/lib/gitlab/markdown/reference_filter.rb index 55cb6a4e6bc..5778fd865df 100644 --- a/lib/gitlab/markdown/reference_filter.rb +++ b/lib/gitlab/markdown/reference_filter.rb @@ -7,8 +7,7 @@ module Gitlab # References within <pre>, <code>, <a>, and <style> elements are ignored. # # Context options: - # :project (required) - Current project, ignored when reference is - # cross-project. + # :project (required) - Current project, ignored if reference is cross-project. # :reference_class - Custom CSS class added to reference links. # :only_path - Generate path-only links. # diff --git a/lib/gitlab/markdown/snippet_reference_filter.rb b/lib/gitlab/markdown/snippet_reference_filter.rb index 42f035ce295..193a548af92 100644 --- a/lib/gitlab/markdown/snippet_reference_filter.rb +++ b/lib/gitlab/markdown/snippet_reference_filter.rb @@ -1,18 +1,10 @@ -require 'html/pipeline' - module Gitlab module Markdown - # HTML filter that replaces snippet references with links. References within - # <pre>, <code>, <a>, and <style> elements are ignored. References to + # HTML filter that replaces snippet references with links. References to # snippets that do not exist are ignored. # - # Context options: - # :project (required) - Current project, ignored when reference is - # cross-project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class SnippetReferenceFilter < HTML::Pipeline::Filter + # This filter supports cross-project references. + class SnippetReferenceFilter < ReferenceFilter include CrossProjectReference # Public: Find `$123` snippet references in text @@ -38,30 +30,10 @@ module Gitlab # This pattern supports cross-project references. SNIPPET_PATTERN = /#{PROJECT_PATTERN}?\$(?<snippet>\d+)/ - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if context[:project].nil? - next unless content.match(SNIPPET_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = snippet_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(SNIPPET_PATTERN) do |content| + snippet_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace `$123` snippet references in text with links to the referenced @@ -77,7 +49,7 @@ module Gitlab if snippet = project.snippets.find_by(id: id) title = "Snippet: #{snippet.title}" - klass = "gfm gfm-snippet #{context[:reference_class]}".strip + klass = reference_class(:snippet) url = url_for_snippet(snippet, project) diff --git a/lib/gitlab/markdown/user_reference_filter.rb b/lib/gitlab/markdown/user_reference_filter.rb index 3ac82041ff4..5fc8ed55fe2 100644 --- a/lib/gitlab/markdown/user_reference_filter.rb +++ b/lib/gitlab/markdown/user_reference_filter.rb @@ -1,18 +1,9 @@ -require 'html/pipeline' - module Gitlab module Markdown - # HTML filter that replaces user or group references with links. References - # within <pre>, <code>, <a>, and <style> elements are ignored. + # HTML filter that replaces user or group references with links. # # A special `@all` reference is also supported. - # - # Context options: - # :project (required) - Current project. - # :reference_class - Custom CSS class added to reference links. - # :only_path - Generate path-only links. - # - class UserReferenceFilter < HTML::Pipeline::Filter + class UserReferenceFilter < ReferenceFilter # Public: Find `@user` user references in text # # UserReferenceFilter.references_in(text) do |match, username| @@ -33,30 +24,10 @@ module Gitlab # Pattern used to extract `@user` user references from text USER_PATTERN = /@(?<user>#{Gitlab::Regex::NAMESPACE_REGEX_STR})/ - # Don't look for references in text nodes that are children of these - # elements. - IGNORE_PARENTS = %w(pre code a style).to_set - def call - doc.search('text()').each do |node| - content = node.to_html - - next if project.nil? - next unless content.match(USER_PATTERN) - next if has_ancestor?(node, IGNORE_PARENTS) - - html = user_link_filter(content) - - next if html == content - - node.replace(html) + replace_text_nodes_matching(USER_PATTERN) do |content| + user_link_filter(content) end - - doc - end - - def validate - needs :project end # Replace `@user` user references in text with links to the referenced @@ -70,7 +41,7 @@ module Gitlab project = context[:project] self.class.references_in(text) do |match, user| - klass = "gfm gfm-project_member #{context[:reference_class]}".strip + klass = reference_class(:project_member) if user == 'all' url = link_to_all(project) @@ -94,27 +65,23 @@ module Gitlab end end - def project - context[:project] + private + + def urls + Rails.application.routes.url_helpers end - # TODO (rspeicher): Cleanup def group_url(*args) - h = Rails.application.routes.url_helpers - h.group_url(*args) + urls.group_url(*args) end - # TODO (rspeicher): Cleanup def user_url(*args) - h = Rails.application.routes.url_helpers - h.user_url(*args) + urls.user_url(*args) end - # TODO (rspeicher): Cleanup def link_to_all(project) - h = Rails.application.routes.url_helpers - h.namespace_project_url(project.namespace, project, - only_path: context[:only_path]) + urls.namespace_project_url(project.namespace, project, + only_path: context[:only_path]) end def user_can_reference_group?(group) |