emoji_filter.rb 2.2 KB
Newer Older
1 2
module Banzai
  module Filter
H
henrik 已提交
3
    # HTML filter that replaces :emoji: and unicode with images.
4 5 6 7 8 9 10 11 12 13
    #
    # 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
14
        search_text_nodes(doc).each do |node|
15 16 17
          content = node.to_html
          next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS)

J
Johan H 已提交
18 19
          next unless content.include?(':') || node.text.match(emoji_unicode_pattern)

E
Eric Eastwood 已提交
20 21
          html = emoji_unicode_element_unicode_filter(content)
          html = emoji_name_element_unicode_filter(html)
22

J
Johan H 已提交
23 24 25 26
          next if html == content

          node.replace(html)
        end
27 28 29
        doc
      end

E
Eric Eastwood 已提交
30
      # Replace :emoji: with corresponding gl-emoji unicode.
31 32 33
      #
      # text - String text to replace :emoji: in.
      #
E
Eric Eastwood 已提交
34 35
      # Returns a String with :emoji: replaced with gl-emoji unicode.
      def emoji_name_element_unicode_filter(text)
36 37
        text.gsub(emoji_pattern) do |match|
          name = $1
E
Eric Eastwood 已提交
38
          Gitlab::Emoji.gl_emoji_tag(name)
39 40 41
        end
      end

E
Eric Eastwood 已提交
42
      # Replace unicode emoji with corresponding gl-emoji unicode.
H
henrik 已提交
43
      #
J
Johan H 已提交
44
      # text - String text to replace unicode emoji in.
H
henrik 已提交
45
      #
E
Eric Eastwood 已提交
46 47
      # Returns a String with unicode emoji replaced with gl-emoji unicode.
      def emoji_unicode_element_unicode_filter(text)
H
henrik 已提交
48
        text.gsub(emoji_unicode_pattern) do |moji|
E
Eric Eastwood 已提交
49 50
          emoji_info = Gitlab::Emoji.emojis_by_moji[moji]
          Gitlab::Emoji.gl_emoji_tag(emoji_info['name'])
H
henrik 已提交
51 52
        end
      end
J
Johan H 已提交
53

54 55 56 57
      # 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
J
Johan H 已提交
58

H
henrik 已提交
59 60 61 62
      # 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
J
Johan H 已提交
63

64 65 66 67 68 69
      private

      def emoji_pattern
        self.class.emoji_pattern
      end

H
henrik 已提交
70 71 72
      def emoji_unicode_pattern
        self.class.emoji_unicode_pattern
      end
73 74 75
    end
  end
end