haml 6.1.1 → 6.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,173 +2,161 @@
2
2
  require 'haml/object_ref'
3
3
 
4
4
  module Haml::AttributeBuilder
5
- BOOLEAN_ATTRIBUTES = %w[disabled readonly multiple checked autobuffer
6
- autoplay controls loop selected hidden scoped async
7
- defer reversed ismap seamless muted required
8
- autofocus novalidate formnovalidate open pubdate
9
- itemscope allowfullscreen default inert sortable
10
- truespeed typemustmatch download].freeze
11
-
12
- # For JRuby, TruffleRuby, and Wasm, fallback to Ruby implementation.
13
- if /java|wasm/ === RUBY_PLATFORM || RUBY_ENGINE == 'truffleruby'
14
- class << self
15
- def build(escape_attrs, quote, format, boolean_attributes, object_ref, *hashes)
16
- hashes << Haml::ObjectRef.parse(object_ref) if object_ref
17
- buf = []
18
- hash = merge_all_attrs(hashes)
19
-
20
- keys = hash.keys.sort!
21
- keys.each do |key|
22
- case key
23
- when 'id'.freeze
24
- buf << " id=#{quote}#{build_id(escape_attrs, *hash[key])}#{quote}"
25
- when 'class'.freeze
26
- buf << " class=#{quote}#{build_class(escape_attrs, *hash[key])}#{quote}"
27
- when 'data'.freeze
28
- buf << build_data(escape_attrs, quote, *hash[key])
29
- when *boolean_attributes, /\Adata-/
30
- build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
31
- else
32
- buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
33
- end
5
+ class << self
6
+ def build(escape_attrs, quote, format, object_ref, *hashes)
7
+ hashes << Haml::ObjectRef.parse(object_ref) if object_ref
8
+ buf = []
9
+ hash = merge_all_attrs(hashes)
10
+
11
+ keys = hash.keys.sort!
12
+ keys.each do |key|
13
+ case key
14
+ when 'id'
15
+ buf << " id=#{quote}#{build_id(escape_attrs, *hash[key])}#{quote}"
16
+ when 'class'
17
+ buf << " class=#{quote}#{build_class(escape_attrs, *hash[key])}#{quote}"
18
+ when 'data'
19
+ buf << build_data(escape_attrs, quote, *hash[key])
20
+ when 'aria'
21
+ buf << build_aria(escape_attrs, quote, *hash[key])
22
+ when *Haml::BOOLEAN_ATTRIBUTES, /\Adata-/, /\Aaria-/
23
+ build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
24
+ else
25
+ buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
34
26
  end
35
- buf.join
36
- end
37
-
38
- def build_id(escape_attrs, *values)
39
- escape_html(escape_attrs, values.flatten.select { |v| v }.join('_'))
40
27
  end
28
+ buf.join
29
+ end
41
30
 
42
- def build_class(escape_attrs, *values)
43
- if values.size == 1
44
- value = values.first
45
- case
46
- when value.is_a?(String)
47
- # noop
48
- when value.is_a?(Array)
49
- value = value.flatten.select { |v| v }.map(&:to_s).uniq.join(' ')
50
- when value
51
- value = value.to_s
52
- else
53
- return ''
54
- end
55
- return escape_html(escape_attrs, value)
56
- end
31
+ def build_id(escape_attrs, *values)
32
+ escape_html(escape_attrs, values.flatten.select { |v| v }.join('_'))
33
+ end
57
34
 
58
- classes = []
59
- values.each do |value|
60
- case
61
- when value.is_a?(String)
62
- classes += value.split(' ')
63
- when value.is_a?(Array)
64
- classes += value.select { |v| v }
65
- when value
66
- classes << value.to_s
67
- end
35
+ def build_class(escape_attrs, *values)
36
+ if values.size == 1
37
+ value = values.first
38
+ case
39
+ when value.is_a?(String)
40
+ # noop
41
+ when value.is_a?(Array)
42
+ value = value.flatten.select { |v| v }.map(&:to_s).uniq.join(' ')
43
+ when value
44
+ value = value.to_s
45
+ else
46
+ return ''
68
47
  end
69
- escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
48
+ return escape_html(escape_attrs, value)
70
49
  end
71
50
 
72
- def build_data(escape_attrs, quote, *hashes)
73
- build_data_attribute(:data, escape_attrs, quote, *hashes)
51
+ classes = []
52
+ values.each do |value|
53
+ case
54
+ when value.is_a?(String)
55
+ classes += value.split(' ')
56
+ when value.is_a?(Array)
57
+ classes += value.select { |v| v }
58
+ when value
59
+ classes << value.to_s
60
+ end
74
61
  end
