mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 00:32:52 +08:00
FIX: Do not add empty use/svg tags in ExcerptParser (#19969)
There was an issue where if hashtag-cooked HTML was sent to the ExcerptParser without the keep_svg option, we would end up with empty </use> and </svg> tags on the parts of the excerpt where the hashtag was, in this case when a post push notification was sent. Fixed this, and also added a way to only display a plaintext version of the hashtag for cases like this via PrettyText#excerpt.
This commit is contained in:
@ -23,7 +23,14 @@ class PostAlerter
|
|||||||
topic_title: post.topic.title,
|
topic_title: post.topic.title,
|
||||||
topic_id: post.topic.id,
|
topic_id: post.topic.id,
|
||||||
excerpt:
|
excerpt:
|
||||||
excerpt || post.excerpt(400, text_entities: true, strip_links: true, remap_emoji: true),
|
excerpt ||
|
||||||
|
post.excerpt(
|
||||||
|
400,
|
||||||
|
text_entities: true,
|
||||||
|
strip_links: true,
|
||||||
|
remap_emoji: true,
|
||||||
|
plain_hashtags: true,
|
||||||
|
),
|
||||||
username: username || post.username,
|
username: username || post.username,
|
||||||
post_url: post_url,
|
post_url: post_url,
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ module Email
|
|||||||
correct_first_body_margin
|
correct_first_body_margin
|
||||||
correct_footer_style
|
correct_footer_style
|
||||||
correct_footer_style_highlight_first
|
correct_footer_style_highlight_first
|
||||||
decorate_hashtags
|
strip_hashtag_link_icons
|
||||||
reset_tables
|
reset_tables
|
||||||
|
|
||||||
html_lang = SiteSetting.default_locale.sub("_", "-")
|
html_lang = SiteSetting.default_locale.sub("_", "-")
|
||||||
@ -396,7 +396,7 @@ module Email
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def decorate_hashtags
|
def strip_hashtag_link_icons
|
||||||
@fragment
|
@fragment
|
||||||
.search(".hashtag-cooked")
|
.search(".hashtag-cooked")
|
||||||
.each do |hashtag|
|
.each do |hashtag|
|
||||||
|
@ -181,10 +181,10 @@ class ExcerptParser < Nokogiri::XML::SAX::Document
|
|||||||
when "div", "span"
|
when "div", "span"
|
||||||
throw :done if @start_excerpt
|
throw :done if @start_excerpt
|
||||||
when "svg"
|
when "svg"
|
||||||
characters("</svg>", truncate: false, count_it: false, encode: false)
|
characters("</svg>", truncate: false, count_it: false, encode: false) if @keep_svg
|
||||||
@in_svg = false
|
@in_svg = false
|
||||||
when "use"
|
when "use"
|
||||||
characters("</use>", truncate: false, count_it: false, encode: false)
|
characters("</use>", truncate: false, count_it: false, encode: false) if @keep_svg
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -469,10 +469,21 @@ module PrettyText
|
|||||||
DiscourseEvent.trigger(:reduce_excerpt, doc, options)
|
DiscourseEvent.trigger(:reduce_excerpt, doc, options)
|
||||||
strip_image_wrapping(doc)
|
strip_image_wrapping(doc)
|
||||||
strip_oneboxed_media(doc)
|
strip_oneboxed_media(doc)
|
||||||
|
|
||||||
|
if SiteSetting.enable_experimental_hashtag_autocomplete && options[:plain_hashtags]
|
||||||
|
convert_hashtag_links_to_plaintext(doc)
|
||||||
|
end
|
||||||
|
|
||||||
html = doc.to_html
|
html = doc.to_html
|
||||||
ExcerptParser.get_excerpt(html, max_length, options)
|
ExcerptParser.get_excerpt(html, max_length, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.convert_hashtag_links_to_plaintext(doc)
|
||||||
|
doc
|
||||||
|
.css("a.hashtag-cooked")
|
||||||
|
.each { |hashtag| hashtag.replace("##{hashtag.attributes["data-slug"]}") }
|
||||||
|
end
|
||||||
|
|
||||||
def self.strip_links(string)
|
def self.strip_links(string)
|
||||||
return string if string.blank?
|
return string if string.blank?
|
||||||
|
|
||||||
|
@ -1209,6 +1209,22 @@ RSpec.describe PostAlerter do
|
|||||||
expect(JSON.parse(body)).to eq(payload)
|
expect(JSON.parse(body)).to eq(payload)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not have invalid HTML in the excerpt when enable_experimental_hashtag_autocomplete is enabled" do
|
||||||
|
SiteSetting.enable_experimental_hashtag_autocomplete = true
|
||||||
|
Fabricate(:category, slug: "random")
|
||||||
|
Jobs.run_immediately!
|
||||||
|
body = nil
|
||||||
|
|
||||||
|
stub_request(:post, "https://site2.com/push").to_return do |request|
|
||||||
|
body = request.body
|
||||||
|
{ status: 200, body: "OK" }
|
||||||
|
end
|
||||||
|
create_post_with_alerts(user: user, raw: "this, @eviltrout, is a test with #random")
|
||||||
|
expect(JSON.parse(body)["notifications"][0]["excerpt"]).to eq(
|
||||||
|
"this, @eviltrout, is a test with #random",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
context "with push subscriptions" do
|
context "with push subscriptions" do
|
||||||
before do
|
before do
|
||||||
Fabricate(:push_subscription, user: evil_trout)
|
Fabricate(:push_subscription, user: evil_trout)
|
||||||
|
Reference in New Issue
Block a user