FIX: support for generating excerpt when nesting <details> blocks

This commit is contained in:
Régis Hanol 2018-01-22 19:17:35 +01:00
parent f06f7161ea
commit cbb321658f
2 changed files with 49 additions and 21 deletions

View File

@ -18,6 +18,7 @@ class ExcerptParser < Nokogiri::XML::SAX::Document
@keep_onebox_source = options[:keep_onebox_source] == true @keep_onebox_source = options[:keep_onebox_source] == true
@remap_emoji = options[:remap_emoji] == true @remap_emoji = options[:remap_emoji] == true
@start_excerpt = false @start_excerpt = false
@in_details_depth = 0
@summary_contents = "" @summary_contents = ""
@detail_contents = "" @detail_contents = ""
end end
@ -91,14 +92,15 @@ class ExcerptParser < Nokogiri::XML::SAX::Document
when "aside" when "aside"
attributes = Hash[*attributes.flatten] attributes = Hash[*attributes.flatten]
unless @keep_onebox_source && attributes['class'].include?('onebox') unless @keep_onebox_source && attributes['class'].include?('onebox')
@in_quote = true @in_quote = true
end end
when 'article' when 'article'
if @keep_onebox_source && attributes.include?(['class', 'onebox-body']) if @keep_onebox_source && attributes.include?(['class', 'onebox-body'])
@in_quote = true @in_quote = true
end end
when "div", "span" when "div", "span"
if attributes.include?(["class", "excerpt"]) if attributes.include?(["class", "excerpt"])
@excerpt = "" @excerpt = ""
@ -110,13 +112,18 @@ class ExcerptParser < Nokogiri::XML::SAX::Document
include_tag("span", attributes) include_tag("span", attributes)
@in_spoiler = true @in_spoiler = true
end end
when "details" when "details"
@detail_contents = "" @detail_contents = "" if @in_details_depth == 0
@in_details = true @in_details_depth += 1
when "summary" when "summary"
if @in_details_depth == 1 && !@in_summary
@summary_contents = "" @summary_contents = ""
@in_summary = true @in_summary = true
end end
end
end end
def end_element(name) def end_element(name)
@ -135,16 +142,17 @@ class ExcerptParser < Nokogiri::XML::SAX::Document
when "aside" when "aside"
@in_quote = false @in_quote = false
when "details" when "details"
@in_details = false @in_details_depth -= 1
if @in_details_depth == 0
full = "<details><summary>#{clean(@summary_contents)}</summary>#{clean(@detail_contents)}</details>" full = "<details><summary>#{clean(@summary_contents)}</summary>#{clean(@detail_contents)}</details>"
if @current_length + full.length > @length if @current_length + full.length > @length
@excerpt << "<details class='disabled'><summary>#{@summary_contents[0..@length]}</summary></details>" @excerpt << "<details class='disabled'><summary>#{@summary_contents[0..@length]}</summary></details>"
else else
@excerpt << full @excerpt << full
end end
end
when "summary" when "summary"
@in_summary = false @in_summary = false if @in_details_depth == 1
when "div", "span" when "div", "span"
throw :done if @start_excerpt throw :done if @start_excerpt
characters("</span>", false, false, false) if @in_spoiler characters("</span>", false, false, false) if @in_spoiler
@ -161,7 +169,7 @@ class ExcerptParser < Nokogiri::XML::SAX::Document
# we call length on this so might as well ensure we have a string # we call length on this so might as well ensure we have a string
string = string.to_s string = string.to_s
if @in_details if @in_details_depth > 0
if @in_summary if @in_summary
@summary_contents << string @summary_contents << string
else else

View File

@ -0,0 +1,20 @@
require "rails_helper"
require "excerpt_parser"
describe ExcerptParser do
it "handles nested <details> blocks" do
html = <<~HTML
<details>
<summary>FOO</summary>
<details>
<summary>BAR</summary>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ultrices, ex bibendum vestibulum vestibulum, mi velit pulvinar risus, sed consequat eros libero in eros. Fusce luctus mattis mauris, vitae semper lorem sodales quis. Donec pellentesque lacus ac ante aliquam, tincidunt iaculis risus interdum. In ullamcorper cursus massa ut lacinia. Donec quis diam finibus, rutrum odio eu, maximus leo. Nulla facilisi. Nullam suscipit quam et bibendum sagittis. Praesent sollicitudin neque at luctus ornare. Maecenas tristique dapibus risus, ac dictum ipsum gravida aliquam. Phasellus vehicula eu arcu sed imperdiet. Vestibulum ornare eros a nisi faucibus vehicula. Quisque congue placerat nulla, nec finibus nulla ultrices vitae. Quisque ac mi sem. Curabitur eu porttitor justo. Etiam dignissim in orci iaculis congue. Donec tempus cursus orci, a placerat elit varius nec.</p>
</details>
</details>
HTML
expect(ExcerptParser.get_excerpt(html, 200, strip_links: true)).to eq(%{<details class='disabled'><summary>FOO</summary></details>})
end
end