summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2022-11-09 14:21:57 +0100
committerClaire <claire.github-309c@sitedethib.com>2022-11-14 11:20:41 +0100
commit2dd8f977e84b67ed073a932accd2fbf4d2f38f3a (patch)
tree9a3850298c71c097e6befa4d558f97839c78ee44
parent2db06e1d089404844b632b3a2164c4bd3af24424 (diff)
Fix emoji substitution not applying only to text nodes in backend code
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
-rw-r--r--app/lib/emoji_formatter.rb68
1 files changed, 30 insertions, 38 deletions
diff --git a/app/lib/emoji_formatter.rb b/app/lib/emoji_formatter.rb
index 194849c23da..a9785d5f90c 100644
--- a/app/lib/emoji_formatter.rb
+++ b/app/lib/emoji_formatter.rb
@@ -23,48 +23,40 @@ class EmojiFormatter
def to_s
return html if custom_emojis.empty? || html.blank?
- i = -1
- tag_open_index = nil
- inside_shortname = false
- shortname_start_index = -1
- invisible_depth = 0
- last_index = 0
- result = ''.dup
-
- while i + 1 < html.size
- i += 1
-
- if invisible_depth.zero? && inside_shortname && html[i] == ':'
- inside_shortname = false
- shortcode = html[shortname_start_index + 1..i - 1]
- char_after = html[i + 1]
-
- next unless (char_after.nil? || !DISALLOWED_BOUNDING_REGEX.match?(char_after)) && (emoji = emoji_map[shortcode])
-
- result << html[last_index..shortname_start_index - 1] if shortname_start_index.positive?
- result << image_for_emoji(shortcode, emoji)
- last_index = i + 1
- elsif tag_open_index && html[i] == '>'
- tag = html[tag_open_index..i]
- tag_open_index = nil
-
- if invisible_depth.positive?
- invisible_depth += count_tag_nesting(tag)
- elsif tag == '<span class="invisible">'
- invisible_depth = 1
+ tree = Nokogiri::HTML.fragment(html)
+ tree.xpath('./text()|.//text()[not(ancestor[@class="invisible"])]').to_a.each do |node|
+ i = -1
+ inside_shortname = false
+ shortname_start_index = -1
+ last_index = 0
+ text = node.content
+ result = Nokogiri::XML::NodeSet.new(tree.document)
+
+ while i + 1 < text.size
+ i += 1
+
+ if inside_shortname && text[i] == ':'
+ inside_shortname = false
+ shortcode = text[shortname_start_index + 1..i - 1]
+ char_after = text[i + 1]
+
+ next unless (char_after.nil? || !DISALLOWED_BOUNDING_REGEX.match?(char_after)) && (emoji = emoji_map[shortcode])
+
+ result << Nokogiri::XML::Text.new(text[last_index..shortname_start_index - 1], tree.document) if shortname_start_index.positive?
+ result << Nokogiri::HTML.fragment(image_for_emoji(shortcode, emoji))
+
+ last_index = i + 1
+ elsif text[i] == ':' && (i.zero? || !DISALLOWED_BOUNDING_REGEX.match?(text[i - 1]))
+ inside_shortname = true
+ shortname_start_index = i
end
- elsif html[i] == '<'
- tag_open_index = i
- inside_shortname = false
- elsif !tag_open_index && html[i] == ':' && (i.zero? || !DISALLOWED_BOUNDING_REGEX.match?(html[i - 1]))
- inside_shortname = true
- shortname_start_index = i
end
- end
- result << html[last_index..-1]
+ result << Nokogiri::XML::Text.new(text[last_index..-1], tree.document)
+ node.replace(result)
+ end
- result.html_safe # rubocop:disable Rails/OutputSafety
+ tree.to_html.html_safe # rubocop:disable Rails/OutputSafety
end
private