diff --git a/spec/blueprint/html/renderer_spec.cr b/spec/blueprint/html/renderer_spec.cr new file mode 100644 index 0000000..f941d9a --- /dev/null +++ b/spec/blueprint/html/renderer_spec.cr @@ -0,0 +1,75 @@ +require "../../spec_helper" + +private class Component + include Blueprint::HTML + + private def blueprint(&) + span { yield } + end +end + +describe "renderer" do + it "renders Blueprint::HTML classes" do + actual_html = Blueprint::HTML.build do + render Component do + "Hello" + end + end + + expected_html = "Hello" + + actual_html.should eq expected_html + end + + it "renders Blueprint::HTML instances" do + actual_html = Blueprint::HTML.build do + render Component.new do + "Hello" + end + end + + expected_html = "Hello" + + actual_html.should eq expected_html + end + + it "renders strings" do + actual_html = Blueprint::HTML.build do + render "Hello" + end + + expected_html = "Hello" + + actual_html.should eq expected_html + end + + it "renders blocks" do + actual_html = Blueprint::HTML.build do + render ->{ "He" + "llo" } + end + + expected_html = "Hello" + + actual_html.should eq expected_html + end + + it "renders nothing when renderable is nil" do + actual_html = Blueprint::HTML.build do + render nil + end + + expected_html = "" + + actual_html.should eq expected_html + end + + it "renders objects that respond `to_s`" do + actual_html = Blueprint::HTML.build do + render MarkdownLink.new("Example", "example.com") + end + + expected_html = "[Example](example.com)" + + actual_html.should eq expected_html + end +end diff --git a/src/blueprint/html.cr b/src/blueprint/html.cr index 7485764..de4d2b0 100644 --- a/src/blueprint/html.cr +++ b/src/blueprint/html.cr @@ -10,11 +10,11 @@ module Blueprint::HTML include Blueprint::HTML::BlockRenderer include Blueprint::HTML::BufferAppender include Blueprint::HTML::ComponentRegistrar - include Blueprint::HTML::ComponentRenderer include Blueprint::HTML::ElementRegistrar include Blueprint::HTML::ElementRenderer include Blueprint::HTML::Forms include Blueprint::HTML::Helpers + include Blueprint::HTML::Renderer include Blueprint::HTML::StandardElements include Blueprint::HTML::StyleBuilder include Blueprint::HTML::SVG @@ -65,10 +65,10 @@ module Blueprint::HTML {% if @type.has_method?(:around_render) %} around_render do - blueprint { capture_content { yield } } + blueprint { __capture_content__ { yield } } end {% else %} - blueprint { capture_content { yield } } + blueprint { __capture_content__ { yield } } {% end %} {% if @type.has_method?(:after_render) %} diff --git a/src/blueprint/html/block_renderer.cr b/src/blueprint/html/block_renderer.cr index 4862926..9579c2b 100644 --- a/src/blueprint/html/block_renderer.cr +++ b/src/blueprint/html/block_renderer.cr @@ -1,9 +1,17 @@ module Blueprint::HTML::BlockRenderer - private def capture_content(&) : Nil + private def __capture_content__(&) : Nil buffer_size_before_block_evaluation = @buffer.bytesize content = yield return if buffer_size_before_block_evaluation != @buffer.bytesize # return if something was written to buffer - append_to_buffer(content) + __append_to_buffer__(content) + end + + private def __capture_content__(block : Proc) : Nil + buffer_size_before_block_evaluation = @buffer.bytesize + content = block.call + return if buffer_size_before_block_evaluation != @buffer.bytesize # return if something was written to buffer + + __append_to_buffer__(content) end end diff --git a/src/blueprint/html/buffer_appender.cr b/src/blueprint/html/buffer_appender.cr index 9410e8c..47f6d1b 100644 --- a/src/blueprint/html/buffer_appender.cr +++ b/src/blueprint/html/buffer_appender.cr @@ -1,20 +1,24 @@ module Blueprint::HTML::BufferAppender - private def append_to_buffer(content : String) - escape(content, @buffer) + private def __append_to_buffer__(content : String) + __escape__(content, @buffer) end - private def append_to_buffer(content : SafeObject) + private def __append_to_buffer__(content : Proc) + __capture_content__(content) + end + + private def __append_to_buffer__(content : SafeObject) content.to_s(@buffer) end - private def append_to_buffer(content : Nil) + private def __append_to_buffer__(content : Nil) end - private def append_to_buffer(content) - escape(content.to_s, @buffer) + private def __append_to_buffer__(content) + __escape__(content.to_s, @buffer) end - private def escape(value : String, io : IO) + private def __escape__(value : String, io : IO) ::HTML.escape(value, io) end end diff --git a/src/blueprint/html/component_renderer.cr b/src/blueprint/html/component_renderer.cr deleted file mode 100644 index 9f1e5c8..0000000 --- a/src/blueprint/html/component_renderer.cr +++ /dev/null @@ -1,11 +0,0 @@ -module Blueprint::HTML::ComponentRenderer - private def render(blueprint : Blueprint::HTML) : Nil - blueprint.to_s(@buffer) - end - - private def render(blueprint : Blueprint::HTML, &) : Nil - blueprint.to_s(@buffer) do - yield blueprint - end - end -end diff --git a/src/blueprint/html/element_registrar.cr b/src/blueprint/html/element_registrar.cr index ffa2f55..3fc3070 100644 --- a/src/blueprint/html/element_registrar.cr +++ b/src/blueprint/html/element_registrar.cr @@ -6,7 +6,7 @@ module Blueprint::HTML::ElementRegistrar @buffer << "<{{tag.id}}" __append_attributes__(attributes) @buffer << ">" - capture_content { yield } + __capture_content__ { yield } @buffer << "" end @@ -20,7 +20,7 @@ module Blueprint::HTML::ElementRegistrar @buffer << "<{{tag.id}}" __append_attributes__(attributes) @buffer << ">" - append_to_buffer(__content__) + __append_to_buffer__(__content__) @buffer << "" end end diff --git a/src/blueprint/html/element_renderer.cr b/src/blueprint/html/element_renderer.cr index 56e9f35..162c143 100644 --- a/src/blueprint/html/element_renderer.cr +++ b/src/blueprint/html/element_renderer.cr @@ -4,7 +4,7 @@ module Blueprint::HTML::ElementRenderer @buffer << tag_name __append_attributes__(attributes) @buffer << ">" - capture_content { yield } + __capture_content__ { yield } @buffer << "" @@ -15,7 +15,7 @@ module Blueprint::HTML::ElementRenderer @buffer << tag_name __append_attributes__(attributes) @buffer << ">" - append_to_buffer(__content__) + __append_to_buffer__(__content__) @buffer << "" diff --git a/src/blueprint/html/renderer.cr b/src/blueprint/html/renderer.cr new file mode 100644 index 0000000..5b2f554 --- /dev/null +++ b/src/blueprint/html/renderer.cr @@ -0,0 +1,25 @@ +module Blueprint::HTML::Renderer + private def render(renderable : Blueprint::HTML) : Nil + renderable.to_s(@buffer) + end + + private def render(renderable : Blueprint::HTML.class) : Nil + renderable.new.to_s(@buffer) + end + + private def render(renderable : Blueprint::HTML, &) : Nil + renderable.to_s(@buffer) do + yield renderable + end + end + + private def render(renderable : Blueprint::HTML.class, &) : Nil + renderable.new.to_s(@buffer) do + yield renderable + end + end + + private def render(renderable) : Nil + __append_to_buffer__(renderable) + end +end diff --git a/src/blueprint/html/utils.cr b/src/blueprint/html/utils.cr index c06353a..8f1dd37 100644 --- a/src/blueprint/html/utils.cr +++ b/src/blueprint/html/utils.cr @@ -1,6 +1,6 @@ module Blueprint::HTML::Utils private def plain(content : String) : Nil - append_to_buffer(content) + __append_to_buffer__(content) end private def doctype : Nil @@ -9,7 +9,7 @@ module Blueprint::HTML::Utils private def comment(content) : Nil @buffer << "" end @@ -18,6 +18,6 @@ module Blueprint::HTML::Utils end private def raw(content : SafeObject) : Nil - append_to_buffer(content) + __append_to_buffer__(content) end end