Skip to content

Commit ea7a870

Browse files
committed
handle partials
1 parent cccf353 commit ea7a870

File tree

2 files changed

+19
-18
lines changed

2 files changed

+19
-18
lines changed

lib/theo-rails/theo.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ def self.attribute_value(name = 'value')
99
ATTRIBUTE = /(?:(?<=\s)(?:(?:#{ATTRIBUTE_NAME.source}\s*=\s*#{attribute_value})|#{ATTRIBUTE_NAME.source}))/
1010
DYNAMIC_ATTRIBUTE = /(?:(?<=\s)(?:(?:#{ATTRIBUTE_NAME.source}\s*%=\s*#{attribute_value('dynvalue')})|(?:#{ATTRIBUTE_NAME.source}%)))/
1111
RESERVED_ATTRIBUTE_NAME = %w[alias and begin break case class def do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield].to_set
12+
# Source: https://meiert.com/blog/boolean-attributes-of-html/
13+
BOOLEAN_ATTRIBUTE_NAME = %w[allowfullscreen alpha async autofocus autoplay checked controls default defer disabled formnovalidate inert ismap itemscope loop multiple muted nomodule novalidate open playsinline readonly required reversed selected shadowrootclonable shadowrootcustomelementregistry shadowrootdelegatesfocus shadowrootserializable]
1214
CLASS_ATTRIBUTE = /(?:\s+class\s*=\s*#{attribute_value})/
1315
STYLE_ATTRIBUTE = /(?:\s+style\s*=\s*#{attribute_value})/
1416
ATTRIBUTES = /(?<attrs>(?:\s+#{ATTRIBUTE.source})*)/
@@ -56,9 +58,7 @@ def process(source)
5658
remove_attributes += [class_attribute[0]]
5759
value = "(#{value}).to_s + ' #{class_attribute[:value]}'"
5860
end
59-
end
60-
61-
if name == 'style'
61+
elsif name == 'style'
6262
style_attribute = STYLE_ATTRIBUTE.match(tag)
6363

6464
if style_attribute
@@ -67,9 +67,9 @@ def process(source)
6767
end
6868
end
6969

70-
next "#{name}=\"<%= #{value} %>\"" if is_partial
70+
next "<% if #{value} %>#{name}<% end %>" if BOOLEAN_ATTRIBUTE_NAME.include?(name) unless is_partial
7171

72-
"<% if (_val = #{value}) %>#{name}=\"<%= _val %>\"<% end %>"
72+
"#{name}=\"<%= #{value} %>\""
7373
end
7474

7575
remove_attributes.each { |remove_attribute| tag = tag.sub(remove_attribute, '') }

spec/theo-rails/theo_spec.rb

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,43 +80,44 @@ class AvatarComponent < Component
8080
it 'evaluates dynamic attribute' do
8181
theo = %(<a href%="2 % 2 == 0 ? '/even' : '/odd'">Link</a>)
8282

83-
expect(to_erb(theo)).to eq %(<a <% if (_val = 2 % 2 == 0 ? '/even' : '/odd') %>href="<%= _val %>"<% end %>>Link</a>)
83+
expect(to_erb(theo)).to eq %(<a href="<%= 2 % 2 == 0 ? '/even' : '/odd' %>">Link</a>)
8484
expect(to_html(theo)).to eq %(<a href="/even">Link</a>)
8585
end
8686

8787
it 'evaluates shortened dynamic attribute' do
8888
theo = %(<a href%>Link</a>)
8989

90-
expect(to_erb(theo)).to eq %(<a <% if (_val = href) %>href="<%= _val %>"<% end %>>Link</a>)
90+
expect(to_erb(theo)).to eq %(<a href="<%= href %>">Link</a>)
9191
expect(to_html(theo, href: '/one')).to eq %(<a href="/one">Link</a>)
9292
end
9393

9494
it 'evaluates shortened reserved dynamic attribute' do
9595
theo = %(<div class%>Content</div>)
9696

97-
expect(to_erb(theo)).to eq %(<div <% if (_val = binding.local_variable_get('class')) %>class="<%= _val %>"<% end %>>Content</div>)
97+
expect(to_erb(theo)).to eq %(<div class="<%= binding.local_variable_get('class') %>">Content</div>)
9898
expect(to_html(theo, class: 'red')).to eq %(<div class="red">Content</div>)
9999
end
100100

101101
it 'merges class attribute' do
102102
theo = %(<span class="red" data="dummy" class%="1 + 1">Text</span>)
103103

104-
expect(to_erb(theo)).to eq %(<span data="dummy" <% if (_val = (1 + 1).to_s + ' red') %>class="<%= _val %>"<% end %>>Text</span>)
104+
expect(to_erb(theo)).to eq %(<span data="dummy" class="<%= (1 + 1).to_s + ' red' %>">Text</span>)
105105
expect(to_html(theo)).to eq %(<span data="dummy" class="2 red">Text</span>)
106106
end
107107

108108
it 'merges style attribute' do
109109
theo = %(<span style="color: red" data="dummy" style%="'opacity: ' + (1.0/2).to_s">Text</span>)
110110

111-
expect(to_erb(theo)).to eq %(<span data="dummy" <% if (_val = ('opacity: ' + (1.0/2).to_s).to_s + '; color: red') %>style="<%= _val %>"<% end %>>Text</span>)
111+
expect(to_erb(theo)).to eq %(<span data="dummy" style="<%= ('opacity: ' + (1.0/2).to_s).to_s + '; color: red' %>">Text</span>)
112112
expect(to_html(theo)).to eq %(<span data="dummy" style="opacity: 0.5; color: red">Text</span>)
113113
end
114114

115-
it 'erases dynamic attribute with nil value in normal tags' do
116-
theo = %(<div title%="nil">Content</div>)
115+
it 'handles boolean attributes in HTML tags' do
116+
theo = %(<input disabled%="locked">)
117117

118-
expect(to_erb(theo)).to eq %(<div <% if (_val = nil) %>title="<%= _val %>"<% end %>>Content</div>)
119-
expect(to_html(theo)).to eq %(<div >Content</div>)
118+
expect(to_erb(theo)).to eq %(<input <% if locked %>disabled<% end %>>)
119+
expect(to_html(theo, locked: true)).to eq %(<input disabled>)
120+
expect(to_html(theo, locked: false)).to eq %(<input >)
120121
end
121122

122123
it 'ignores trim symbols' do
@@ -127,10 +128,10 @@ class AvatarComponent < Component
127128
end
128129

129130
it 'ignores % percent in attribute value' do
130-
theo = %(<span style="transform: translateX(calc(-100% - 48px))" data-test%="false">Text</span>)
131+
theo = %(<span style="transform: translateX(calc(-100% - 48px))" data-test%="true">Text</span>)
131132

132-
expect(to_erb(theo)).to eq %(<span style="transform: translateX(calc(-100% - 48px))" <% if (_val = false) %>data-test="<%= _val %>"<% end %>>Text</span>)
133-
expect(to_html(theo)).to eq %(<span style="transform: translateX(calc(-100% - 48px))" >Text</span>)
133+
expect(to_erb(theo)).to eq %(<span style="transform: translateX(calc(-100% - 48px))" data-test="<%= true %>">Text</span>)
134+
expect(to_html(theo)).to eq %(<span style="transform: translateX(calc(-100% - 48px))" data-test="true">Text</span>)
134135
end
135136
end
136137

@@ -145,7 +146,7 @@ class AvatarComponent < Component
145146
it 'surrounds tag with if conditional and interprets dynamic attributes' do
146147
theo = %(<span %if="condition" class%="cls">Text</span>)
147148

148-
expect(to_erb(theo)).to eq %(<% if condition %>\n<span <% if (_val = cls) %>class="<%= _val %>"<% end %>>Text</span>\n<% end %>)
149+
expect(to_erb(theo)).to eq %(<% if condition %>\n<span class="<%= cls %>">Text</span>\n<% end %>)
149150
expect(to_html(theo, condition: true, cls: 'red')).to eq %(\n<span class="red">Text</span>\n)
150151
end
151152

0 commit comments

Comments
 (0)