Browse Source

Make Docs::Parser return the entire document instead of <body>

Thibaut Courouble 9 years ago
parent
commit
6f0214eaf3

+ 4 - 2
lib/docs/core/parser.rb

@@ -9,14 +9,16 @@ module Docs
 
     private
 
+    DOCUMENT_RGX = /\A(?:\s|(?:<!--.*?-->))*<(?:\!doctype|html)/i
+
     def document?
-      @content =~ /\A\s*<(?:\!doctype|html)/i
+      @content =~ DOCUMENT_RGX
     end
 
     def parse_as_document
       document = Nokogiri::HTML.parse @content, nil, 'UTF-8'
       @title = document.at_css('title').try(:content)
-      document.at_css 'body'
+      document
     end
 
     def parse_as_fragment

+ 2 - 0
lib/docs/filters/core/container.rb

@@ -8,6 +8,8 @@ module Docs
 
       if container
         doc.at_css(container) || raise(ContainerNotFound, "element '#{container}' could not be found in the document, url=#{current_url}")
+      elsif doc.name == 'document'
+        doc.at_css('body')
       else
         doc
       end

+ 11 - 5
test/lib/docs/core/parser_test.rb

@@ -14,17 +14,23 @@ class DocsParserTest < MiniTest::Spec
     context "with an HTML fragment" do
       it "returns the fragment" do
         body = '<div>Test</div>'
-        assert_equal body, parser(body).html.inner_html
+        html = parser(body).html
+        assert_equal '#document-fragment', html.name
+        assert_equal body, html.inner_html
       end
     end
 
     context "with an HTML document" do
-      it "returns the <body>" do
-        body = '<!doctype html><meta charset=utf-8><title></title><div>Test</div>'
-        assert_equal '<div>Test</div>', parser(body).html.inner_html
+      it "returns the document" do
+        body = '<!-- foo --> <!doctype html><meta charset=utf-8><title></title><div>Test</div>'
+        html = parser(body).html
+        assert_equal 'document', html.name
+        assert_equal '<div>Test</div>', html.at_css('body').inner_html
 
         body = '<html><meta charset=utf-8><title></title><div>Test</div></html>'
-        assert_equal '<div>Test</div>', parser(body).html.inner_html
+        html = parser(body).html
+        assert_equal 'document', html.name
+        assert_equal '<div>Test</div>', html.at_css('body').inner_html
       end
     end
   end

+ 12 - 2
test/lib/docs/filters/core/container_test.rb

@@ -4,6 +4,7 @@ require 'docs'
 class ContainerFilterTest < MiniTest::Spec
   include FilterTestHelper
   self.filter_class = Docs::ContainerFilter
+  self.filter_type = 'html'
 
   before do
     @body = '<div>Test</div>'
@@ -56,8 +57,17 @@ class ContainerFilterTest < MiniTest::Spec
   end
 
   context "when context[:container] is nil" do
-    it "returns the document" do
-      assert_equal @body, filter_output.inner_html
+    context "and the document is an HTML fragment" do
+      it "returns the document" do
+        assert_equal @body, filter_output.inner_html
+      end
+    end
+
+    context "and the document is an HTML document" do
+      it "returns the <body>" do
+        @body = '<html><meta charset=utf-8><title></title><div>Test</div></html>'
+        assert_equal '<div>Test</div>', filter_output.inner_html
+      end
     end
   end
 end

+ 11 - 2
test/support/filter_test_helper.rb

@@ -3,15 +3,16 @@ module FilterTestHelper
 
   included do
     class_attribute :filter_class
+    class_attribute :filter_type
   end
 
   def filter
-    @filter ||= filter_class.new @body || '', context, result
+    @filter ||= filter_class.new prepare_body(@body || ''), context, result
   end
 
   def filter_output
     @filter_output ||= begin
-      filter.instance_variable_set :@html, @body if @body
+      filter.instance_variable_set :@html, prepare_body(@body) if @body
       filter.call
     end
   end
@@ -41,4 +42,12 @@ module FilterTestHelper
   def link_to(href)
     %(<a href="#{href}">Link</a>)
   end
+
+  def prepare_body(body)
+    if self.class.filter_type == 'html'
+      Docs::Parser.new(body).html
+    else
+      body
+    end
+  end
 end