62
+ escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
63
+ end
75
64
 
76
- def build_aria(escape_attrs, quote, *hashes)
77
- build_data_attribute(:aria, escape_attrs, quote, *hashes)
78
- end
65
+ def build_data(escape_attrs, quote, *hashes)
66
+ build_data_attribute(:data, escape_attrs, quote, *hashes)
67
+ end
79
68
 
80
- private
69
+ def build_aria(escape_attrs, quote, *hashes)
70
+ build_data_attribute(:aria, escape_attrs, quote, *hashes)
71
+ end
81
72
 
82
- def build_data_attribute(key, escape_attrs, quote, *hashes)
83
- attrs = []
84
- if hashes.size > 1 && hashes.all? { |h| h.is_a?(Hash) }
85
- data_value = merge_all_attrs(hashes)
86
- else
87
- data_value = hashes.last
88
- end
89
- hash = flatten_attributes(key => data_value)
73
+ private
90
74
 
91
- hash.sort_by(&:first).each do |key, value|
92
- case value
93
- when true
94
- attrs << " #{key}"
95
- when nil, false
96
- # noop
97
- else
98
- attrs << " #{key}=#{quote}#{escape_html(escape_attrs, value.to_s)}#{quote}"
99
- end
100
- end
101
- attrs.join
75
+ def build_data_attribute(key, escape_attrs, quote, *hashes)
76
+ attrs = []
77
+ if hashes.size > 1 && hashes.all? { |h| h.is_a?(Hash) }
78
+ data_value = merge_all_attrs(hashes)
79
+ else
80
+ data_value = hashes.last
102
81
  end
82
+ hash = flatten_attributes(key => data_value)
103
83
 
104
- def flatten_attributes(attributes)
105
- flattened = {}
106
-
107
- attributes.each do |key, value|
108
- case value
109
- when attributes
110
- when Hash
111
- flatten_attributes(value).each do |k, v|
112
- if k.nil?
113
- flattened[key] = v
114
- else
115
- flattened["#{key}-#{k.to_s.gsub(/_/, '-')}"] = v
116
- end
117
- end
118
- else
119
- flattened[key] = value if value
120
- end
84
+ hash.sort_by(&:first).each do |key, value|
85
+ case value
86
+ when true
87
+ attrs << " #{key}"
88
+ when nil, false
89
+ # noop
90
+ else
91
+ attrs << " #{key}=#{quote}#{escape_html(escape_attrs, value.to_s)}#{quote}"
121
92
  end
122
- flattened
123
93
  end
94
+ attrs.join
95
+ end
96
+
97
+ def flatten_attributes(attributes)
98
+ flattened = {}
124
99
 
125
- def merge_all_attrs(hashes)
126
- merged = {}
127
- hashes.each do |hash|
128
- hash.each do |key, value|
129
- key = key.to_s
130
- case key
131
- when 'id'.freeze, 'class'.freeze, 'data'.freeze
132
- merged[key] ||= []
133
- merged[key] << value
100
+ attributes.each do |key, value|
101
+ case value
102
+ when attributes
103
+ when Hash
104
+ flatten_attributes(value).each do |k, v|
105
+ if k.nil?
106
+ flattened[key] = v
134
107
  else
135
- merged[key] = value
108
+ flattened["#{key}-#{k.to_s.gsub(/_/, '-')}"] = v
136
109
  end
137
110
  end
111
+ else
112
+ flattened[key] = value if value
138
113
  end
139
- merged
140
114
  end
115
+ flattened
116
+ end
141
117
 
142
- def build_boolean!(escape_attrs, quote, format, buf, key, value)
143
- case value
144
- when true
145
- case format
146
- when :xhtml
147
- buf << " #{key}=#{quote}#{key}#{quote}"
118
+ def merge_all_attrs(hashes)
119
+ merged = {}
120
+ hashes.each do |hash|
121
+ unless hash.is_a?(Hash)
122
+ raise ArgumentError, "Non-hash object is given to attributes!"
123
+ end
124
+ hash.each do |key, value|
125
+ key = key.to_s
126
+ case key
127
+ when 'id', 'class', 'data', 'aria'
128
+ merged[key] ||= []
129
+ merged[key] << value
148
130
  else
