summaryrefslogtreecommitdiff
path: root/lib/gitlab/markdown
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2015-04-14 18:34:01 -0400
committerRobert Speicher <rspeicher@gmail.com>2015-04-20 13:01:45 -0400
commitb3b8fc6c8a559b743d98577d07bc45a884e242a3 (patch)
tree72ffcac0405cbe78f90581f15010babc9e728f15 /lib/gitlab/markdown
parent6189b24fddae66e1c2bb71c496301ff85701cb90 (diff)
downloadgitlab-ce-b3b8fc6c8a559b743d98577d07bc45a884e242a3.tar.gz
DRY up reference filters using ReferenceFilter base class
Diffstat (limited to 'lib/gitlab/markdown')
-rw-r--r--lib/gitlab/markdown/commit_range_reference_filter.rb44
-rw-r--r--lib/gitlab/markdown/commit_reference_filter.rb44
-rw-r--r--lib/gitlab/markdown/cross_project_reference.rb10
-rw-r--r--lib/gitlab/markdown/external_issue_reference_filter.rb44
-rw-r--r--lib/gitlab/markdown/issue_reference_filter.rb48
-rw-r--r--lib/gitlab/markdown/label_reference_filter.rb43
-rw-r--r--lib/gitlab/markdown/merge_request_reference_filter.rb40
-rw-r--r--lib/gitlab/markdown/reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/snippet_reference_filter.rb40
-rw-r--r--lib/gitlab/markdown/user_reference_filter.rb59
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)