diff --git a/spec/instance_tag_attrs/tag_spec.cr b/spec/instance_tag_attrs/tag_spec.cr index 080556d..b6b9bc5 100644 --- a/spec/instance_tag_attrs/tag_spec.cr +++ b/spec/instance_tag_attrs/tag_spec.cr @@ -47,12 +47,12 @@ module ToHtml::InstanceTagAttrs::TagSpec expected = <<-HTML
- An image of this + An image of this
- Another image of this + Another image of this
HTML diff --git a/spec/instance_template/void_element_spec.cr b/spec/instance_template/void_element_spec.cr new file mode 100644 index 0000000..a49a722 --- /dev/null +++ b/spec/instance_template/void_element_spec.cr @@ -0,0 +1,66 @@ +require "../spec_helper" + +module ToHtml::InstanceTemplate::VoidElementSpec + class MyView + ToHtml.class_template do + div do + span { "First line" } + br + span { "Second line" } + hr + embed MyVideo.new("/media/video.mp4") + hr + form action: "/inputs", method: "POST" do + input MyInputField.new("foo"), placeholder: "bar" + input type: "submit", name: "submit", value: "Submit" + end + end + end + end + + class MyVideo + getter path : String + + def initialize(@path); end + + ToHtml.instance_tag_attrs do + type = "video/webm" + src = path + width = "250" + height = "200" + end + end + + class MyInputField + getter field_value : String + + def initialize(@field_value); end + + ToHtml.instance_tag_attrs do + type = "text" + name = "name" + value = field_value + end + end + + describe "MyView.to_html" do + it "should render void elements correctly" do + expected = <<-HTML.squish +
+ First line +
+ Second line +
+ +
+
+ + +
+
+ HTML + + MyView.to_html.should eq(expected) + end + end +end diff --git a/src/instance_template.cr b/src/instance_template.cr index fb4c3fc..7106947 100644 --- a/src/instance_template.cr +++ b/src/instance_template.cr @@ -57,7 +57,9 @@ module ToHtml end macro to_html_eval_exp(io, indent_level, break_line = true, &blk) - {% if blk.body.is_a?(Call) && ToHtml::TAG_NAMES.includes?(blk.body.name.stringify) %} + {% if blk.body.is_a?(Call) && ToHtml::VOID_TAG_NAMES.includes?(blk.body.name.stringify) %} + ToHtml.to_html_add_void_tag({{io}}, {{indent_level}}, {{break_line}}, {{blk.body}}) + {% elsif blk.body.is_a?(Call) && ToHtml::TAG_NAMES.includes?(blk.body.name.stringify) %} ToHtml.to_html_add_tag({{io}}, {{indent_level}}, {{break_line}}, {{blk.body}}) {% elsif blk.body.is_a?(Call) && blk.body.name.stringify == "doctype" %} {{io}} << "" @@ -127,12 +129,6 @@ module ToHtml {% else %} %attr_hash = ToHtml::AttributeHash.new - {% if call.named_args %} - {% for named_arg in call.named_args %} - %attr_hash[{{named_arg.name.stringify}}] = {{named_arg.value}}.to_s - {% end %} - {% end %} - {% for arg in call.args %} {% if arg.is_a?(TupleLiteral) %} %attr_hash[{{arg}}.first] = {{arg}}.last @@ -141,6 +137,12 @@ module ToHtml {% end %} {% end %} + {% if call.named_args %} + {% for named_arg in call.named_args %} + %attr_hash[{{named_arg.name.stringify}}] = {{named_arg.value}}.to_s + {% end %} + {% end %} + {{io}} << "<{{call.name}}" {{io}} << " " unless %attr_hash.empty? {{io}} << %attr_hash @@ -168,4 +170,39 @@ module ToHtml {% end %} {% end %} end + + macro to_html_add_void_tag(io, indent_level, break_line, call) + {% if flag?(:to_html_pretty) %} + {{io}} << " " * {{indent_level}} + {% end %} + {% if call.args.empty? && !call.named_args %} + {{io}} << "<{{call.name}}>" + {% elsif call.args.empty? && call.named_args %} + {{io}} << "<{{call.name}} " + {{ call.named_args.map { |a| "#{a.name}=#{a.value}" }.join(" ") }} + ">" + {% else %} + %attr_hash = ToHtml::AttributeHash.new + + {% for arg in call.args %} + {% if arg.is_a?(TupleLiteral) %} + %attr_hash[{{arg}}.first] = {{arg}}.last + {% else %} + {{arg}}.to_html_attrs({{call.name.stringify}}, %attr_hash) + {% end %} + {% end %} + + {% if call.named_args %} + {% for named_arg in call.named_args %} + %attr_hash[{{named_arg.name.stringify}}] = {{named_arg.value}}.to_s + {% end %} + {% end %} + + {{io}} << "<{{call.name}}" + {{io}} << " " unless %attr_hash.empty? + {{io}} << %attr_hash + {{io}} << ">" + {% end %} + {% if flag?(:to_html_pretty) && break_line %} + {{io}} << "\n" + {% end %} + end end diff --git a/src/tag_names.cr b/src/tag_names.cr index 99f75f0..5ba2a68 100644 --- a/src/tag_names.cr +++ b/src/tag_names.cr @@ -3,23 +3,19 @@ module ToHtml a abbr address - area article aside audio b - base bdi bdo blockquote body - br button canvas caption cite code - col colgroup data datalist @@ -32,7 +28,6 @@ module ToHtml dl dt em - embed fieldset figcaption figure @@ -46,23 +41,18 @@ module ToHtml h6 head header - hr html i iframe - img - input ins kbd label legend li - link main map mark menu - meta meter nav noscript @@ -72,7 +62,6 @@ module ToHtml option output p - param picture pre progress @@ -86,7 +75,6 @@ module ToHtml section select small - source span strong style @@ -105,11 +93,26 @@ module ToHtml time title tr - track u ul var video + ] + + VOID_TAG_NAMES = %w[ + area + base + br + col + embed + hr + img + input + link + meta + param + source + track wbr ] end