149
- buf << " #{key}"
131
+ merged[key] = value
150
132
  end
151
- when false, nil
152
- # omitted
153
- else
154
- buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
155
133
  end
156
134
  end
135
+ merged
136
+ end
157
137
 
158
- def escape_html(escape_attrs, str)
159
- if escape_attrs
160
- Haml::Util.escape_html(str)
138
+ def build_boolean!(escape_attrs, quote, format, buf, key, value)
139
+ case value
140
+ when true
141
+ case format
142
+ when :xhtml
143
+ buf << " #{key}=#{quote}#{key}#{quote}"
161
144
  else
162
- str
145
+ buf << " #{key}"
163
146
  end
147
+ when false, nil
148
+ # omitted
149
+ else
150
+ buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
151
+ end
152
+ end
153
+
154
+ def escape_html(escape_attrs, str)
155
+ if escape_attrs
156
+ Haml::Util.escape_html(str)
157
+ else
158
+ str
164
159
  end
165
160
  end
166
- else
167
- # Haml::AttributeBuilder.build
168
- # Haml::AttributeBuilder.build_id
169
- # Haml::AttributeBuilder.build_class
170
- # Haml::AttributeBuilder.build_data
171
- # Haml::AttributeBuilder.build_aria
172
- require 'haml/haml'
173
161
  end
174
162
  end
@@ -4,6 +4,14 @@ require 'haml/attribute_parser'
4
4
  require 'haml/ruby_expression'
5
5
 
6
6
  module Haml
7
+ # The list of boolean attributes. You may add custom attributes to this constant.
8
+ BOOLEAN_ATTRIBUTES = %w[disabled readonly multiple checked autobuffer
9
+ autoplay controls loop selected hidden scoped async
10
+ defer reversed ismap seamless muted required
11
+ autofocus novalidate formnovalidate open pubdate
12
+ itemscope allowfullscreen default inert sortable
13
+ truespeed typemustmatch download]
14
+
7
15
  class AttributeCompiler
8
16
  def initialize(identity, options)
9
17
  @identity = identity
@@ -31,10 +39,7 @@ module Haml
31
39
  attrs = []
32
40
  attrs.unshift(node.value[:attributes].inspect) if node.value[:attributes] != {}
33
41
 
34
- args = [
35
- @escape_attrs.inspect, "#{@quote.inspect}.freeze", @format.inspect,
36
- '::Haml::AttributeBuilder::BOOLEAN_ATTRIBUTES', node.value[:object_ref],
37
- ] + attrs
42
+ args = [@escape_attrs.inspect, "#{@quote.inspect}.freeze", @format.inspect, node.value[:object_ref]] + attrs
38
43
  [:html, :attrs, [:dynamic, "::Haml::AttributeBuilder.build(#{args.join(', ')}, #{node.value[:dynamic_attributes].to_literal})"]]
39
44
  end
40
45
 
@@ -52,7 +57,7 @@ module Haml
52
57
  compile_class!(temple, key, values)
53
58
  when 'data', 'aria'
54
59
  compile_data!(temple, key, values)
55
- when *AttributeBuilder::BOOLEAN_ATTRIBUTES, /\Adata-/, /\Aaria-/
60
+ when *BOOLEAN_ATTRIBUTES, /\Adata-/, /\Aaria-/
56
61
  compile_boolean!(temple, key, values)
57
62
  else
58
63
  compile_common!(temple, key, values)
@@ -8,10 +8,12 @@ module Haml
8
8
 
9
9
  def compile(node)
10
10
  case node.value[:type]
11
- when 'xml'
12
- xml_doctype
13
11
  when ''
14
12
  html_doctype(node)
13
+ when 'xml'
14
+ xml_doctype
15
+ when 'rdfa'
16
+ rdfa_doctype
15
17
  else
16
18
  [:html, :doctype, node.value[:type]]
17
19
  end
@@ -41,6 +43,10 @@ module Haml
41
43
  [:multi]
42
44
  end
43
45
  end
