1
0
Fork 0
forked from fedi/mastodon

Fix emoji substitution not applying only to text nodes in backend code (#20641)

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
Claire 2022-11-14 20:26:21 +01:00 committed by GitHub
parent 625e086996
commit 71c92d3f56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -23,48 +23,40 @@ class EmojiFormatter
def to_s def to_s
return html if custom_emojis.empty? || html.blank? return html if custom_emojis.empty? || html.blank?
tree = Nokogiri::HTML.fragment(html)
tree.xpath('./text()|.//text()[not(ancestor[@class="invisible"])]').to_a.each do |node|
i = -1 i = -1
tag_open_index = nil
inside_shortname = false inside_shortname = false
shortname_start_index = -1 shortname_start_index = -1
invisible_depth = 0
last_index = 0 last_index = 0
result = ''.dup text = node.content
result = Nokogiri::XML::NodeSet.new(tree.document)
while i + 1 < html.size while i + 1 < text.size
i += 1 i += 1
if invisible_depth.zero? && inside_shortname && html[i] == ':' if inside_shortname && text[i] == ':'
inside_shortname = false inside_shortname = false
shortcode = html[shortname_start_index + 1..i - 1] shortcode = text[shortname_start_index + 1..i - 1]
char_after = html[i + 1] char_after = text[i + 1]
next unless (char_after.nil? || !DISALLOWED_BOUNDING_REGEX.match?(char_after)) && (emoji = emoji_map[shortcode]) 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 << Nokogiri::XML::Text.new(text[last_index..shortname_start_index - 1], tree.document) if shortname_start_index.positive?
result << image_for_emoji(shortcode, emoji) result << Nokogiri::HTML.fragment(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? last_index = i + 1
invisible_depth += count_tag_nesting(tag) elsif text[i] == ':' && (i.zero? || !DISALLOWED_BOUNDING_REGEX.match?(text[i - 1]))
elsif tag == '<span class="invisible">'
invisible_depth = 1
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 inside_shortname = true
shortname_start_index = i shortname_start_index = i
end end
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 end
private private