haml 7.3.1 → 7.4.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -1
- data/REFERENCE.md +1 -1
- data/lib/haml/attribute_builder.rb +17 -6
- data/lib/haml/attribute_compiler.rb +9 -6
- data/lib/haml/compiler/script_compiler.rb +6 -9
- data/lib/haml/helpers.rb +1 -1
- data/lib/haml/parser.rb +2 -1
- data/lib/haml/preserver.rb +52 -0
- data/lib/haml/rails_helpers.rb +4 -12
- data/lib/haml/util.rb +9 -5
- data/lib/haml/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4dced0d7329423afd97a56b1ce6b32f4c332a9f4e725aed6a41f4e5d7c10bfd7
|
|
4
|
+
data.tar.gz: 985f140fb9f9ae590c0e37ae7d5f06632c5c1f4a522578639e2a98527fb85e20
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba4cc15a925752648e293fd712e024c92da5d0e1d827e28719e871e5ffa7a647fc928c46650f7a2c92bf3ad8c67e70f821fd1710de346affb528639f34652af1
|
|
7
|
+
data.tar.gz: 062d2e3a5b523a5450179790f20627920e9086065b13f15591b4472178a3e7ec4672caa299466a428b343a21b5fd7eb85c0549f032b22ba5854aacf1510ad576
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
# Haml Changelog
|
|
2
2
|
|
|
3
|
+
## 7.4.1
|
|
4
|
+
|
|
5
|
+
* Build the preserve regex once per tag list instead of per call https://github.com/haml/haml/pull/1220
|
|
6
|
+
|
|
7
|
+
## 7.4.0
|
|
8
|
+
|
|
9
|
+
* `Haml::BOOLEAN_ATTRIBUTES` is changed from Array to Set https://github.com/haml/haml/pull/1216
|
|
10
|
+
* A guard on `respond_to?(:html_safe?)` is removed from `Haml::Util.escape_html_safe` https://github.com/haml/haml/pull/1217
|
|
11
|
+
* Keep interpolated text in the source encoding, fixing the `Encoding::CompatibilityError` remaining on an ASCII-8BIT
|
|
12
|
+
template source that mixes plain text and interpolation with non-ASCII characters https://github.com/haml/haml/issues/1218
|
|
13
|
+
|
|
3
14
|
## 7.3.1
|
|
4
15
|
|
|
5
|
-
* Keep Prism-derived fragments in the source encoding, fixing `Encoding::CompatibilityError` on an ASCII-8BIT
|
|
16
|
+
* Keep Prism-derived fragments in the source encoding, fixing `Encoding::CompatibilityError` on an ASCII-8BIT
|
|
17
|
+
template source with non-ASCII characters (regression in 7.3.0) https://github.com/haml/haml/issues/1218
|
|
6
18
|
|
|
7
19
|
## 7.3.0
|
|
8
20
|
|
data/REFERENCE.md
CHANGED
|
@@ -320,7 +320,7 @@ or using `true` and `false`:
|
|
|
320
320
|
%input(selected=true)
|
|
321
321
|
|
|
322
322
|
This feature works only for attributes that are included in
|
|
323
|
-
[`Haml::BOOLEAN_ATTRIBUTES`](https://github.com/haml/haml/blob/main/lib/haml/attribute_compiler.rb#
|
|
323
|
+
[`Haml::BOOLEAN_ATTRIBUTES`](https://github.com/haml/haml/blob/main/lib/haml/attribute_compiler.rb#L9),
|
|
324
324
|
as well as `data-` and `aria-` attributes.
|
|
325
325
|
|
|
326
326
|
%input{'data-hidden' => false}
|
|
@@ -19,10 +19,12 @@ module Haml::AttributeBuilder
|
|
|
19
19
|
buf << build_data(escape_attrs, quote, format, *hash[key])
|
|
20
20
|
when 'aria'
|
|
21
21
|
buf << build_aria(escape_attrs, quote, format, *hash[key])
|
|
22
|
-
when *Haml::BOOLEAN_ATTRIBUTES, /\Adata-/, /\Aaria-/
|
|
23
|
-
build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
|
|
24
22
|
else
|
|
25
|
-
|
|
23
|
+
if boolean_attribute?(key)
|
|
24
|
+
build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
|
|
25
|
+
else
|
|
26
|
+
buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
|
|
27
|
+
end
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
buf.join
|
|
@@ -72,6 +74,10 @@ module Haml::AttributeBuilder
|
|
|
72
74
|
|
|
73
75
|
private
|
|
74
76
|
|
|
77
|
+
def boolean_attribute?(key)
|
|
78
|
+
Haml::BOOLEAN_ATTRIBUTES.include?(key) || key.start_with?('data-', 'aria-')
|
|
79
|
+
end
|
|
80
|
+
|
|
75
81
|
def build_data_attribute(key, escape_attrs, quote, format, *hashes)
|
|
76
82
|
attrs = []
|
|
77
83
|
if hashes.size > 1 && hashes.all? { |h| h.is_a?(Hash) }
|
|
@@ -98,14 +104,18 @@ module Haml::AttributeBuilder
|
|
|
98
104
|
flattened = {}
|
|
99
105
|
|
|
100
106
|
attributes.each do |key, value|
|
|
107
|
+
# Recursing into a hash which contains itself would never end.
|
|
108
|
+
next if value.equal?(attributes)
|
|
109
|
+
|
|
101
110
|
case value
|
|
102
|
-
when attributes
|
|
103
111
|
when Hash
|
|
104
112
|
flatten_attributes(value).each do |k, v|
|
|
105
113
|
if k.nil?
|
|
106
114
|
flattened[key] = v
|
|
107
115
|
else
|
|
108
|
-
|
|
116
|
+
k = k.is_a?(Symbol) ? k.name : k.to_s
|
|
117
|
+
k = k.tr('_', '-') if k.include?('_')
|
|
118
|
+
flattened["#{key}-#{k}"] = v
|
|
109
119
|
end
|
|
110
120
|
end
|
|
111
121
|
else
|
|
@@ -122,7 +132,8 @@ module Haml::AttributeBuilder
|
|
|
122
132
|
raise ArgumentError, "Non-hash object is given to attributes!"
|
|
123
133
|
end
|
|
124
134
|
hash.each do |key, value|
|
|
125
|
-
|
|
135
|
+
# Symbol#name hands back the interned String; to_s allocates one per render.
|
|
136
|
+
key = key.is_a?(Symbol) ? key.name : key.to_s
|
|
126
137
|
case key
|
|
127
138
|
when 'id', 'class', 'data', 'aria'
|
|
128
139
|
merged[key] ||= []
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
require 'set'
|
|
2
3
|
require 'haml/attribute_builder'
|
|
3
4
|
require 'haml/attribute_parser'
|
|
4
5
|
require 'haml/ruby_expression'
|
|
5
6
|
|
|
6
7
|
module Haml
|
|
7
|
-
# The
|
|
8
|
-
BOOLEAN_ATTRIBUTES = %w[disabled readonly multiple checked autobuffer
|
|
8
|
+
# The set of boolean attributes. You may add custom attributes to this constant.
|
|
9
|
+
BOOLEAN_ATTRIBUTES = Set.new(%w[disabled readonly multiple checked autobuffer
|
|
9
10
|
autoplay controls loop selected hidden scoped async
|
|
10
11
|
defer reversed ismap seamless muted required
|
|
11
12
|
autofocus novalidate formnovalidate open pubdate
|
|
12
13
|
itemscope allowfullscreen default inert sortable
|
|
13
|
-
truespeed typemustmatch download]
|
|
14
|
+
truespeed typemustmatch download])
|
|
14
15
|
|
|
15
16
|
class AttributeCompiler
|
|
16
17
|
def initialize(identity, options)
|
|
@@ -55,10 +56,12 @@ module Haml
|
|
|
55
56
|
compile_class!(temple, key, values)
|
|
56
57
|
when 'data', 'aria'
|
|
57
58
|
compile_data!(temple, key, values)
|
|
58
|
-
when *BOOLEAN_ATTRIBUTES, /\Adata-/, /\Aaria-/
|
|
59
|
-
compile_boolean!(temple, key, values)
|
|
60
59
|
else
|
|
61
|
-
|
|
60
|
+
if BOOLEAN_ATTRIBUTES.include?(key) || key.start_with?('data-', 'aria-')
|
|
61
|
+
compile_boolean!(temple, key, values)
|
|
62
|
+
else
|
|
63
|
+
compile_common!(temple, key, values)
|
|
64
|
+
end
|
|
62
65
|
end
|
|
63
66
|
end
|
|
64
67
|
temple
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require 'temple/static_analyzer'
|
|
3
|
+
require 'haml/helpers'
|
|
4
|
+
require 'haml/preserver'
|
|
3
5
|
require 'haml/ruby_expression'
|
|
4
6
|
require 'haml/string_splitter'
|
|
5
7
|
|
|
6
8
|
module Haml
|
|
7
9
|
class Compiler
|
|
8
10
|
class ScriptCompiler
|
|
9
|
-
def self.find_and_preserve(input, tags)
|
|
10
|
-
|
|
11
|
-
re = /<(#{tags})([^>]*)>(.*?)(<\/\1>)/im
|
|
12
|
-
input.to_s.gsub(re) do |s|
|
|
13
|
-
s =~ re # Can't rely on $1, etc. existing since Rails' SafeBuffer#gsub is incompatible
|
|
14
|
-
"<#{$1}#{$2}>#{Haml::Helpers.preserve($3)}</#{$1}>"
|
|
15
|
-
end
|
|
11
|
+
def self.find_and_preserve(input, tags = ::Haml::Preserver::DEFAULT_TAGS)
|
|
12
|
+
::Haml::Preserver.find_and_preserve(input, tags) { |content| ::Haml::Helpers.preserve(content) }
|
|
16
13
|
end
|
|
17
14
|
|
|
18
15
|
def initialize(identity, options)
|
|
@@ -69,7 +66,7 @@ module Haml
|
|
|
69
66
|
if node.value[:escape_html]
|
|
70
67
|
str = Haml::Util.escape_html(str)
|
|
71
68
|
elsif node.value[:preserve]
|
|
72
|
-
str = ScriptCompiler.find_and_preserve(str
|
|
69
|
+
str = ScriptCompiler.find_and_preserve(str)
|
|
73
70
|
end
|
|
74
71
|
[:multi, [:static, str], [:newline]]
|
|
75
72
|
end
|
|
@@ -104,7 +101,7 @@ module Haml
|
|
|
104
101
|
end
|
|
105
102
|
|
|
106
103
|
def find_and_preserve(code)
|
|
107
|
-
%Q[::Haml::Compiler::ScriptCompiler.find_and_preserve(#{code}
|
|
104
|
+
%Q[::Haml::Compiler::ScriptCompiler.find_and_preserve(#{code})]
|
|
108
105
|
end
|
|
109
106
|
|
|
110
107
|
def escape_html(temple)
|
data/lib/haml/helpers.rb
CHANGED
data/lib/haml/parser.rb
CHANGED
|
@@ -444,7 +444,8 @@ module Haml
|
|
|
444
444
|
end
|
|
445
445
|
else
|
|
446
446
|
if Util.contains_interpolation?(value)
|
|
447
|
-
value = Util.unescape_interpolation(value
|
|
447
|
+
value = Util.unescape_interpolation(value)
|
|
448
|
+
escape_interpolation = true if escape_html
|
|
448
449
|
parse = true
|
|
449
450
|
escape_html = false
|
|
450
451
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Haml
|
|
3
|
+
# find_and_preserve, shared by compiled templates and RailsHelpers.
|
|
4
|
+
#
|
|
5
|
+
# @api private
|
|
6
|
+
module Preserver
|
|
7
|
+
DEFAULT_TAGS = %w[textarea pre code].freeze
|
|
8
|
+
|
|
9
|
+
def self.build_regex(tags)
|
|
10
|
+
# An empty entry would add an alternative matching `<>`.
|
|
11
|
+
pattern = tags.reject(&:empty?).map { |tag| Regexp.escape(tag) }.join('|')
|
|
12
|
+
/<(#{pattern})([^>]*)>(.*?)(<\/\1>)/im
|
|
13
|
+
end
|
|
14
|
+
private_class_method :build_regex
|
|
15
|
+
|
|
16
|
+
DEFAULT_REGEX = build_regex(DEFAULT_TAGS)
|
|
17
|
+
private_constant :DEFAULT_REGEX
|
|
18
|
+
|
|
19
|
+
# Past this many lists the merge below turns quadratic, so the cache starts over.
|
|
20
|
+
MAX_REGEXES = 64
|
|
21
|
+
private_constant :MAX_REGEXES
|
|
22
|
+
|
|
23
|
+
INITIAL_REGEXES = { DEFAULT_TAGS => DEFAULT_REGEX }.freeze
|
|
24
|
+
private_constant :INITIAL_REGEXES
|
|
25
|
+
|
|
26
|
+
@regexes = INITIAL_REGEXES
|
|
27
|
+
|
|
28
|
+
# The cache is replaced, never mutated, so a racing writer at worst rebuilds a regex.
|
|
29
|
+
def self.regex(tags)
|
|
30
|
+
return DEFAULT_REGEX if tags.equal?(DEFAULT_TAGS)
|
|
31
|
+
|
|
32
|
+
cache = @regexes
|
|
33
|
+
cache[tags] || begin
|
|
34
|
+
regex = build_regex(tags)
|
|
35
|
+
# Copied so a caller mutating its own list, or a String in it, cannot strand the entry.
|
|
36
|
+
key = tags.map { |tag| tag.dup.freeze }.freeze
|
|
37
|
+
cache = INITIAL_REGEXES if cache.size >= MAX_REGEXES
|
|
38
|
+
@regexes = cache.merge(key => regex).freeze
|
|
39
|
+
regex
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.find_and_preserve(input, tags)
|
|
44
|
+
re = regex(tags)
|
|
45
|
+
input.to_s.gsub(re) do |s|
|
|
46
|
+
s =~ re # Can't rely on $1, etc. existing since Rails' SafeBuffer#gsub is incompatible
|
|
47
|
+
name, attributes, content = $1, $2, $3
|
|
48
|
+
"<#{name}#{attributes}>#{yield(content)}</#{name}>"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/haml/rails_helpers.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
require 'haml/helpers'
|
|
3
|
+
require 'haml/preserver'
|
|
3
4
|
|
|
4
5
|
# There are only helpers that depend on ActionView internals.
|
|
5
6
|
module Haml
|
|
@@ -7,21 +8,12 @@ module Haml
|
|
|
7
8
|
include Helpers
|
|
8
9
|
extend self
|
|
9
10
|
|
|
10
|
-
DEFAULT_PRESERVE_TAGS =
|
|
11
|
+
DEFAULT_PRESERVE_TAGS = Preserver::DEFAULT_TAGS
|
|
11
12
|
|
|
12
13
|
def find_and_preserve(input = nil, tags = DEFAULT_PRESERVE_TAGS, &block)
|
|
13
14
|
return find_and_preserve(capture_haml(&block), input || tags) if block
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
s << '|' unless s.empty?
|
|
17
|
-
s << Regexp.escape(t)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
re = /<(#{tags})([^>]*)>(.*?)(<\/\1>)/im
|
|
21
|
-
input.to_s.gsub(re) do |s|
|
|
22
|
-
s =~ re # Can't rely on $1, etc. existing since Rails' SafeBuffer#gsub is incompatible
|
|
23
|
-
"<#{$1}#{$2}>#{preserve($3)}</#{$1}>"
|
|
24
|
-
end
|
|
16
|
+
Preserver.find_and_preserve(input, tags) { |content| preserve(content) }
|
|
25
17
|
end
|
|
26
18
|
|
|
27
19
|
def preserve(input = nil, &block)
|
data/lib/haml/util.rb
CHANGED
|
@@ -26,10 +26,9 @@ module Haml
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
# TODO: Remove unescape_interpolation's workaround and get rid of `respond_to?`.
|
|
30
29
|
def self.escape_html_safe(html)
|
|
31
30
|
html = html.to_s
|
|
32
|
-
|
|
31
|
+
html.html_safe? ? html : escape_html(html)
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
# Silence all output to STDERR within a block.
|
|
@@ -202,7 +201,7 @@ MSG
|
|
|
202
201
|
/#[\{$@]/ === str
|
|
203
202
|
end
|
|
204
203
|
|
|
205
|
-
def unescape_interpolation(str
|
|
204
|
+
def unescape_interpolation(str)
|
|
206
205
|
res = ''.dup
|
|
207
206
|
rest = Haml::Util.handle_interpolation str.dump do |scan|
|
|
208
207
|
escapes = (scan[2].size - 1) / 2
|
|
@@ -218,12 +217,17 @@ MSG
|
|
|
218
217
|
end
|
|
219
218
|
content = eval("\"#{interpolated}\"")
|
|
220
219
|
content = "#{char}#{content}" if char == '@' || char == '$'
|
|
221
|
-
content = "Haml::Util.escape_html_safe((#{content}).to_s)" if escape_html
|
|
222
220
|
|
|
223
221
|
res << "\#{#{content}}"
|
|
224
222
|
end
|
|
225
223
|
end
|
|
226
|
-
|
|
224
|
+
# The result is rebuilt from `str.dump` fragments and eval'd pieces, so it can
|
|
225
|
+
# come out tagged with an encoding that differs from `str`'s (e.g. UTF-8 for a
|
|
226
|
+
# BINARY source). The compiled template joins this string literal's fragments
|
|
227
|
+
# with fragments sliced out of the source itself, and mixed encodings raise
|
|
228
|
+
# Encoding::CompatibilityError, so bring it back to the source encoding.
|
|
229
|
+
# See haml/haml#1218.
|
|
230
|
+
(res + rest).force_encoding(str.encoding)
|
|
227
231
|
end
|
|
228
232
|
|
|
229
233
|
private
|
data/lib/haml/version.rb
CHANGED
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: 7.
|
|
4
|
+
version: 7.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Natalie Weizenbaum
|
|
@@ -307,6 +307,7 @@ files:
|
|
|
307
307
|
- lib/haml/identity.rb
|
|
308
308
|
- lib/haml/object_ref.rb
|
|
309
309
|
- lib/haml/parser.rb
|
|
310
|
+
- lib/haml/preserver.rb
|
|
310
311
|
- lib/haml/rails_helpers.rb
|
|
311
312
|
- lib/haml/rails_template.rb
|
|
312
313
|
- lib/haml/railtie.rb
|