Commit 2c4eef58 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'rs-remove-gitlab-pipeline' into 'master'

Remove html-pipeline-gitlab

Ports the custom emoji filter to the app itself.

See merge request !1781
parents d7f61aff 870969a1
...@@ -88,7 +88,7 @@ gem "six" ...@@ -88,7 +88,7 @@ gem "six"
gem "seed-fu" gem "seed-fu"
# Markup pipeline for GitLab # Markup pipeline for GitLab
gem 'html-pipeline-gitlab', '~> 0.1' gem 'html-pipeline', '~> 1.11.0'
# Markdown to HTML # Markdown to HTML
gem "github-markup" gem "github-markup"
......
...@@ -278,12 +278,6 @@ GEM ...@@ -278,12 +278,6 @@ GEM
html-pipeline (1.11.0) html-pipeline (1.11.0)
activesupport (>= 2) activesupport (>= 2)
nokogiri (~> 1.4) nokogiri (~> 1.4)
html-pipeline-gitlab (0.2.0)
actionpack (~> 4)
gitlab_emoji (~> 0.1)
html-pipeline (~> 1.11.0)
mime-types
sanitize (~> 2.1)
http_parser.rb (0.5.3) http_parser.rb (0.5.3)
httparty (0.13.3) httparty (0.13.3)
json (~> 1.8) json (~> 1.8)
...@@ -717,7 +711,7 @@ DEPENDENCIES ...@@ -717,7 +711,7 @@ DEPENDENCIES
guard-spinach guard-spinach
haml-rails haml-rails
hipchat (~> 1.5.0) hipchat (~> 1.5.0)
html-pipeline-gitlab (~> 0.1) html-pipeline (~> 1.11.0)
httparty httparty
jasmine (= 2.0.2) jasmine (= 2.0.2)
jquery-atwho-rails (~> 0.3.3) jquery-atwho-rails (~> 0.3.3)
......
require 'html/pipeline' require 'html/pipeline'
require 'html/pipeline/gitlab'
module Gitlab module Gitlab
# Custom parser for GitLab-flavored Markdown # Custom parser for GitLab-flavored Markdown
...@@ -61,19 +60,24 @@ module Gitlab ...@@ -61,19 +60,24 @@ module Gitlab
reference_only_path: true reference_only_path: true
) )
markdown_context = { pipeline = HTML::Pipeline.new(filters)
context = {
# SanitizationFilter
whitelist: sanitization_whitelist,
# EmojiFilter
asset_root: Gitlab.config.gitlab.url, asset_root: Gitlab.config.gitlab.url,
asset_host: Gitlab::Application.config.asset_host, asset_host: Gitlab::Application.config.asset_host,
whitelist: sanitization_whitelist,
reference_class: html_options[:class], # ReferenceFilter
only_path: options[:reference_only_path],
current_user: current_user, current_user: current_user,
project: project only_path: options[:reference_only_path],
project: project,
reference_class: html_options[:class]
} }
markdown_pipeline = HTML::Pipeline::Gitlab.new(filters).pipeline result = pipeline.call(text, context)
result = markdown_pipeline.call(text, markdown_context)
save_options = 0 save_options = 0
if options[:xhtml] if options[:xhtml]
...@@ -91,7 +95,7 @@ module Gitlab ...@@ -91,7 +95,7 @@ module Gitlab
private private
# Custom filters for html-pipeline: # Filters used in our pipeline
# #
# SanitizationFilter should come first so that all generated reference HTML # SanitizationFilter should come first so that all generated reference HTML
# goes through untouched. # goes through untouched.
...@@ -101,6 +105,8 @@ module Gitlab ...@@ -101,6 +105,8 @@ module Gitlab
[ [
HTML::Pipeline::SanitizationFilter, HTML::Pipeline::SanitizationFilter,
Gitlab::Markdown::EmojiFilter,
Gitlab::Markdown::UserReferenceFilter, Gitlab::Markdown::UserReferenceFilter,
Gitlab::Markdown::IssueReferenceFilter, Gitlab::Markdown::IssueReferenceFilter,
Gitlab::Markdown::ExternalIssueReferenceFilter, Gitlab::Markdown::ExternalIssueReferenceFilter,
...@@ -109,8 +115,6 @@ module Gitlab ...@@ -109,8 +115,6 @@ module Gitlab
Gitlab::Markdown::CommitRangeReferenceFilter, Gitlab::Markdown::CommitRangeReferenceFilter,
Gitlab::Markdown::CommitReferenceFilter, Gitlab::Markdown::CommitReferenceFilter,
Gitlab::Markdown::LabelReferenceFilter, Gitlab::Markdown::LabelReferenceFilter,
HTML::Pipeline::Gitlab::GitlabEmojiFilter
] ]
end end
......
require 'gitlab_emoji'
require 'html/pipeline/filter'
require 'action_controller'
module Gitlab
module Markdown
# HTML filter that replaces :emoji: with images.
#
# Based on HTML::Pipeline::EmojiFilter
#
# Context options:
# :asset_root
# :asset_host
class EmojiFilter < HTML::Pipeline::Filter
IGNORED_ANCESTOR_TAGS = %w(pre code tt).to_set
def call
doc.search('text()').each do |node|
content = node.to_html
next unless content.include?(':')
next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS)
html = emoji_image_filter(content)
next if html == content
node.replace(html)
end
doc
end
# Replace :emoji: with corresponding images.
#
# text - String text to replace :emoji: in.
#
# Returns a String with :emoji: replaced with images.
def emoji_image_filter(text)
text.gsub(emoji_pattern) do |match|
name = $1
"<img class='emoji' title=':#{name}:' alt=':#{name}:' src='#{emoji_url(name)}' height='20' width='20' align='absmiddle' />"
end
end
private
def emoji_url(name)
emoji_path = "emoji/#{emoji_filename(name)}"
if context[:asset_host]
# Asset host is specified.
url_to_image(emoji_path)
elsif context[:asset_root]
# Gitlab url is specified
File.join(context[:asset_root], url_to_image(emoji_path))
else
# All other cases
url_to_image(emoji_path)
end
end
def url_to_image(image)
ActionController::Base.helpers.url_to_image(image)
end
# Build a regexp that matches all valid :emoji: names.
def self.emoji_pattern
@emoji_pattern ||= /:(#{Emoji.emojis_names.map { |name| Regexp.escape(name) }.join('|')}):/
end
def emoji_pattern
self.class.emoji_pattern
end
def emoji_filename(name)
"#{Emoji.emoji_filename(name)}.png"
end
end
end
end
This diff is collapsed.
require 'spec_helper'
module Gitlab::Markdown
describe EmojiFilter do
def filter(html, contexts = {})
described_class.call(html, contexts)
end
before do
ActionController::Base.asset_host = 'https://foo.com'
end
it 'replaces supported emoji' do
doc = filter('<p>:heart:</p>')
expect(doc.css('img').first.attr('src')).to eq 'https://foo.com/assets/emoji/2764.png'
end
it 'ignores unsupported emoji' do
exp = act = '<p>:foo:</p>'
doc = filter(act)
expect(doc.to_html).to match Regexp.escape(exp)
end
it 'correctly encodes the URL' do
doc = filter('<p>:+1:</p>')
expect(doc.css('img').first.attr('src')).to eq 'https://foo.com/assets/emoji/1F44D.png'
end
it 'matches at the start of a string' do
doc = filter(':+1:')
expect(doc.css('img').size).to eq 1
end
it 'matches at the end of a string' do
doc = filter('This gets a :-1:')
expect(doc.css('img').size).to eq 1
end
it 'matches with adjacent text' do
doc = filter('+1 (:+1:)')
expect(doc.css('img').size).to eq 1
end
it 'matches multiple emoji in a row' do
doc = filter(':see_no_evil::hear_no_evil::speak_no_evil:')
expect(doc.css('img').size).to eq 3
end
it 'has a title attribute' do
doc = filter(':-1:')
expect(doc.css('img').first.attr('title')).to eq ':-1:'
end
it 'has an alt attribute' do
doc = filter(':-1:')
expect(doc.css('img').first.attr('alt')).to eq ':-1:'
end
it 'has an align attribute' do
doc = filter(':8ball:')
expect(doc.css('img').first.attr('align')).to eq 'absmiddle'
end
it 'has an emoji class' do
doc = filter(':cat:')
expect(doc.css('img').first.attr('class')).to eq 'emoji'
end
it 'has height and width attributes' do
doc = filter(':dog:')
img = doc.css('img').first
expect(img.attr('width')).to eq '20'
expect(img.attr('height')).to eq '20'
end
it 'keeps whitespace intact' do
doc = filter('This deserves a :+1:, big time.')
expect(doc.to_html).to match(/^This deserves a <img.+>, big time\.\z/)
end
it 'uses a custom asset_root context' do
root = Gitlab.config.gitlab.url + 'gitlab/root'
doc = filter(':smile:', asset_root: root)
expect(doc.css('img').first.attr('src')).to start_with(root)
end
it 'uses a custom asset_host context' do
ActionController::Base.asset_host = 'https://cdn.example.com'
doc = filter(':frowning:', asset_host: 'https://this-is-ignored-i-guess?')
expect(doc.css('img').first.attr('src')).to start_with('https://cdn.example.com')
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment