2018-07-23 09:32:32 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-01-23 11:21:12 +00:00
|
|
|
# Generated HTML is transformed back to GFM by app/assets/javascripts/behaviors/markdown/nodes/emoji.js
|
2015-12-15 14:51:16 +00:00
|
|
|
module Banzai
|
|
|
|
module Filter
|
2016-10-11 13:41:10 +00:00
|
|
|
# HTML filter that replaces :emoji: and unicode with images.
|
2015-04-16 21:38:01 +00:00
|
|
|
#
|
|
|
|
# Based on HTML::Pipeline::EmojiFilter
|
|
|
|
class EmojiFilter < HTML::Pipeline::Filter
|
|
|
|
IGNORED_ANCESTOR_TAGS = %w(pre code tt).to_set
|
2020-10-20 18:08:54 +00:00
|
|
|
IGNORE_UNICODE_EMOJIS = %w(™ © ®).freeze
|
2015-04-16 21:38:01 +00:00
|
|
|
|
|
|
|
def call
|
2021-06-01 21:10:06 +00:00
|
|
|
doc.xpath('descendant-or-self::text()').each do |node|
|
2015-04-16 21:38:01 +00:00
|
|
|
content = node.to_html
|
|
|
|
next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS)
|
|
|
|
|
2016-10-11 14:27:09 +00:00
|
|
|
next unless content.include?(':') || node.text.match(emoji_unicode_pattern)
|
|
|
|
|
2017-02-28 04:44:34 +00:00
|
|
|
html = emoji_unicode_element_unicode_filter(content)
|
|
|
|
html = emoji_name_element_unicode_filter(html)
|
2015-04-16 21:38:01 +00:00
|
|
|
|
2016-10-11 14:27:09 +00:00
|
|
|
next if html == content
|
|
|
|
|
|
|
|
node.replace(html)
|
|
|
|
end
|
2015-04-16 21:38:01 +00:00
|
|
|
doc
|
|
|
|
end
|
|
|
|
|
2017-02-28 04:44:34 +00:00
|
|
|
# Replace :emoji: with corresponding gl-emoji unicode.
|
2015-04-16 21:38:01 +00:00
|
|
|
#
|
|
|
|
# text - String text to replace :emoji: in.
|
|
|
|
#
|
2017-02-28 04:44:34 +00:00
|
|
|
# Returns a String with :emoji: replaced with gl-emoji unicode.
|
|
|
|
def emoji_name_element_unicode_filter(text)
|
2015-04-16 21:38:01 +00:00
|
|
|
text.gsub(emoji_pattern) do |match|
|
2020-09-03 09:08:20 +00:00
|
|
|
name = Regexp.last_match(1)
|
2017-02-28 04:44:34 +00:00
|
|
|
Gitlab::Emoji.gl_emoji_tag(name)
|
2015-04-16 21:38:01 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-02-28 04:44:34 +00:00
|
|
|
# Replace unicode emoji with corresponding gl-emoji unicode.
|
2016-10-11 13:41:10 +00:00
|
|
|
#
|
2016-10-11 14:27:09 +00:00
|
|
|
# text - String text to replace unicode emoji in.
|
2016-10-11 13:41:10 +00:00
|
|
|
#
|
2017-02-28 04:44:34 +00:00
|
|
|
# Returns a String with unicode emoji replaced with gl-emoji unicode.
|
|
|
|
def emoji_unicode_element_unicode_filter(text)
|
2016-10-11 13:41:10 +00:00
|
|
|
text.gsub(emoji_unicode_pattern) do |moji|
|
2017-02-28 04:44:34 +00:00
|
|
|
emoji_info = Gitlab::Emoji.emojis_by_moji[moji]
|
|
|
|
Gitlab::Emoji.gl_emoji_tag(emoji_info['name'])
|
2016-10-11 13:41:10 +00:00
|
|
|
end
|
|
|
|
end
|
2016-10-11 14:27:09 +00:00
|
|
|
|
2016-07-19 13:06:39 +00:00
|
|
|
# Build a regexp that matches all valid :emoji: names.
|
|
|
|
def self.emoji_pattern
|
2017-04-25 10:06:24 +00:00
|
|
|
@emoji_pattern ||=
|
2018-01-27 05:35:53 +00:00
|
|
|
%r{(?<=[^[:alnum:]:]|\n|^)
|
2017-04-25 10:06:24 +00:00
|
|
|
:(#{Gitlab::Emoji.emojis_names.map { |name| Regexp.escape(name) }.join('|')}):
|
2018-01-27 05:35:53 +00:00
|
|
|
(?=[^[:alnum:]:]|$)}x
|
2016-07-19 13:06:39 +00:00
|
|
|
end
|
2016-10-11 14:27:09 +00:00
|
|
|
|
2016-10-11 13:41:10 +00:00
|
|
|
# Build a regexp that matches all valid unicode emojis names.
|
|
|
|
def self.emoji_unicode_pattern
|
2020-10-20 18:08:54 +00:00
|
|
|
@emoji_unicode_pattern ||=
|
|
|
|
begin
|
|
|
|
filtered_emojis = Gitlab::Emoji.emojis_unicodes - IGNORE_UNICODE_EMOJIS
|
|
|
|
/(#{filtered_emojis.map { |moji| Regexp.escape(moji) }.join('|')})/
|
|
|
|
end
|
2016-10-11 13:41:10 +00:00
|
|
|
end
|
2016-10-11 14:27:09 +00:00
|
|
|
|
2015-04-16 21:38:01 +00:00
|
|
|
private
|
|
|
|
|
|
|
|
def emoji_pattern
|
|
|
|
self.class.emoji_pattern
|
|
|
|
end
|
|
|
|
|
2016-10-11 13:41:10 +00:00
|
|
|
def emoji_unicode_pattern
|
|
|
|
self.class.emoji_unicode_pattern
|
|
|
|
end
|
2015-04-16 21:38:01 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|