hamlit 2.11.0-java → 2.12.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +12 -10
- data/CHANGELOG.md +16 -1
- data/Gemfile +1 -7
- data/REFERENCE.md +4 -4
- data/ext/hamlit/hamlit.c +0 -1
- data/lib/hamlit/attribute_builder.rb +2 -2
- data/lib/hamlit/attribute_compiler.rb +3 -3
- data/lib/hamlit/compiler/children_compiler.rb +18 -4
- data/lib/hamlit/parser/haml_attribute_builder.rb +164 -0
- data/lib/hamlit/parser/haml_helpers.rb +6 -0
- data/lib/hamlit/parser/haml_parser.rb +32 -9
- data/lib/hamlit/parser/haml_xss_mods.rb +6 -3
- data/lib/hamlit/temple_line_counter.rb +31 -0
- data/lib/hamlit/version.rb +1 -1
- metadata +22 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9730ad24ae51f479f990d08aaa054adc41541e02f058889d085c437b7fce3772
|
4
|
+
data.tar.gz: 96956fc4d9e69332956936769d0843548d769179f31c2499706befc566dab02b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d12567ab91773b31fbb8431362c821261b5ad47e678f75465df51e52a48bb101da829dd9e93b7aea75925a77b179f09f92ab08c0c0042b46478f0497bed7c6e
|
7
|
+
data.tar.gz: fa594a116affab20ea90313253bc5308a9e0d47a369b07d4b971e97728ac8fcbb6bbaa4ee1509ffede4b9f546e47d1abd6810d0c545377357748805416bfd34f
|
data/.travis.yml
CHANGED
@@ -9,11 +9,13 @@ matrix:
|
|
9
9
|
include:
|
10
10
|
- rvm: 2.3.8
|
11
11
|
env: TASK=test
|
12
|
-
- rvm: 2.4.
|
12
|
+
- rvm: 2.4.9
|
13
13
|
env: TASK=test
|
14
|
-
- rvm: 2.5.
|
14
|
+
- rvm: 2.5.7
|
15
15
|
env: TASK=test
|
16
|
-
- rvm: 2.6.
|
16
|
+
- rvm: 2.6.5
|
17
|
+
env: TASK=test
|
18
|
+
- rvm: 2.7.0
|
17
19
|
env: TASK=test
|
18
20
|
- rvm: ruby-head
|
19
21
|
env: TASK=test
|
@@ -21,19 +23,19 @@ matrix:
|
|
21
23
|
env: TASK=test
|
22
24
|
- rvm: truffleruby
|
23
25
|
env: TASK=test
|
24
|
-
- rvm: 2.
|
26
|
+
- rvm: 2.7.0
|
25
27
|
env: TASK=bench TEMPLATE=benchmark/boolean_attribute.haml,benchmark/class_attribute.haml,benchmark/id_attribute.haml,benchmark/data_attribute.haml,benchmark/common_attribute.haml
|
26
|
-
- rvm: 2.
|
28
|
+
- rvm: 2.7.0
|
27
29
|
env: TASK=bench TEMPLATE=benchmark/dynamic_attributes/boolean_attribute.haml,benchmark/dynamic_attributes/class_attribute.haml,benchmark/dynamic_attributes/id_attribute.haml,benchmark/dynamic_attributes/data_attribute.haml,benchmark/dynamic_attributes/common_attribute.haml
|
28
|
-
- rvm: 2.
|
30
|
+
- rvm: 2.7.0
|
29
31
|
env: TASK=bench SLIM_BENCH=1
|
30
|
-
- rvm: 2.
|
32
|
+
- rvm: 2.7.0
|
31
33
|
env: TASK=bench TEMPLATE=benchmark/etc/attribute_builder.haml
|
32
|
-
- rvm: 2.
|
34
|
+
- rvm: 2.7.0
|
33
35
|
env: TASK=bench TEMPLATE=benchmark/etc/static_analyzer.haml
|
34
|
-
- rvm: 2.
|
36
|
+
- rvm: 2.7.0
|
35
37
|
env: TASK=bench TEMPLATE=benchmark/etc/string_interpolation.haml
|
36
|
-
- rvm: 2.
|
38
|
+
- rvm: 2.7.0
|
37
39
|
env: TASK=bench TEMPLATE=test/haml/templates/standard.haml COMPILE=1
|
38
40
|
allow_failures:
|
39
41
|
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,22 @@ All notable changes to this project will be documented in this file. This
|
|
4
4
|
project adheres to [Semantic Versioning](http://semver.org/). This change log is based upon
|
5
5
|
[keep-a-changelog](https://github.com/olivierlacan/keep-a-changelog).
|
6
6
|
|
7
|
-
## [2.
|
7
|
+
## [2.12.0](https://github.com/k0kubun/hamlit/compare/v2.11.1...v2.12.0) - 2020-09-30
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
|
11
|
+
- Class names are no longer ordered alphabetically
|
12
|
+
*Thanks to @aliismayilov*
|
13
|
+
- This is compatible with [Haml 5.2](https://github.com/haml/haml/blob/v5.2.0/CHANGELOG.md#52)
|
14
|
+
|
15
|
+
## [2.11.1](https://github.com/k0kubun/hamlit/compare/v2.11.0...v2.11.1) - 2020-08-25
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- Fix a line number on an error after filters like preserve, plain, and ruby.
|
20
|
+
*Thanks to @rgisiger*
|
21
|
+
|
22
|
+
## [2.11.0](https://github.com/k0kubun/hamlit/compare/v2.10.1...v2.11.0) - 2019-12-12
|
8
23
|
|
9
24
|
### Added
|
10
25
|
|
data/Gemfile
CHANGED
@@ -8,10 +8,6 @@ end
|
|
8
8
|
# Specify your gem's dependencies in hamlit.gemspec
|
9
9
|
gemspec
|
10
10
|
|
11
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
|
12
|
-
gem 'rack', '< 2'
|
13
|
-
end
|
14
|
-
|
15
11
|
gem 'benchmark-ips', '2.3.0'
|
16
12
|
gem 'maxitest'
|
17
13
|
gem 'pry'
|
@@ -22,9 +18,7 @@ else
|
|
22
18
|
gem 'redcarpet'
|
23
19
|
|
24
20
|
if RUBY_PLATFORM !~ /mswin|mingw/ && RUBY_ENGINE != 'truffleruby'
|
25
|
-
|
26
|
-
gem 'faml'
|
27
|
-
end
|
21
|
+
gem 'faml'
|
28
22
|
gem 'stackprof'
|
29
23
|
end
|
30
24
|
end
|
data/REFERENCE.md
CHANGED
@@ -122,10 +122,10 @@ and merging multiple ids results in concatenation by "\_".
|
|
122
122
|
%div{ id: false }
|
123
123
|
|
124
124
|
# Output
|
125
|
-
<div id='foo_bar'></
|
126
|
-
<div id='foo_bar'></
|
127
|
-
<div id='foo_bar'></
|
128
|
-
<div id=''></
|
125
|
+
<div id='foo_bar'></div>
|
126
|
+
<div id='foo_bar'></div>
|
127
|
+
<div id='foo_bar'></div>
|
128
|
+
<div id=''></div>
|
129
129
|
```
|
130
130
|
|
131
131
|
### class attribute
|
data/ext/hamlit/hamlit.c
CHANGED
@@ -47,7 +47,7 @@ module Hamlit::AttributeBuilder
|
|
47
47
|
when value.is_a?(String)
|
48
48
|
# noop
|
49
49
|
when value.is_a?(Array)
|
50
|
-
value = value.flatten.select { |v| v }.map(&:to_s).
|
50
|
+
value = value.flatten.select { |v| v }.map(&:to_s).uniq.join(' ')
|
51
51
|
when value
|
52
52
|
value = value.to_s
|
53
53
|
else
|
@@ -67,7 +67,7 @@ module Hamlit::AttributeBuilder
|
|
67
67
|
classes << value.to_s
|
68
68
|
end
|
69
69
|
end
|
70
|
-
escape_html(escape_attrs, classes.map(&:to_s).
|
70
|
+
escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
|
71
71
|
end
|
72
72
|
|
73
73
|
def build_data(escape_attrs, quote, *hashes)
|
@@ -17,7 +17,7 @@ module Hamlit
|
|
17
17
|
if node.value[:object_ref] != :nil || !Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
|
18
18
|
return runtime_compile(node)
|
19
19
|
end
|
20
|
-
node.value[:
|
20
|
+
[node.value[:dynamic_attributes].new, node.value[:dynamic_attributes].old].compact.each do |attribute_str|
|
21
21
|
hash = AttributeParser.parse(attribute_str)
|
22
22
|
return runtime_compile(node) unless hash
|
23
23
|
hashes << hash
|
@@ -28,11 +28,11 @@ module Hamlit
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def runtime_compile(node)
|
31
|
-
attrs =
|
31
|
+
attrs = []
|
32
32
|
attrs.unshift(node.value[:attributes].inspect) if node.value[:attributes] != {}
|
33
33
|
|
34
34
|
args = [@escape_attrs.inspect, "#{@quote.inspect}.freeze", @format.inspect].push(node.value[:object_ref]) + attrs
|
35
|
-
[:html, :attrs, [:dynamic, "::Hamlit::AttributeBuilder.build(#{args.join(', ')})"]]
|
35
|
+
[:html, :attrs, [:dynamic, "::Hamlit::AttributeBuilder.build(#{args.join(', ')}, #{node.value[:dynamic_attributes].to_literal})"]]
|
36
36
|
end
|
37
37
|
|
38
38
|
def static_compile(static_hash, dynamic_hashes)
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'hamlit/temple_line_counter'
|
3
|
+
|
2
4
|
module Hamlit
|
3
5
|
class Compiler
|
4
6
|
class ChildrenCompiler
|
@@ -14,7 +16,7 @@ module Hamlit
|
|
14
16
|
node.children.each do |n|
|
15
17
|
rstrip_whitespace!(temple) if nuke_prev_whitespace?(n)
|
16
18
|
insert_newlines!(temple, n)
|
17
|
-
temple <<
|
19
|
+
temple << moving_lineno(n) { block.call(n) }
|
18
20
|
temple << :whitespace if insert_whitespace?(n)
|
19
21
|
end
|
20
22
|
rstrip_whitespace!(temple) if nuke_inner_whitespace?(node)
|
@@ -27,19 +29,31 @@ module Hamlit
|
|
27
29
|
(node.line - @lineno).times do
|
28
30
|
temple << [:newline]
|
29
31
|
end
|
32
|
+
|
30
33
|
@lineno = node.line
|
34
|
+
end
|
31
35
|
|
36
|
+
def moving_lineno(node, &block)
|
37
|
+
# before: As they may have children, we need to increment lineno before compilation.
|
32
38
|
case node.type
|
33
39
|
when :script, :silent_script
|
34
40
|
@lineno += 1
|
35
|
-
when :filter
|
36
|
-
@lineno += (node.value[:text] || '').split("\n").size
|
37
41
|
when :tag
|
38
|
-
node.value[:
|
42
|
+
[node.value[:dynamic_attributes].new, node.value[:dynamic_attributes].old].compact.each do |attribute_hash|
|
39
43
|
@lineno += attribute_hash.count("\n")
|
40
44
|
end
|
41
45
|
@lineno += 1 if node.children.empty? && node.value[:parse]
|
42
46
|
end
|
47
|
+
|
48
|
+
temple = block.call # compile
|
49
|
+
|
50
|
+
# after: filter may not have children, and for some dynamic filters we can't predict the number of lines.
|
51
|
+
case node.type
|
52
|
+
when :filter
|
53
|
+
@lineno += TempleLineCounter.count_lines(temple)
|
54
|
+
end
|
55
|
+
|
56
|
+
temple
|
43
57
|
end
|
44
58
|
|
45
59
|
def confirm_whitespace(temple)
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hamlit
|
4
|
+
module HamlAttributeBuilder
|
5
|
+
# https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
|
6
|
+
INVALID_ATTRIBUTE_NAME_REGEX = /[ \0"'>\/=]/
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def build_attributes(is_html, attr_wrapper, escape_attrs, hyphenate_data_attrs, attributes = {})
|
10
|
+
# @TODO this is an absolutely ridiculous amount of arguments. At least
|
11
|
+
# some of this needs to be moved into an instance method.
|
12
|
+
join_char = hyphenate_data_attrs ? '-' : '_'
|
13
|
+
|
14
|
+
attributes.each do |key, value|
|
15
|
+
if value.is_a?(Hash)
|
16
|
+
data_attributes = attributes.delete(key)
|
17
|
+
data_attributes = flatten_data_attributes(data_attributes, '', join_char)
|
18
|
+
data_attributes = build_data_keys(data_attributes, hyphenate_data_attrs, key)
|
19
|
+
verify_attribute_names!(data_attributes.keys)
|
20
|
+
attributes = data_attributes.merge(attributes)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
result = attributes.collect do |attr, value|
|
25
|
+
next if value.nil?
|
26
|
+
|
27
|
+
value = filter_and_join(value, ' ') if attr == 'class'
|
28
|
+
value = filter_and_join(value, '_') if attr == 'id'
|
29
|
+
|
30
|
+
if value == true
|
31
|
+
next " #{attr}" if is_html
|
32
|
+
next " #{attr}=#{attr_wrapper}#{attr}#{attr_wrapper}"
|
33
|
+
elsif value == false
|
34
|
+
next
|
35
|
+
end
|
36
|
+
|
37
|
+
value =
|
38
|
+
if escape_attrs == :once
|
39
|
+
Hamlit::HamlHelpers.escape_once_without_haml_xss(value.to_s)
|
40
|
+
elsif escape_attrs
|
41
|
+
Hamlit::HamlHelpers.html_escape_without_haml_xss(value.to_s)
|
42
|
+
else
|
43
|
+
value.to_s
|
44
|
+
end
|
45
|
+
" #{attr}=#{attr_wrapper}#{value}#{attr_wrapper}"
|
46
|
+
end
|
47
|
+
result.compact!
|
48
|
+
result.sort!
|
49
|
+
result.join
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String, nil]
|
53
|
+
def filter_and_join(value, separator)
|
54
|
+
return '' if (value.respond_to?(:empty?) && value.empty?)
|
55
|
+
|
56
|
+
if value.is_a?(Array)
|
57
|
+
value = value.flatten
|
58
|
+
value.map! {|item| item ? item.to_s : nil}
|
59
|
+
value.compact!
|
60
|
+
value = value.join(separator)
|
61
|
+
else
|
62
|
+
value = value ? value.to_s : nil
|
63
|
+
end
|
64
|
+
!value.nil? && !value.empty? && value
|
65
|
+
end
|
66
|
+
|
67
|
+
# Merges two attribute hashes.
|
68
|
+
# This is the same as `to.merge!(from)`,
|
69
|
+
# except that it merges id, class, and data attributes.
|
70
|
+
#
|
71
|
+
# ids are concatenated with `"_"`,
|
72
|
+
# and classes are concatenated with `" "`.
|
73
|
+
# data hashes are simply merged.
|
74
|
+
#
|
75
|
+
# Destructively modifies `to`.
|
76
|
+
#
|
77
|
+
# @param to [{String => String,Hash}] The attribute hash to merge into
|
78
|
+
# @param from [{String => Object}] The attribute hash to merge from
|
79
|
+
# @return [{String => String,Hash}] `to`, after being merged
|
80
|
+
def merge_attributes!(to, from)
|
81
|
+
from.keys.each do |key|
|
82
|
+
to[key] = merge_value(key, to[key], from[key])
|
83
|
+
end
|
84
|
+
to
|
85
|
+
end
|
86
|
+
|
87
|
+
# Merge multiple values to one attribute value. No destructive operation.
|
88
|
+
#
|
89
|
+
# @param key [String]
|
90
|
+
# @param values [Array<Object>]
|
91
|
+
# @return [String,Hash]
|
92
|
+
def merge_values(key, *values)
|
93
|
+
values.inject(nil) do |to, from|
|
94
|
+
merge_value(key, to, from)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def verify_attribute_names!(attribute_names)
|
99
|
+
attribute_names.each do |attribute_name|
|
100
|
+
if attribute_name =~ INVALID_ATTRIBUTE_NAME_REGEX
|
101
|
+
raise InvalidAttributeNameError.new("Invalid attribute name '#{attribute_name}' was rendered")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# Merge a couple of values to one attribute value. No destructive operation.
|
109
|
+
#
|
110
|
+
# @param to [String,Hash,nil]
|
111
|
+
# @param from [Object]
|
112
|
+
# @return [String,Hash]
|
113
|
+
def merge_value(key, to, from)
|
114
|
+
if from.kind_of?(Hash) || to.kind_of?(Hash)
|
115
|
+
from = { nil => from } if !from.is_a?(Hash)
|
116
|
+
to = { nil => to } if !to.is_a?(Hash)
|
117
|
+
to.merge(from)
|
118
|
+
elsif key == 'id'
|
119
|
+
merged_id = filter_and_join(from, '_')
|
120
|
+
if to && merged_id
|
121
|
+
merged_id = "#{to}_#{merged_id}"
|
122
|
+
elsif to || merged_id
|
123
|
+
merged_id ||= to
|
124
|
+
end
|
125
|
+
merged_id
|
126
|
+
elsif key == 'class'
|
127
|
+
merged_class = filter_and_join(from, ' ')
|
128
|
+
if to && merged_class
|
129
|
+
merged_class = (to.split(' ') | merged_class.split(' ')).join(' ')
|
130
|
+
elsif to || merged_class
|
131
|
+
merged_class ||= to
|
132
|
+
end
|
133
|
+
merged_class
|
134
|
+
else
|
135
|
+
from
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def build_data_keys(data_hash, hyphenate, attr_name="data")
|
140
|
+
Hash[data_hash.map do |name, value|
|
141
|
+
if name == nil
|
142
|
+
[attr_name, value]
|
143
|
+
elsif hyphenate
|
144
|
+
["#{attr_name}-#{name.to_s.tr('_', '-')}", value]
|
145
|
+
else
|
146
|
+
["#{attr_name}-#{name}", value]
|
147
|
+
end
|
148
|
+
end]
|
149
|
+
end
|
150
|
+
|
151
|
+
def flatten_data_attributes(data, key, join_char, seen = [])
|
152
|
+
return {key => data} unless data.is_a?(Hash)
|
153
|
+
|
154
|
+
return {key => nil} if seen.include? data.object_id
|
155
|
+
seen << data.object_id
|
156
|
+
|
157
|
+
data.sort {|x, y| x[0].to_s <=> y[0].to_s}.inject({}) do |hash, (k, v)|
|
158
|
+
joined = key == '' ? k : [key, k].join(join_char)
|
159
|
+
hash.merge! flatten_data_attributes(v, joined, join_char, seen)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -617,6 +617,9 @@ MESSAGE
|
|
617
617
|
text.gsub(HTML_ESCAPE_REGEX, HTML_ESCAPE)
|
618
618
|
end
|
619
619
|
|
620
|
+
# Always escape text regardless of html_safe?
|
621
|
+
alias_method :html_escape_without_haml_xss, :html_escape
|
622
|
+
|
620
623
|
HTML_ESCAPE_ONCE_REGEX = /[\"><]|&(?!(?:[a-zA-Z]+|#(?:\d+|[xX][0-9a-fA-F]+));)/
|
621
624
|
|
622
625
|
# Escapes HTML entities in `text`, but without escaping an ampersand
|
@@ -629,6 +632,9 @@ MESSAGE
|
|
629
632
|
text.gsub(HTML_ESCAPE_ONCE_REGEX, HTML_ESCAPE)
|
630
633
|
end
|
631
634
|
|
635
|
+
# Always escape text once regardless of html_safe?
|
636
|
+
alias_method :escape_once_without_haml_xss, :escape_once
|
637
|
+
|
632
638
|
# Returns whether or not the current template is a Haml template.
|
633
639
|
#
|
634
640
|
# This function, unlike other {Haml::Helpers} functions,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'strscan'
|
2
2
|
require 'hamlit/parser/haml_util'
|
3
3
|
require 'hamlit/parser/haml_error'
|
4
|
+
require 'hamlit/parser/haml_attribute_builder'
|
4
5
|
|
5
6
|
module Hamlit
|
6
7
|
class HamlParser
|
@@ -206,6 +207,31 @@ module Hamlit
|
|
206
207
|
end
|
207
208
|
end
|
208
209
|
|
210
|
+
# @param [String] new - Hash literal including dynamic values.
|
211
|
+
# @param [String] old - Hash literal including dynamic values or Ruby literal of multiple Hashes which MUST be interpreted as method's last arguments.
|
212
|
+
DynamicAttributes = Struct.new(:new, :old) do
|
213
|
+
undef :old=
|
214
|
+
def old=(value)
|
215
|
+
unless value =~ /\A{.*}\z/m
|
216
|
+
raise ArgumentError.new('Old attributes must start with "{" and end with "}"')
|
217
|
+
end
|
218
|
+
self[:old] = value
|
219
|
+
end
|
220
|
+
|
221
|
+
# This will be a literal for Haml::Buffer#attributes's last argument, `attributes_hashes`.
|
222
|
+
def to_literal
|
223
|
+
[new, stripped_old].compact.join(', ')
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
# For `%foo{ { foo: 1 }, bar: 2 }`, :old is "{ { foo: 1 }, bar: 2 }" and this method returns " { foo: 1 }, bar: 2 " for last argument.
|
229
|
+
def stripped_old
|
230
|
+
return nil if old.nil?
|
231
|
+
old.sub!(/\A{/, '').sub!(/}\z/m, '')
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
209
235
|
# Processes and deals with lowering indentation.
|
210
236
|
def process_indent(line)
|
211
237
|
return unless line.tabs <= @template_tabs && @template_tabs > 0
|
@@ -403,22 +429,20 @@ module Hamlit
|
|
403
429
|
end
|
404
430
|
|
405
431
|
attributes = ::Hamlit::HamlParser.parse_class_and_id(attributes)
|
406
|
-
|
432
|
+
dynamic_attributes = DynamicAttributes.new
|
407
433
|
|
408
434
|
if attributes_hashes[:new]
|
409
435
|
static_attributes, attributes_hash = attributes_hashes[:new]
|
410
|
-
|
411
|
-
|
436
|
+
HamlAttributeBuilder.merge_attributes!(attributes, static_attributes) if static_attributes
|
437
|
+
dynamic_attributes.new = attributes_hash
|
412
438
|
end
|
413
439
|
|
414
440
|
if attributes_hashes[:old]
|
415
441
|
static_attributes = parse_static_hash(attributes_hashes[:old])
|
416
|
-
|
417
|
-
|
442
|
+
HamlAttributeBuilder.merge_attributes!(attributes, static_attributes) if static_attributes
|
443
|
+
dynamic_attributes.old = attributes_hashes[:old] unless static_attributes || @options.suppress_eval
|
418
444
|
end
|
419
445
|
|
420
|
-
attributes_list.compact!
|
421
|
-
|
422
446
|
raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_self_closing), @next_line.index) if block_opened? && self_closing
|
423
447
|
raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:no_ruby_code, action), last_line - 1) if parse && value.empty?
|
424
448
|
raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:self_closing_content), last_line - 1) if self_closing && !value.empty?
|
@@ -433,7 +457,7 @@ module Hamlit
|
|
433
457
|
line = handle_ruby_multiline(line) if parse
|
434
458
|
|
435
459
|
ParseNode.new(:tag, line.index + 1, :name => tag_name, :attributes => attributes,
|
436
|
-
:
|
460
|
+
:dynamic_attributes => dynamic_attributes, :self_closing => self_closing,
|
437
461
|
:nuke_inner_whitespace => nuke_inner_whitespace,
|
438
462
|
:nuke_outer_whitespace => nuke_outer_whitespace, :object_ref => object_ref,
|
439
463
|
:escape_html => escape_html, :preserve_tag => preserve_tag,
|
@@ -641,7 +665,6 @@ module Hamlit
|
|
641
665
|
raise e
|
642
666
|
end
|
643
667
|
|
644
|
-
attributes_hash = attributes_hash[1...-1] if attributes_hash
|
645
668
|
return attributes_hash, rest, last_line
|
646
669
|
end
|
647
670
|
|
@@ -6,12 +6,15 @@ module Hamlit
|
|
6
6
|
# to work with Rails' XSS protection methods.
|
7
7
|
module XssMods
|
8
8
|
def self.included(base)
|
9
|
-
%w[
|
10
|
-
precede succeed capture_haml haml_concat haml_internal_concat haml_indent
|
11
|
-
escape_once].each do |name|
|
9
|
+
%w[find_and_preserve preserve list_of surround
|
10
|
+
precede succeed capture_haml haml_concat haml_internal_concat haml_indent].each do |name|
|
12
11
|
base.send(:alias_method, "#{name}_without_haml_xss", name)
|
13
12
|
base.send(:alias_method, name, "#{name}_with_haml_xss")
|
14
13
|
end
|
14
|
+
# Those two always have _without_haml_xss
|
15
|
+
%w[html_escape escape_once].each do |name|
|
16
|
+
base.send(:alias_method, name, "#{name}_with_haml_xss")
|
17
|
+
end
|
15
18
|
end
|
16
19
|
|
17
20
|
# Don't escape text that's already safe,
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hamlit
|
3
|
+
# A module to count lines of expected code. This would be faster than actual code generation
|
4
|
+
# and counting newlines in it.
|
5
|
+
module TempleLineCounter
|
6
|
+
class UnexpectedExpression < StandardError; end
|
7
|
+
|
8
|
+
def self.count_lines(exp)
|
9
|
+
type, *args = exp
|
10
|
+
case type
|
11
|
+
when :multi
|
12
|
+
args.map { |a| count_lines(a) }.reduce(:+) || 0
|
13
|
+
when :dynamic, :code
|
14
|
+
args.first.count("\n")
|
15
|
+
when :static
|
16
|
+
0 # It has not real newline "\n" but escaped "\\n".
|
17
|
+
when :case
|
18
|
+
arg, *cases = args
|
19
|
+
arg.count("\n") + cases.map do |cond, e|
|
20
|
+
(cond == :else ? 0 : cond.count("\n")) + count_lines(e)
|
21
|
+
end.reduce(:+)
|
22
|
+
when :escape
|
23
|
+
count_lines(args[1])
|
24
|
+
when :newline
|
25
|
+
1
|
26
|
+
else
|
27
|
+
raise UnexpectedExpression.new("[HAML BUG] Unexpected Temple expression '#{type}' is given!")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/hamlit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hamlit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -17,8 +17,8 @@ dependencies:
|
|
17
17
|
- !ruby/object:Gem::Version
|
18
18
|
version: 0.8.2
|
19
19
|
name: temple
|
20
|
-
prerelease: false
|
21
20
|
type: :runtime
|
21
|
+
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
@@ -31,8 +31,8 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '0'
|
33
33
|
name: thor
|
34
|
-
prerelease: false
|
35
34
|
type: :runtime
|
35
|
+
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
@@ -45,8 +45,8 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
name: tilt
|
48
|
-
prerelease: false
|
49
48
|
type: :runtime
|
49
|
+
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
@@ -59,8 +59,8 @@ dependencies:
|
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
61
|
name: benchmark_driver
|
62
|
-
prerelease: false
|
63
62
|
type: :development
|
63
|
+
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
@@ -73,8 +73,8 @@ dependencies:
|
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
75
|
name: bundler
|
76
|
-
prerelease: false
|
77
76
|
type: :development
|
77
|
+
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
@@ -87,8 +87,8 @@ dependencies:
|
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
89
|
name: coffee-script
|
90
|
-
prerelease: false
|
91
90
|
type: :development
|
91
|
+
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
@@ -101,8 +101,8 @@ dependencies:
|
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '0'
|
103
103
|
name: erubi
|
104
|
-
prerelease: false
|
105
104
|
type: :development
|
105
|
+
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - ">="
|
@@ -115,8 +115,8 @@ dependencies:
|
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '5'
|
117
117
|
name: haml
|
118
|
-
prerelease: false
|
119
118
|
type: :development
|
119
|
+
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
@@ -129,8 +129,8 @@ dependencies:
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
name: less
|
132
|
-
prerelease: false
|
133
132
|
type: :development
|
133
|
+
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - ">="
|
@@ -143,8 +143,8 @@ dependencies:
|
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '1.1'
|
145
145
|
name: minitest-reporters
|
146
|
-
prerelease: false
|
147
146
|
type: :development
|
147
|
+
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
@@ -157,8 +157,8 @@ dependencies:
|
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: 4.0.0
|
159
159
|
name: rails
|
160
|
-
prerelease: false
|
161
160
|
type: :development
|
161
|
+
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - ">="
|
@@ -171,8 +171,8 @@ dependencies:
|
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: '0'
|
173
173
|
name: rake
|
174
|
-
prerelease: false
|
175
174
|
type: :development
|
175
|
+
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - ">="
|
@@ -185,8 +185,8 @@ dependencies:
|
|
185
185
|
- !ruby/object:Gem::Version
|
186
186
|
version: '0'
|
187
187
|
name: rake-compiler
|
188
|
-
prerelease: false
|
189
188
|
type: :development
|
189
|
+
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
192
|
- - ">="
|
@@ -199,8 +199,8 @@ dependencies:
|
|
199
199
|
- !ruby/object:Gem::Version
|
200
200
|
version: '0'
|
201
201
|
name: sass
|
202
|
-
prerelease: false
|
203
202
|
type: :development
|
203
|
+
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
206
|
- - ">="
|
@@ -213,8 +213,8 @@ dependencies:
|
|
213
213
|
- !ruby/object:Gem::Version
|
214
214
|
version: '0'
|
215
215
|
name: slim
|
216
|
-
prerelease: false
|
217
216
|
type: :development
|
217
|
+
prerelease: false
|
218
218
|
version_requirements: !ruby/object:Gem::Requirement
|
219
219
|
requirements:
|
220
220
|
- - ">="
|
@@ -227,8 +227,8 @@ dependencies:
|
|
227
227
|
- !ruby/object:Gem::Version
|
228
228
|
version: '0'
|
229
229
|
name: string_template
|
230
|
-
prerelease: false
|
231
230
|
type: :development
|
231
|
+
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
234
|
- - ">="
|
@@ -241,8 +241,8 @@ dependencies:
|
|
241
241
|
- !ruby/object:Gem::Version
|
242
242
|
version: '0'
|
243
243
|
name: unindent
|
244
|
-
prerelease: false
|
245
244
|
type: :development
|
245
|
+
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
248
|
- - ">="
|
@@ -349,6 +349,7 @@ files:
|
|
349
349
|
- lib/hamlit/parser.rb
|
350
350
|
- lib/hamlit/parser/MIT-LICENSE
|
351
351
|
- lib/hamlit/parser/README.md
|
352
|
+
- lib/hamlit/parser/haml_attribute_builder.rb
|
352
353
|
- lib/hamlit/parser/haml_buffer.rb
|
353
354
|
- lib/hamlit/parser/haml_compiler.rb
|
354
355
|
- lib/hamlit/parser/haml_error.rb
|
@@ -363,6 +364,7 @@ files:
|
|
363
364
|
- lib/hamlit/ruby_expression.rb
|
364
365
|
- lib/hamlit/string_splitter.rb
|
365
366
|
- lib/hamlit/template.rb
|
367
|
+
- lib/hamlit/temple_line_counter.rb
|
366
368
|
- lib/hamlit/utils.rb
|
367
369
|
- lib/hamlit/version.rb
|
368
370
|
homepage: https://github.com/k0kubun/hamlit
|
@@ -384,8 +386,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
384
386
|
- !ruby/object:Gem::Version
|
385
387
|
version: '0'
|
386
388
|
requirements: []
|
387
|
-
|
388
|
-
rubygems_version: 2.7.9
|
389
|
+
rubygems_version: 3.0.6
|
389
390
|
signing_key:
|
390
391
|
specification_version: 4
|
391
392
|
summary: High Performance Haml Implementation
|