Commit 7781bda9 authored by Douwe Maan's avatar Douwe Maan

Move Markdown/reference logic from Gitlab::Markdown to Banzai

parent 9451db38
Pipeline #529994 failed with stage
......@@ -20,7 +20,7 @@ module GitlabMarkdownHelper
end
user = current_user if defined?(current_user)
gfm_body = Gitlab::Markdown.render(escaped_body, project: @project, current_user: user, pipeline: :single_line)
gfm_body = Banzai.render(escaped_body, project: @project, current_user: user, pipeline: :single_line)
fragment = Nokogiri::HTML::DocumentFragment.parse(gfm_body)
if fragment.children.size == 1 && fragment.children[0].name == 'a'
......@@ -50,7 +50,7 @@ module GitlabMarkdownHelper
context[:project] ||= @project
html = Gitlab::Markdown.render(text, context)
html = Banzai.render(text, context)
context.merge!(
current_user: (current_user if defined?(current_user)),
......@@ -61,7 +61,7 @@ module GitlabMarkdownHelper
ref: @ref
)
Gitlab::Markdown.post_process(html, context)
Banzai.post_process(html, context)
end
def asciidoc(text)
......
......@@ -121,6 +121,6 @@ module IssuesHelper
end
end
# Required for Gitlab::Markdown::IssueReferenceFilter
# Required for Banzai::IssueReferenceFilter
module_function :url_for_issue
end
......@@ -107,6 +107,6 @@ module LabelsHelper
options_from_collection_for_select(grouped_labels, 'name', 'title', params[:label_name])
end
# Required for Gitlab::Markdown::LabelReferenceFilter
# Required for Banzai::LabelReferenceFilter
module_function :render_colored_label, :text_color_for_bg, :escape_once
end
......@@ -23,7 +23,7 @@ module Mentionable
included do
if self < Participable
participant ->(current_user) { mentioned_users(current_user, load_lazy_references: false) }
participant ->(current_user) { mentioned_users(current_user) }
end
end
......@@ -43,9 +43,9 @@ module Mentionable
self
end
def all_references(current_user = self.author, text = nil, load_lazy_references: true)
ext = Gitlab::ReferenceExtractor.new(self.project, current_user, load_lazy_references: load_lazy_references)
def all_references(current_user = self.author, text = nil)
ext = Gitlab::ReferenceExtractor.new(self.project, current_user)
if text
ext.analyze(text)
else
......@@ -59,13 +59,13 @@ module Mentionable
ext
end
def mentioned_users(current_user = nil, load_lazy_references: true)
all_references(current_user, load_lazy_references: load_lazy_references).users
def mentioned_users(current_user = nil)
all_references(current_user).users
end
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
def referenced_mentionables(current_user = self.author, text = nil, load_lazy_references: true)
refs = all_references(current_user, text, load_lazy_references: load_lazy_references)
def referenced_mentionables(current_user = self.author, text = nil)
refs = all_references(current_user, text)
refs = (refs.issues + refs.merge_requests + refs.commits)
# We're using this method instead of Array diffing because that requires
......
......@@ -38,20 +38,21 @@ module Participable
# Be aware that this method makes a lot of sql queries.
# Save result into variable if you are going to reuse it inside same request
def participants(current_user = self.author, load_lazy_references: true)
participants = self.class.participant_attrs.flat_map do |attr|
value =
if attr.respond_to?(:call)
instance_exec(current_user, &attr)
else
send(attr)
end
participants =
Gitlab::ReferenceExtractor.lazily do
self.class.participant_attrs.flat_map do |attr|
value =
if attr.respond_to?(:call)
instance_exec(current_user, &attr)
else
send(attr)
end
participants_for(value, current_user)
end.compact.uniq
if load_lazy_references
participants = Gitlab::Markdown::ReferenceFilter::LazyReference.load(participants).uniq
participants_for(value, current_user)
end.compact.uniq
end
unless Gitlab::ReferenceExtractor.lazy?
participants.select! do |user|
user.can?(:read_project, project)
end
......@@ -64,12 +65,12 @@ module Participable
def participants_for(value, current_user = nil)
case value
when User, Gitlab::Markdown::ReferenceFilter::LazyReference
when User, Banzai::LazyReference
[value]
when Enumerable, ActiveRecord::Relation
value.flat_map { |v| participants_for(v, current_user) }
when Participable
value.participants(current_user, load_lazy_references: false)
value.participants(current_user)
end
end
end
......@@ -88,7 +88,7 @@ class Issue < ActiveRecord::Base
note.all_references(load_lazy_references: false).merge_requests
end.uniq
Gitlab::Markdown::ReferenceFilter::LazyReference.load(references).uniq.sort_by(&:iid)
Banzai::LazyReference.load(references).uniq.sort_by(&:iid)
end
# Reset issue events cache
......
......@@ -373,11 +373,11 @@ class Note < ActiveRecord::Base
end
def contains_emoji_only?
note =~ /\A#{Gitlab::Markdown::EmojiFilter.emoji_pattern}\s?\Z/
note =~ /\A#{Banzai::EmojiFilter.emoji_pattern}\s?\Z/
end
def award_emoji_name
original_name = note.match(Gitlab::Markdown::EmojiFilter.emoji_pattern)[1]
original_name = note.match(Banzai::EmojiFilter.emoji_pattern)[1]
AwardEmoji.normilize_emoji_name(original_name)
end
end
module Banzai
def self.render(text, context = {})
Renderer.render(text, context)
end
def self.render_result(text, context = {})
Renderer.render_result(text, context)
end
def self.post_process(html, context)
Renderer.post_process(html, context)
end
end
require 'banzai'
module Banzai
# Common methods for ReferenceFilters that support an optional cross-project
# reference.
module CrossProjectReference
# Given a cross-project reference string, get the Project record
#
# Defaults to value of `context[:project]` if:
# * No reference is given OR
# * Reference given doesn't exist
#
# ref - String reference.
#
# Returns a Project, or nil if the reference can't be found
def project_from_ref(ref)
return context[:project] unless ref
Project.find_with_namespace(ref)
end
end
end
require 'active_support/core_ext/string/output_safety'
require 'banzai'
module Banzai
module Filter
def self.[](name)
const_get("#{name.to_s.camelize}Filter")
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# Issues, Merge Requests, Snippets, Commits and Commit Ranges share
# similar functionality in reference filtering.
class AbstractReferenceFilter < ReferenceFilter
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML Filter for auto-linking URLs in HTML.
#
# Based on HTML::Pipeline::AutolinkFilter
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces commit range references with links.
#
# This filter supports cross-project references.
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces commit references with links.
#
# This filter supports cross-project references.
......
require 'action_controller'
require 'gitlab/markdown'
require 'banzai'
require 'gitlab_emoji'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces :emoji: with images.
#
# Based on HTML::Pipeline::EmojiFilter
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces external issue tracker references with links.
# References are ignored if the project doesn't use an external issue
# tracker.
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML Filter to add a `rel="nofollow"` attribute to external links
#
class ExternalLinkFilter < HTML::Pipeline::Filter
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces issue references with links. References to
# issues that do not exist are ignored.
#
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces label references with links.
class LabelReferenceFilter < ReferenceFilter
# Public: Find label references in text
......
module Gitlab
module Markdown
require 'banzai'
require 'html/pipeline/filter'
module Banzai
module Filter
class MarkdownFilter < HTML::Pipeline::TextFilter
def initialize(text, context = nil, result = nil)
super text, context, result
......@@ -11,8 +14,8 @@ module Gitlab
html.rstrip!
html
end
private
private
def self.redcarpet_options
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces merge request references with links. References
# to merge requests that do not exist are ignored.
#
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that removes references to records that the current user does
# not have permission to view.
#
......@@ -27,7 +27,7 @@ module Gitlab
def user_can_reference?(node)
if node.has_attribute?('data-reference-filter')
reference_type = node.attr('data-reference-filter')
reference_filter = Gitlab::Markdown.const_get(reference_type)
reference_filter = Banzai::Filter.const_get(reference_type)
reference_filter.user_can_reference?(current_user, node, context)
else
......
require 'active_support/core_ext/string/output_safety'
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# Base class for GitLab Flavored Markdown reference filters.
#
# References within <pre>, <code>, <a>, and <style> elements are ignored.
......@@ -12,27 +12,6 @@ module Gitlab
# :project (required) - Current project, ignored if reference is cross-project.
# :only_path - Generate path-only links.
class ReferenceFilter < HTML::Pipeline::Filter
LazyReference = Struct.new(:klass, :ids) do
def self.load(refs)
lazy_references, values = refs.partition { |ref| ref.is_a?(self) }
lazy_values = lazy_references.group_by(&:klass).flat_map do |klass, refs|
ids = refs.flat_map(&:ids)
klass.where(id: ids)
end
values + lazy_values
end
def load
self.klass.where(id: self.ids)
end
end
def self.[](name)
Markdown.const_get("#{name.to_s.camelize}ReferenceFilter")
end
def self.user_can_reference?(user, node, context)
if node.has_attribute?('data-project')
project_id = node.attr('data-project').to_i
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that gathers all referenced records that the current user has
# permission to view.
#
......@@ -20,7 +20,7 @@ module Gitlab
gather_references(node)
end
load_lazy_references unless context[:load_lazy_references] == false
load_lazy_references unless ReferenceExtractor.lazy?
doc
end
......@@ -31,7 +31,7 @@ module Gitlab
return unless node.has_attribute?('data-reference-filter')
reference_type = node.attr('data-reference-filter')
reference_filter = Gitlab::Markdown.const_get(reference_type)
reference_filter = Banzai::Filter.const_get(reference_type)
return if context[:reference_filter] && reference_filter != context[:reference_filter]
......@@ -47,11 +47,10 @@ module Gitlab
end
end
# Will load all references of one type using one query.
def load_lazy_references
refs = result[:references]
refs.each do |type, values|
refs[type] = ReferenceFilter::LazyReference.load(values)
refs[type] = ReferenceExtractor.lazily(values)
end
end
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that "fixes" relative links to files in a repository.
#
# Context options:
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'html/pipeline/sanitization_filter'
module Gitlab
module Markdown
module Banzai
module Filter
# Sanitize HTML
#
# Extends HTML::Pipeline::SanitizationFilter with a custom whitelist.
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces snippet references with links. References to
# snippets that do not exist are ignored.
#
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'rouge/plugins/redcarpet'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML Filter to highlight fenced code blocks
#
class SyntaxHighlightFilter < HTML::Pipeline::Filter
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that adds an anchor child element to all Headers in a
# document, so that they can be linked to.
#
......
require 'gitlab/markdown'
require 'banzai'
require 'task_list/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# Work around a bug in the default TaskList::Filter that adds a `task-list`
# class to every list element, regardless of whether or not it contains a
# task list.
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that "fixes" relative upload links to files.
# Context options:
# :project (required) - Current project
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces user or group references with links.
#
# A special `@all` reference is also supported.
......
require 'banzai'
module Banzai
class LazyReference
def self.load(refs)
lazy_references, values = refs.partition { |ref| ref.is_a?(self) }
lazy_values = lazy_references.group_by(&:klass).flat_map do |klass, refs|
ids = refs.flat_map(&:ids)
klass.where(id: ids)
end
values + lazy_values
end
attr_reader :klass, :ids
def initialize(klass, ids)
@klass = klass
@ids = Array.wrap(ids).map(&:to_i)
end
def load
self.klass.where(id: self.ids)
end
end
end
require 'banzai'
module Banzai
module Pipeline
def self.[](name)
name ||= :full
const_get("#{name.to_s.camelize}Pipeline")
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
class AsciidocPipeline < Pipeline
module Banzai
module Pipeline
class AsciidocPipeline < BasePipeline
def self.filters
[
Gitlab::Markdown::RelativeLinkFilter
Filter::RelativeLinkFilter
]
end
end
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class AtomPipeline < FullPipeline
def self.transform_context(context)
super(context).merge(
only_path: false,
xhtml: true
super(context).merge(
only_path: false,
xhtml: true
)
end
end
......
require 'banzai'
require 'html/pipeline'
module Banzai
module Pipeline
class BasePipeline
def self.filters
[]
end
def self.transform_context(context)
context
end
def self.html_pipeline
@html_pipeline ||= HTML::Pipeline.new(filters)
end
class << self
%i(call to_document to_html).each do |meth|
define_method(meth) do |text, context|
context = transform_context(context)
html_pipeline.send(meth, text, context)
end
end
end
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
module CombinedPipeline
def self.new(*pipelines)
Class.new(Pipeline) do
Class.new(BasePipeline) do
const_set :PIPELINES, pipelines
def self.pipelines
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class DescriptionPipeline < FullPipeline
def self.transform_context(context)
super(context).m