46
+
47
+ def rdfa_doctype
48
+ [:static, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">']
49
+ end
44
50
  end
45
51
  end
46
52
  end
@@ -27,6 +27,11 @@ module Haml
27
27
  source ||= template.source
28
28
  options = RailsTemplate.options
29
29
 
30
+ # Make the filename available in parser etc.
31
+ if template.respond_to?(:identifier)
32
+ options = options.merge(filename: template.identifier)
33
+ end
34
+
30
35
  # https://github.com/haml/haml/blob/4.0.7/lib/haml/template/plugin.rb#L19-L20
31
36
  # https://github.com/haml/haml/blob/4.0.7/lib/haml/options.rb#L228
32
37
  if template.respond_to?(:type) && template.type == 'text/xml'
@@ -43,6 +48,11 @@ module Haml
43
48
  Engine.new(options).call(source)
44
49
  end
45
50
 
51
+ # Rails Turbo looks for this
52
+ def default_format
53
+ :html
54
+ end
55
+
46
56
  def supports_streaming?
47
57
  RailsTemplate.options[:streaming]
48
58
  end
data/lib/haml/util.rb CHANGED
@@ -14,15 +14,16 @@ module Haml
14
14
  module Util
15
15
  extend self
16
16
 
17
- # For JRuby, TruffleRuby, and Wasm, fallback to Ruby implementation.
18
- if /java|wasm/ === RUBY_PLATFORM || RUBY_ENGINE == 'truffleruby'
17
+ begin # Ruby 3.2+ or ERB 4+
18
+ require 'erb/escape'
19
+
20
+ define_singleton_method(:escape_html, ERB::Escape.instance_method(:html_escape))
21
+ rescue LoadError
19
22
  require 'cgi/escape'
20
23
 
21
24
  def self.escape_html(html)
22
25
  CGI.escapeHTML(html.to_s)
23
26
  end
24
- else
25
- require 'haml/haml' # Haml::Util.escape_html
26
27
  end
27
28
 
28
29
  # TODO: Remove unescape_interpolation's workaround and get rid of `respond_to?`.
data/lib/haml/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Haml
3
- VERSION = '6.1.1'
3
+ VERSION = '6.2.3'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.1
4
+ version: 6.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Natalie Weizenbaum
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: exe
14
14
  cert_chain: []
15
- date: 2022-12-10 00:00:00.000000000 Z
15
+ date: 2023-10-04 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: temple
@@ -182,20 +182,6 @@ dependencies:
182
182
  - - ">="
183
183
  - !ruby/object:Gem::Version
184
184
  version: '0'
185
- - !ruby/object:Gem::Dependency
186
- name: rake-compiler
187
- requirement: !ruby/object:Gem::Requirement
188
- requirements:
189
- - - ">="
190
- - !ruby/object:Gem::Version
191
- version: '0'
192
- type: :development
193
- prerelease: false
194
- version_requirements: !ruby/object:Gem::Requirement
195
- requirements:
196
- - - ">="
197
- - !ruby/object:Gem::Version
198
- version: '0'
199
185
  - !ruby/object:Gem::Dependency
200
186
  name: sass
201
187
  requirement: !ruby/object:Gem::Requirement
@@ -258,8 +244,7 @@ email:
258
244
  - ronnie@dio.jp
259
245
  executables:
260
246
  - haml
261
- extensions:
262
- - ext/haml/extconf.rb
247
+ extensions: []
263
248
  extra_rdoc_files: []
264
249
  files:
265
250
  - ".github/FUNDING.yml"
@@ -280,10 +265,6 @@ files:
280
265
  - bin/stackprof
281
266
  - bin/test
282
267
  - exe/haml
283
- - ext/haml/extconf.rb
284
- - ext/haml/haml.c
285
- - ext/haml/hescape.c
286
- - ext/haml/hescape.h
287
268
  - haml.gemspec
288
269
  - lib/haml.rb
289
270
  - lib/haml/ambles.rb
@@ -339,7 +320,8 @@ files:
339
320
  homepage: https://haml.info
340
321
  licenses:
341
322
  - MIT
342
- metadata: {}
323
+ metadata:
324
+ rubygems_mfa_required: 'true'
343
325
  post_install_message:
344
326
  rdoc_options: []
345
327
  require_paths:
@@ -355,7 +337,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
355
337
  - !ruby/object:Gem::Version
356
338
  version: '0'
357
339
  requirements: []
358
- rubygems_version: 3.4.0.dev
340
+ rubygems_version: 3.3.26
359
341
  signing_key:
360
342
  specification_version: 4
361
343
  summary: An elegant, structured (X)HTML/XML templating engine.
data/ext/haml/extconf.rb DELETED
@@ -1,10 +0,0 @@
1
- require 'mkmf'
2
-
3
- $CFLAGS << ' -Wall -Wextra'
4
-
5
- $srcs = %w[
6
- haml.c
7
- hescape.c
8
- ]
9
-
10
- create_makefile('haml/haml')