diff --git a/CHANGELOG b/CHANGELOG index 9e193132ac2..16b05d1d972 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -34,6 +34,7 @@ v 8.13.0 (unreleased) - Simplify Mentionable concern instance methods - Fix permission for setting an issue's due date - API: Multi-file commit !6096 (mahcsig) + - Unicode emoji are now converted to images - Revert "Label list shows all issues (opened or closed) with that label" - Expose expires_at field when sharing project on API - Fix VueJS template tags being rendered in code comments diff --git a/lib/banzai/filter/emoji_filter.rb b/lib/banzai/filter/emoji_filter.rb index 23ae6dfc79a..a8c1ca0c60a 100644 --- a/lib/banzai/filter/emoji_filter.rb +++ b/lib/banzai/filter/emoji_filter.rb @@ -14,15 +14,16 @@ module Banzai search_text_nodes(doc).each do |node| content = node.to_html next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS) - if content.include?(':') || node.text.match(emoji_unicode_pattern) - html = emoji_name_image_filter(content) - html = emoji_unicode_image_filter(html) - next if html == content - node.replace(html) - end + next unless content.include?(':') || node.text.match(emoji_unicode_pattern) + + html = emoji_name_image_filter(content) + html = emoji_unicode_image_filter(html) + + next if html == content + + node.replace(html) end - doc end @@ -34,31 +35,35 @@ module Banzai def emoji_name_image_filter(text) text.gsub(emoji_pattern) do |match| name = $1 - "" + emoji_image_tag(name, emoji_url(name)) end end - - # Replace unicode emojis with corresponding images if they exist. + # Replace unicode emoji with corresponding images if they exist. # - # text - String text to replace unicode emojis in. + # text - String text to replace unicode emoji in. # - # Returns a String with unicode emojis replaced with images. - + # Returns a String with unicode emoji replaced with images. def emoji_unicode_image_filter(text) text.gsub(emoji_unicode_pattern) do |moji| - "" + emoji_image_tag(Gitlab::Emoji.emojis_by_moji[moji]['name'], emoji_unicode_url(moji)) end end + + def emoji_image_tag(emoji_name, emoji_url) + "" + end + # Build a regexp that matches all valid :emoji: names. def self.emoji_pattern @emoji_pattern ||= /:(#{Gitlab::Emoji.emojis_names.map { |name| Regexp.escape(name) }.join('|')}):/ end + # Build a regexp that matches all valid unicode emojis names. def self.emoji_unicode_pattern @emoji_unicode_pattern ||= /(#{Gitlab::Emoji.emojis_unicodes.map { |moji| Regexp.escape(moji) }.join('|')})/ - end + private def emoji_url(name) @@ -80,13 +85,10 @@ module Banzai emoji_unicode_path = emoji_unicode_filename(moji) if context[:asset_host] - # Asset host is specified. url_to_image(emoji_unicode_path) elsif context[:asset_root] - # Gitlab url is specified File.join(context[:asset_root], url_to_image(emoji_unicode_path)) else - # All other cases url_to_image(emoji_unicode_path) end end @@ -102,6 +104,7 @@ module Banzai def emoji_filename(name) "#{Gitlab::Emoji.emoji_filename(name)}.png" end + def emoji_unicode_pattern self.class.emoji_unicode_pattern end diff --git a/lib/gitlab/emoji.rb b/lib/gitlab/emoji.rb index 803b0c2d057..bbbca8acc40 100644 --- a/lib/gitlab/emoji.rb +++ b/lib/gitlab/emoji.rb @@ -9,16 +9,19 @@ module Gitlab def emojis_by_moji Gemojione.index.instance_variable_get(:@emoji_by_moji) end + def emojis_unicodes - emojis_by_moji.keys.sort + emojis_by_moji.keys end + def emojis_names - emojis.keys.sort + emojis.keys end def emoji_filename(name) emojis[name]["unicode"] end + def emoji_unicode_filename(moji) emojis_by_moji[moji]["unicode"] end diff --git a/spec/lib/banzai/filter/emoji_filter_spec.rb b/spec/lib/banzai/filter/emoji_filter_spec.rb index 475160bb5ec..c8e62f528df 100644 --- a/spec/lib/banzai/filter/emoji_filter_spec.rb +++ b/spec/lib/banzai/filter/emoji_filter_spec.rb @@ -16,10 +16,12 @@ describe Banzai::Filter::EmojiFilter, lib: true do doc = filter('
:heart:
') expect(doc.css('img').first.attr('src')).to eq 'https://foo.com/assets/2764.png' end + it 'replaces supported unicode emoji' do doc = filter('❤️
') expect(doc.css('img').first.attr('src')).to eq 'https://foo.com/assets/2764.png' end + it 'ignores unsupported emoji' do exp = act = ':foo:
' doc = filter(act) @@ -162,4 +164,18 @@ describe Banzai::Filter::EmojiFilter, lib: true do 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 + + it 'uses a custom asset_root context' do + root = Gitlab.config.gitlab.url + 'gitlab/root' + + doc = filter("'🎱'", 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("'🎱'", asset_host: 'https://this-is-ignored-i-guess?') + expect(doc.css('img').first.attr('src')).to start_with('https://cdn.example.com') + end end