mirror of
https://github.com/discourse/discourse.git
synced 2025-06-01 17:40:43 +08:00
FIX: Make Oneboxer#apply insert block Oneboxes correctly (#11449)
It used to insert block Oneboxes inside paragraphs which resulted in invalid HTML. This needed an additional parsing for removal of empty paragraphs and the resulting HTML could still be invalid. This commit ensure that block Oneboxes are inserted correctly, by splitting the paragraph containing the link and putting the block between the two. Paragraphs left with nothing but whitespaces will be removed. Follow up to 7f3a30d79fa63aca063e4186a21f983e23d759e8.
This commit is contained in:
@ -99,32 +99,57 @@ module Oneboxer
|
||||
|
||||
each_onebox_link(doc, extra_paths: extra_paths) do |url, element|
|
||||
onebox, _ = yield(url, element)
|
||||
next if onebox.blank?
|
||||
|
||||
if onebox
|
||||
parsed_onebox = Nokogiri::HTML5::fragment(onebox)
|
||||
next unless parsed_onebox.children.count > 0
|
||||
parsed_onebox = Nokogiri::HTML5::fragment(onebox)
|
||||
next if parsed_onebox.children.blank?
|
||||
|
||||
if element&.parent&.node_name&.downcase == "p" &&
|
||||
element.parent.children.count == 1 &&
|
||||
HTML5_BLOCK_ELEMENTS.include?(parsed_onebox.children[0].node_name.downcase)
|
||||
element = element.parent
|
||||
changed = true
|
||||
|
||||
parent = element.parent
|
||||
if parent&.node_name&.downcase == "p" &&
|
||||
parsed_onebox.children.any? { |child| HTML5_BLOCK_ELEMENTS.include?(child.node_name.downcase) }
|
||||
|
||||
siblings = parent.children
|
||||
element_idx = siblings.find_index(element)
|
||||
before_idx = first_significant_element_index(siblings, element_idx - 1, -1)
|
||||
after_idx = first_significant_element_index(siblings, element_idx + 1, +1)
|
||||
|
||||
if before_idx < 0 && after_idx >= siblings.size
|
||||
parent.replace parsed_onebox
|
||||
elsif before_idx < 0
|
||||
parent.children = siblings[after_idx..siblings.size]
|
||||
parent.add_previous_sibling(parsed_onebox)
|
||||
elsif after_idx >= siblings.size
|
||||
parent.children = siblings[0..before_idx]
|
||||
parent.add_next_sibling(parsed_onebox)
|
||||
else
|
||||
parent_rest = parent.dup
|
||||
|
||||
parent.children = siblings[0..before_idx]
|
||||
parent_rest.children = siblings[after_idx..siblings.size]
|
||||
|
||||
parent.add_next_sibling(parent_rest)
|
||||
parent.add_next_sibling(parsed_onebox)
|
||||
end
|
||||
|
||||
changed = true
|
||||
element.swap parsed_onebox.to_html
|
||||
end
|
||||
end
|
||||
|
||||
# strip empty <p> elements
|
||||
doc.css("p").each do |p|
|
||||
if p.children.empty? && doc.children.count > 1
|
||||
p.remove
|
||||
else
|
||||
element.replace parsed_onebox
|
||||
end
|
||||
end
|
||||
|
||||
Result.new(doc, changed)
|
||||
end
|
||||
|
||||
def self.first_significant_element_index(elements, index, step)
|
||||
while index >= 0 && index < elements.size &&
|
||||
(elements[index].node_name.downcase == "br" ||
|
||||
(elements[index].node_name.downcase == "text" && elements[index].to_html.strip.blank?))
|
||||
index = index + step
|
||||
end
|
||||
|
||||
index
|
||||
end
|
||||
|
||||
def self.is_previewing?(user_id)
|
||||
Discourse.redis.get(preview_key(user_id)) == "1"
|
||||
end
|
||||
|
Reference in New Issue
Block a user