Skip to content
Browse files

self closing based on tag name definitions

  • Loading branch information...
1 parent 3c5719f commit d6410b23d411a3ddca33ae7a63b39897e871d56f @maca committed Jul 29, 2012
Showing with 227 additions and 22 deletions.
  1. +15 −6 lib/tiny.rb
  2. +154 −0 lib/tiny/html_tags.rb
  3. +1 −1 spec/erb_spec.rb
  4. +1 −1 spec/haml_spec.rb
  5. +56 −14 spec/pure_ruby_spec.rb
View
21 lib/tiny.rb
@@ -2,6 +2,7 @@
require 'haml'
require 'rack/utils'
require 'tiny/version'
+require 'tiny/html_tags'
require 'ext/tilt/template'
module Tiny
@@ -146,7 +147,6 @@ def output_buffer
class Tag
attr_reader :tag_name, :attrs
-
def initialize tag_name, attrs = {}
@tag_name, @attrs = tag_name, attrs
end
@@ -167,18 +167,27 @@ def tag_attributes
end
def render scope, &block
+ return void_tag if tag_void?
+
content = scope.tiny_capture(self, &block) if block_given?
- scope.tiny_concat render_tag(content)
+ scope.tiny_concat content_tag(content)
+ end
+
+ def tag_void?
+ HTMLTags.void_tags.include? tag_name
end
- def render_tag content
+ def void_tag
+ "<#{tag_name}#{tag_attributes} />"
+ end
+
+ def content_tag content
if content
content.gsub!(/^(?!\s*$)/, " ")
content.gsub!(/\A(?!$)|(?<!^|\n)\z/, "\n")
- "<#{tag_name}#{tag_attributes}>#{content}</#{tag_name}>"
- else
- "<#{tag_name}#{tag_attributes} />"
end
+
+ "<#{tag_name}#{tag_attributes}>#{content}</#{tag_name}>"
end
end
View
154 lib/tiny/html_tags.rb
@@ -0,0 +1,154 @@
+module Tiny
+ module HTMLTags
+ @content_tags = []
+ @void_tags = []
+
+ class << self
+ def tag_def name, void = false
+ void ? @void_tags.push(name) : @content_tags.push(name)
+ end
+
+ def content_tags
+ @content_tags
+ end
+
+ def void_tags
+ @void_tags
+ end
+ end
+
+ tag_def 'area', :void
+ tag_def 'base', :void
+ tag_def 'br', :void
+ tag_def 'col', :void
+ tag_def 'hr', :void
+ tag_def 'img', :void
+ tag_def 'input', :void
+ tag_def 'link', :void
+ tag_def 'meta', :void
+ tag_def 'param', :void
+
+ # html 5 tags
+ tag_def 'embed', :void
+ tag_def 'article'
+ tag_def 'aside'
+ tag_def 'audio'
+ tag_def 'bdi'
+ tag_def 'canvas'
+ tag_def 'command'
+ tag_def 'datalist'
+ tag_def 'details'
+ tag_def 'figcaption'
+ tag_def 'figure'
+ tag_def 'header'
+ tag_def 'hgroup'
+ tag_def 'keygen'
+ tag_def 'mark'
+ tag_def 'meter'
+ tag_def 'nav'
+ tag_def 'output'
+ tag_def 'progress'
+ tag_def 'section'
+ tag_def 'source'
+ tag_def 'summary'
+ tag_def 'track'
+ tag_def 'video'
+ tag_def 'wbr'
+
+ # common tags
+ tag_def 'a'
+ tag_def 'abbr'
+ tag_def 'address'
+
+ tag_def 'b'
+ tag_def 'bdo'
+ tag_def 'big'
+ tag_def 'blockquote'
+ tag_def 'body'
+ tag_def 'button'
+
+ tag_def 'caption'
+ tag_def 'cite'
+ tag_def 'code'
+ tag_def 'colgroup'
+
+ tag_def 'dd'
+ tag_def 'del'
+ tag_def 'dfn'
+ tag_def 'div'
+ tag_def 'dl'
+ tag_def 'dt'
+
+ tag_def 'em'
+
+ tag_def 'fieldset'
+ tag_def 'footer'
+ tag_def 'form'
+
+ tag_def 'h1'
+ tag_def 'h2'
+ tag_def 'h3'
+ tag_def 'h4'
+ tag_def 'h5'
+ tag_def 'h6'
+ tag_def 'head'
+ tag_def 'html'
+
+ tag_def 'i'
+ tag_def 'iframe'
+ tag_def 'ins'
+
+ tag_def 'kbd'
+
+ tag_def 'label'
+ tag_def 'legend'
+ tag_def 'li'
+
+ tag_def 'map'
+
+ tag_def 'noscript'
+
+ tag_def 'object'
+ tag_def 'ol'
+ tag_def 'optgroup'
+ tag_def 'option'
+
+ tag_def 'p'
+ tag_def 'pre'
+
+ tag_def 'q'
+
+ tag_def 'rp'
+ tag_def 'rt'
+ tag_def 'ruby'
+
+ tag_def 's'
+ tag_def 'samp'
+ tag_def 'script'
+ tag_def 'select'
+ tag_def 'small'
+ tag_def 'span'
+ tag_def 'strike'
+ tag_def 'strong'
+ tag_def 'style'
+ tag_def 'sub'
+ tag_def 'sup'
+
+ tag_def 'table'
+ tag_def 'tbody'
+ tag_def 'td'
+ tag_def 'textarea'
+ tag_def 'tfoot'
+ tag_def 'th'
+ tag_def 'thead'
+ tag_def 'time'
+ tag_def 'title'
+ tag_def 'tr'
+ tag_def 'tt'
+
+ tag_def 'u'
+ tag_def 'ul'
+
+ tag_def 'var'
+ end
+end
View
2 spec/erb_spec.rb
@@ -61,7 +61,7 @@
<% end %>
ERB
end.render(self)
- output.should == "<ul>\n <li />\n</ul>"
+ output.should == "<ul>\n <li></li></ul>"
end
end
View
2 spec/haml_spec.rb
@@ -69,7 +69,7 @@
= tag(:li)
HAML
end.render(self)
- output.should == "<ul>\n <li />\n</ul>\n"
+ output.should == "<ul>\n <li></li>\n</ul>\n"
end
it 'shuould concat with newlines after text' do
View
70 spec/pure_ruby_spec.rb
@@ -21,35 +21,33 @@
end
it 'should not use blank attribute values' do
- output = tag(:li, :class => [], :id => nil) { text 'Hello' }
- output.should =~ /<li>/
+ output = tag(:li, :class => [], :id => nil)
+ output.should == "<li></li>"
end
it 'should not emit value for an atribute value of true' do
output = tag(:li, 'data-something' => true)
- output.should == "<li data-something />"
+ output.should == "<li data-something></li>"
end
it 'should not allow passing text without #text' do
output = tag(:li) { 'Hello' }
output.should == '<li></li>'
end
- describe 'multiple classes' do
- before do
- @output = tag(:li, :class => %w(item in-stock)) { text 'Hello' }
- end
- it { output.should have_css 'li.item' }
- it { output.should have_css 'li.in-stock' }
+ it 'should output multiple classes passing an array' do
+ output = tag(:li, :class => %w(item in-stock))
+ output.should == '<li class="item in-stock"></li>'
end
- describe 'safe and unsafe' do
+ describe 'safety' do
it 'should escape attribute html' do
- tag(:a, :href => '<script>').should == '<a href="&lt;script&gt;" />'
+ tag(:a, :href => '<script>').should == '<a href="&lt;script&gt;"></a>'
+ tag(:a, :href => 'art&copy').should == '<a href="art&amp;copy"></a>'
end
it 'should allow html in attribute' do
- tag(:a, :href => raw('<script>')).should == '<a href="<script>" />'
+ tag(:a, :href => raw('<script>')).should == '<a href="<script>"></a>'
end
end
end
@@ -143,7 +141,7 @@
describe 'outside content block' do
it 'should not concatenate contiguous calls' do
tag(:span)
- tag(:a).should == '<a />'
+ tag(:a).should == '<a></a>'
end
end
end
@@ -158,14 +156,16 @@
@output = tag(:li){ text! '&<>' }
@output.should =~ /&<>/
end
+
+ it 'should concat text'
end
describe 'formatting' do
it 'shuould concat with newlines and indentation' do
output = tag(:ul) do
tag (:li)
end
- output.should == "<ul>\n <li />\n</ul>"
+ output.should == "<ul>\n <li></li>\n</ul>"
end
it 'shuould concat with newlines after text' do
@@ -219,4 +219,46 @@
end
end
end
+
+ describe 'tag closing' do
+ describe 'void tags' do
+ it 'should define void tags' do
+ Tiny::HTMLTags.void_tags.should == %w(area base br col hr img input link meta param embed)
+ end
+
+ Tiny::HTMLTags.void_tags.each do |tag_name|
+ describe tag_name do
+ it 'sould autoclose' do
+ tag(tag_name).should == "<#{tag_name} />"
+ end
+
+ it 'should omit content' do
+ tag(tag_name){ text 'hi' }.should == "<#{tag_name} />"
+ end
+ end
+ end
+ end
+
+ describe 'content tags' do
+ it 'should define content tags' do
+ tags = %w(
+ article aside audio bdi canvas command datalist details
+ figcaption figure header hgroup keygen mark meter nav output progress
+ section source summary track video wbr a abbr address b bdo big
+ blockquote body button caption cite code colgroup dd del dfn div dl dt
+ em fieldset footer form h1 h2 h3 h4 h5 h6 head html i iframe ins kbd
+ label legend li map noscript object ol optgroup option p pre q rp rt
+ ruby s samp script select small span strike strong style sub sup table
+ tbody td textarea tfoot th thead time title tr tt u ul var
+ )
+ Tiny::HTMLTags.content_tags.should == tags
+ end
+
+ Tiny::HTMLTags.content_tags.each do |tag_name|
+ it "should not autoclose #{tag_name} if not empty" do
+ tag(tag_name).should == "<#{tag_name}></#{tag_name}>"
+ end
+ end
+ end
+ end
end

0 comments on commit d6410b2

Please sign in to comment.
Something went wrong with that request. Please try again.