diff --git a/Gemfile.lock b/Gemfile.lock index c82a4fb1..f8ab66bc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,7 @@ PATH activesupport (>= 5.2, < 8) cable_ready (~> 5.0) nokogiri (~> 1.0) + nokogiri-html5-inference rack (>= 2, < 4) railties (>= 5.2, < 8) redis (>= 4.0, < 6.0) @@ -127,6 +128,8 @@ GEM racc (~> 1.4) nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) + nokogiri-html5-inference (0.1.1) + nokogiri (~> 1.14) parallel (1.22.1) parser (3.2.1.0) ast (~> 2.4.1) diff --git a/lib/stimulus_reflex.rb b/lib/stimulus_reflex.rb index 35e9d001..94d3d170 100644 --- a/lib/stimulus_reflex.rb +++ b/lib/stimulus_reflex.rb @@ -8,6 +8,7 @@ require "action_cable" require "action_view" require "nokogiri" +require "nokogiri/html5/inference" require "cable_ready" require "stimulus_reflex/version" require "stimulus_reflex/open_struct_fix" diff --git a/lib/stimulus_reflex/html/document_fragment.rb b/lib/stimulus_reflex/html/document_fragment.rb index ea1b6a5b..846e5dda 100644 --- a/lib/stimulus_reflex/html/document_fragment.rb +++ b/lib/stimulus_reflex/html/document_fragment.rb @@ -4,7 +4,11 @@ module StimulusReflex module HTML class DocumentFragment < Document def parsing_class - Nokogiri + Nokogiri::HTML5::Inference + end + + def document_element + @document end end end diff --git a/stimulus_reflex.gemspec b/stimulus_reflex.gemspec index 5aed3d02..2e0b3789 100644 --- a/stimulus_reflex.gemspec +++ b/stimulus_reflex.gemspec @@ -50,6 +50,7 @@ Gem::Specification.new do |gem| gem.add_dependency "nokogiri", "~> 1.0" gem.add_dependency "rack", ">= 2", "< 4" gem.add_dependency "redis", ">= 4.0", "< 6.0" + gem.add_dependency "nokogiri-html5-inference" gem.add_development_dependency "bundler", "~> 2.0" gem.add_development_dependency "magic_frozen_string_literal", "~> 1.2" diff --git a/test/broadcasters/selector_broadcaster_test.rb b/test/broadcasters/selector_broadcaster_test.rb index ded2b4e8..bcb54a79 100644 --- a/test/broadcasters/selector_broadcaster_test.rb +++ b/test/broadcasters/selector_broadcaster_test.rb @@ -71,9 +71,7 @@ class SelectorBroadcasterTest < StimulusReflex::BroadcasterTestCase "operations" => [ { "selector" => "html", - # Nokogiri automatically adds a `` tag for the encoding - # See. https://github.com/sparklemotion/nokogiri/blob/6ea1449926ce97648bb2f7401c9e4fdcb0e261ba/lib/nokogiri/html4/document.rb#L34-L35 - "html" => "Test
bar
baz
", + "html" => "Test
bar
baz
", "payload" => {}, "childrenOnly" => true, "permanentAttributeName" => nil, diff --git a/test/html/document_fragment_test.rb b/test/html/document_fragment_test.rb index f4bccc26..777ac892 100644 --- a/test/html/document_fragment_test.rb +++ b/test/html/document_fragment_test.rb @@ -109,13 +109,68 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal "1", fragment.inner_html.squish end + test "should properly parse " do + html = "
" + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "
", fragment.to_html.squish + assert_equal "
", fragment.outer_html.squish + end + + test "should properly parse with and with " do + html = "" + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "", fragment.to_html.squish + assert_equal "", fragment.outer_html.squish + end + + test "should properly parse
" do + html = "
Caption
" + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "
Caption
", fragment.to_html.squish + assert_equal "
Caption
", fragment.outer_html.squish + end + + test "should properly parse with and " do + html = "
" + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "
", fragment.to_html.squish + assert_equal "
", fragment.outer_html.squish + end + + test "should properly parse with and and s" do + html = "
1
1
" + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "
1
1
", fragment.to_html.squish + assert_equal "
1
1
", fragment.outer_html.squish + end + + test "should properly parse
1
1
1
1
1
1
with " do html = "" fragment = StimulusReflex::HTML::DocumentFragment.new(html) assert_equal "", fragment.to_html.squish assert_equal "", fragment.outer_html.squish - assert_equal "", fragment.inner_html.squish end test "should properly parse " do @@ -124,7 +179,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal "", fragment.to_html.squish assert_equal "", fragment.outer_html.squish - assert_equal "", fragment.inner_html.squish end test "should properly parse " do @@ -133,7 +187,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal "", fragment.to_html.squish assert_equal "", fragment.outer_html.squish - assert_equal "", fragment.inner_html.squish end test "should properly parse ", fragment.to_html.squish assert_equal "", fragment.outer_html.squish - assert_equal "Caption", fragment.inner_html.squish end test "should properly parse and " do @@ -157,7 +209,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal %(), fragment.to_html.squish assert_equal %(), fragment.outer_html.squish - assert_equal %(), fragment.inner_html.squish end test "should properly parse " do @@ -176,7 +227,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal "", fragment.to_html.squish assert_equal "", fragment.outer_html.squish - assert_equal "
  • 1
  • ", fragment.inner_html.squish end test "should properly parse
  • " do @@ -185,7 +235,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal "
  • 1
  • ", fragment.to_html.squish assert_equal "
  • 1
  • ", fragment.outer_html.squish - assert_equal "1", fragment.inner_html.squish end test "should properly parse two siblings input" do @@ -193,8 +242,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase
    @@ -202,9 +251,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - # assert_equal 2, fragment.document_element.at_css("input").children.length - assert_equal %(
    ), fragment.to_html.squish - assert_equal %(
    ), fragment.outer_html.squish + assert_equal %(
    ), fragment.to_html.squish + assert_equal %(
    ), fragment.outer_html.squish end test "should properly parse after non-closed " do @@ -212,7 +260,7 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase
    - + After Input
    @@ -230,8 +278,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %( some text), fragment.to_html.squish - assert_equal %( some text), fragment.outer_html.squish + assert_equal %( some text), fragment.to_html.squish + assert_equal %( some text), fragment.outer_html.squish end test "non-closing tag" do @@ -327,8 +375,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %( ), fragment.to_html.squish - assert_equal %( ), fragment.outer_html.squish + assert_equal %( ), fragment.to_html.squish + assert_equal %( ), fragment.outer_html.squish end test " alongside inside with doctype and content" do @@ -345,8 +393,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %( Title

    Header

    ), fragment.to_html.squish - assert_equal %( Title

    Header

    ), fragment.outer_html.squish + assert_equal %( Title

    Header

    ), fragment.to_html.squish + assert_equal %( Title

    Header

    ), fragment.outer_html.squish end test " alongside inside with content" do @@ -363,8 +411,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(

    Hello World

    ), fragment.to_html.squish - assert_equal %(

    Hello World

    ), fragment.outer_html.squish + assert_equal %(

    Hello World

    ), fragment.to_html.squish + assert_equal %(

    Hello World

    ), fragment.outer_html.squish end test "" do @@ -452,8 +500,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(<div data-reflex-permanent></div>), fragment.to_html.squish - assert_equal %(<div data-reflex-permanent></div>), fragment.outer_html.squish + assert_equal %(<div data-reflex-permanent=""></div>), fragment.to_html.squish + assert_equal %(<div data-reflex-permanent=""></div>), fragment.outer_html.squish end test "boolean attribute with attribute name as value on <div> tag" do @@ -472,8 +520,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(<input required>), fragment.to_html.squish - assert_equal %(<input required>), fragment.outer_html.squish + assert_equal %(<input required="">), fragment.to_html.squish + assert_equal %(<input required="">), fragment.outer_html.squish end test "boolean attribute on closed <input> tag" do @@ -482,8 +530,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(<input required>), fragment.to_html.squish - assert_equal %(<input required>), fragment.outer_html.squish + assert_equal %(<input required="">), fragment.to_html.squish + assert_equal %(<input required="">), fragment.outer_html.squish end test "boolean attribute with attribute name as value on non-closed <input> tag" do @@ -514,8 +562,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(<!-- Hello Comment --> <div data-attribute="present" some-attribute checked>Content</div>), fragment.to_html.squish - assert_equal %(<!-- Hello Comment --> <div data-attribute="present" some-attribute checked>Content</div>), fragment.outer_html.squish + assert_equal %(<!-- Hello Comment --> <div data-attribute="present" some-attribute="" checked="">Content</div>), fragment.to_html.squish + assert_equal %(<!-- Hello Comment --> <div data-attribute="present" some-attribute="" checked="">Content</div>), fragment.outer_html.squish end test "should parse comments with quotes" do @@ -526,8 +574,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(<!-- Hello "Comment" --> <div data-attribute="present" some-attribute checked>Content</div>), fragment.to_html.squish - assert_equal %(<!-- Hello "Comment" --> <div data-attribute="present" some-attribute checked>Content</div>), fragment.outer_html.squish + assert_equal %(<!-- Hello "Comment" --> <div data-attribute="present" some-attribute="" checked="">Content</div>), fragment.to_html.squish + assert_equal %(<!-- Hello "Comment" --> <div data-attribute="present" some-attribute="" checked="">Content</div>), fragment.outer_html.squish end test "case-sensitive attributes" do @@ -535,8 +583,8 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %(<div data-someThing="value">1</div>), fragment.to_html.squish - assert_equal %(<div data-someThing="value">1</div>), fragment.outer_html.squish + assert_equal %(<div data-something="value">1</div>), fragment.to_html.squish + assert_equal %(<div data-something="value">1</div>), fragment.outer_html.squish end test "case-sensitive <svg> tags" do @@ -546,7 +594,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal %(<svg><feSpecularLighting><fePointLight></fePointLight></feSpecularLighting></svg>), fragment.to_html.squish assert_equal %(<svg><feSpecularLighting><fePointLight></fePointLight></feSpecularLighting></svg>), fragment.outer_html.squish - assert_equal %(<feSpecularLighting><fePointLight></fePointLight></feSpecularLighting>), fragment.inner_html.squish end test "non-standard HTML attributes (Alpine.js-like)" do @@ -573,7 +620,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase outer_container = %(<div id="container"> #{inner_container} </div>) assert_equal raw_html.squish, fragment.to_html.squish - assert_equal outer_title.squish, fragment.inner_html.squish assert_equal raw_html.squish, fragment.outer_html.squish refute fragment.match("body").present? @@ -644,12 +690,11 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase outer_p = %(<p>#{inner_p}</p>) inner_body = %(<h1>Home#index</h1> #{outer_p}) outer_body = %(<body id="body"> #{inner_body} </body>) - inner_html = %(<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>StimulusReflex Test #{outer_body}) - outer_html = %( #{inner_html} ) + inner_html = %( StimulusReflex Test #{outer_body}) + outer_html = %(#{inner_html}) - assert_equal outer_html, fragment.to_html.squish - assert_equal outer_html, fragment.outer_html.squish - assert_equal inner_html, fragment.inner_html.squish + assert_equal "#{outer_html}", fragment.to_html.squish + assert_equal "#{outer_html}", fragment.outer_html.squish assert_equal outer_html, fragment.match("html").to_html.squish assert_equal outer_html, fragment.match("html").outer_html.squish diff --git a/test/html/document_test.rb b/test/html/document_test.rb index f9f3e8e6..d60a344a 100644 --- a/test/html/document_test.rb +++ b/test/html/document_test.rb @@ -52,8 +52,8 @@ class StimulusReflex::HTML::DocumentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::DocumentFragment.new(html) - assert_equal %( ), fragment.to_html.squish - assert_equal %( ), fragment.outer_html.squish + assert_equal %( ), fragment.to_html.squish + assert_equal %( ), fragment.outer_html.squish end test " alongside inside with doctype and content" do @@ -70,8 +70,8 @@ class StimulusReflex::HTML::DocumentTest < ActiveSupport::TestCase ) fragment = StimulusReflex::HTML::Document.new(html) - assert_equal %( Title

    Header

    ), fragment.to_html.squish - assert_equal %( Title

    Header

    ), fragment.outer_html.squish + assert_equal %( Title

    Header

    ), fragment.to_html.squish + assert_equal %( Title

    Header

    ), fragment.outer_html.squish end test "should extract a document of the HTML" do
    " do + html = "
    12
    " + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "
    12
    ", fragment.to_html.squish + assert_equal "
    12
    ", fragment.outer_html.squish + end + + test "should properly parse with " do + html = "
    12
    " + fragment = StimulusReflex::HTML::DocumentFragment.new(html) + + assert_equal "
    12
    ", fragment.to_html.squish + assert_equal "
    12
    ", fragment.outer_html.squish + end + test "should properly parse
    12
    12
    12
    12
    12
    12
    12
    12
    12
    12
    " do @@ -142,7 +195,6 @@ class StimulusReflex::HTML::DocumentFragmentTest < ActiveSupport::TestCase assert_equal "CaptionCaption