haml 6.0.8 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ff76f0fdc08205d557aad04a3701f7aad3df7badb119afe88c3a538fad318e8
4
- data.tar.gz: a9bae0ed0aab397b6718df223ae9d093c94b349ecf1a0c0306d7faa446c53e3f
3
+ metadata.gz: 1c6e33698052b2d1823959741be8219446b8b3257f5124449daa8cd8deb70e4a
4
+ data.tar.gz: d2a168766babc32a3f83b065e6d158e5b937995cdd5a46552fb95d4035ad5924
5
5
  SHA512:
6
- metadata.gz: bdd2458541e841265ae99d5825a5d76fab8b977d8fd38ae110e19b73dbd1059616de97e6963d5feb42f15cc5b7648887646f4f6a17ec4fbe6aec883ef61865a6
7
- data.tar.gz: c3dd71673d91323183695d6d734102422caabad995b76574a7a11ec59703cfc31302df250f6a679e974c7f4f6be50eff6b44c06a0ad45a2d47257a259de07af8
6
+ metadata.gz: c6d71bcdb86f5281b34c9f56684263db88e947b17c8d79eb764b6ecb8f17945ad7fc374b2ad8032066b0c7ae52e3c0045de3658b76fc073e5ee8ab73e3c7eae3
7
+ data.tar.gz: 408d9dd0b14378515d175778a9d9b472b70819c2371189aa145d2e787590213f453bba60e6dec2aee5aadf9e7bc0fd6c4b077f96676c9b6e899896ce60eb07cc
data/.github/FUNDING.yml CHANGED
@@ -1 +1,3 @@
1
- github: haml
1
+ github:
2
+ - haml
3
+ - k0kubun
@@ -14,6 +14,7 @@ jobs:
14
14
  test:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
+ fail-fast: false
17
18
  matrix:
18
19
  ruby:
19
20
  - '2.5'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Haml Changelog
2
2
 
3
+ ## 6.1.1
4
+
5
+ * Fix an empty output of Ruby 3.1's Hash shorthand syntax [#1083](https://github.com/haml/haml/issues/1083)
6
+
7
+ ## 6.1.0
8
+
9
+ * Optimize away a `to_s` call on `=` scripts
10
+ * Fix escaping for objects that return an `html_safe` string on `to_s` [#1117](https://github.com/haml/haml/issues/1117)
11
+
12
+ ## 6.0.12
13
+
14
+ * Fix a whitespace removal with `>` and an `if`-`else` statement [#1114](https://github.com/haml/haml/issues/1114)
15
+
16
+ ## 6.0.11
17
+
18
+ * Fix a whitespace removal with `>` and an `if` statement [#1114](https://github.com/haml/haml/issues/1114)
19
+
20
+ ## 6.0.10
21
+
22
+ * Evaluate :erb filter in the template context like Haml 5
23
+
24
+ ## 6.0.9
25
+
26
+ * Support sass-embedded [#1112](https://github.com/haml/haml/issues/1112)
27
+
3
28
  ## 6.0.8
4
29
 
5
30
  * Support interpolation in HTML comments, which has not been working since 6.0.0
@@ -63,6 +88,8 @@ Released on September 21, 2022
63
88
  * The parser is kept as is, but everything else is replaced.
64
89
  * The `haml` CLI interface was also replaced.
65
90
  * The interface of `Haml::Engine` is changed. `Haml::Template` is most likely what you need now.
91
+ * before: `Haml::Engine.new("%p Haml code!").render`
92
+ * after: `Haml::Template.new { "%p Haml code!" }.render`
66
93
  * Most Haml helpers are removed.
67
94
  * Rails:
68
95
  * Kept: `find_and_reserve`, `preserve`, `surround`, `precede`, `succeed`, `capture_haml`
@@ -78,11 +105,14 @@ Released on September 21, 2022
78
105
  `defer`, `disabled`, `download`, `formnovalidate`, `hidden`, `inert`, `ismap`, `itemscope`, `loop`,
79
106
  `multiple`, `muted`, `novalidate`, `open`, `pubdate`, `readonly`, `required`, `reversed`, `scoped`,
80
107
  `seamless`, `selected`, `sortable`, `truespeed`, `typemustmatch`
108
+ * Only `data` and `aria` attributes support using a nested Hash to render hyphenated attributes, e.g.
109
+ `data: { foo: 'bar' }` becomes `data-foo="bar"`, but this no longer works for non-`data`/`aria` attributes.
81
110
  * Some legacy Rails integration is removed.
82
111
  * The default value of `escape_html` option became true.
83
112
  * `-` script lines no longer support capturing. Only `=` lines are supported to yield a nested block.
84
113
  * Overriding `data` attributes with another falsy `data-*` attribute that has the same name
85
114
  is no longer supported. [#1105](https://github.com/haml/haml/issues/1105)
115
+ * :erb filter is not executed in the template context (fixed in 6.0.10)
86
116
 
87
117
  ## 5.2.2
88
118
 
data/REFERENCE.md CHANGED
@@ -338,20 +338,19 @@ will render as:
338
338
  <a> tag is so old links to here still work. -->
339
339
  <a id="html5_custom_data_attributes" style="border:0;"></a>
340
340
 
341
- #### Prefixed Attributes
341
+ #### Data Attributes
342
342
 
343
343
  HTML5 allows for adding
344
344
  [custom non-visible data attributes](http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
345
345
  to elements using attribute names beginning with `data-`. The
346
346
  [Accessible Rich Internet Applications](http://www.w3.org/WAI/intro/aria)
347
- specification makes use of attributes beginning with `aria-`. There are also
348
- frameworks that use non-standard attributes with a common prefix.
347
+ specification makes use of attributes beginning with `aria-`.
349
348
 
350
349
  Haml can help generate collections of attributes that share a prefix like
351
- these. Any entry in an attribute hash that has a Hash as its value is expanded
352
- into a series of attributes, one for each key/value pair in the hash, with the
353
- attribute name formed by joining the “parent” key name to the key name with a
354
- hyphen.
350
+ these. Any entry in an `data` or `aria` attribute hash that has a Hash as its
351
+ value is expanded into a series of attributes, one for each key/value pair in
352
+ the hash, with the attribute name formed by joining the “parent” key name to
353
+ the key name with a hyphen. This works only for `data` or `aria`.
355
354
 
356
355
  For example:
357
356
 
@@ -19,7 +19,7 @@ module Haml
19
19
  end
20
20
  [node.value[:dynamic_attributes].new, node.value[:dynamic_attributes].old].compact.each do |attribute_str|
21
21
  hash = AttributeParser.parse(attribute_str)
22
- return runtime_compile(node) unless hash
22
+ return runtime_compile(node) if hash.nil? || hash.any? { |_key, value| value.empty? }
23
23
  hashes << hash
24
24
  end
25
25
  static_compile(node.value[:attributes], hashes)
@@ -6,21 +6,22 @@ module Haml
6
6
  class ChildrenCompiler
7
7
  def initialize
8
8
  @lineno = 1
9
+ @multi_flattener = Temple::Filters::MultiFlattener.new
9
10
  end
10
11
 
11
12
  def compile(node, &block)
12
13
  temple = [:multi]
13
14
  return temple if node.children.empty?
14
15
 
15
- temple << :whitespace if prepend_whitespace?(node)
16
+ temple << [:whitespace] if prepend_whitespace?(node)
16
17
  node.children.each do |n|
17
18
  rstrip_whitespace!(temple) if nuke_prev_whitespace?(n)
18
19
  insert_newlines!(temple, n)
19
20
  temple << moving_lineno(n) { block.call(n) }
20
- temple << :whitespace if insert_whitespace?(n)
21
+ temple << [:whitespace] if insert_whitespace?(n)
21
22
  end
22
23
  rstrip_whitespace!(temple) if nuke_inner_whitespace?(node)
23
- confirm_whitespace(temple)
24
+ temple
24
25
  end
25
26
 
26
27
  private
@@ -56,17 +57,6 @@ module Haml
56
57
  temple
57
58
  end
58
59
 
59
- def confirm_whitespace(temple)
60
- temple.map do |exp|
61
- case exp
62
- when :whitespace
63
- [:static, "\n"]
64
- else
65
- exp
66
- end
67
- end
68
- end
69
-
70
60
  def prepend_whitespace?(node)
71
61
  return false unless %i[comment tag].include?(node.type)
72
62
  !nuke_inner_whitespace?(node)
@@ -100,9 +90,48 @@ module Haml
100
90
  end
101
91
 
102
92
  def rstrip_whitespace!(temple)
103
- if temple[-1] == :whitespace
104
- temple.delete_at(-1)
93
+ return if temple.size == 1
94
+
95
+ case temple[0]
96
+ when :multi
97
+ case temple[-1][0]
98
+ when :whitespace
99
+ temple.delete_at(-1)
100
+ when :multi, :block
101
+ rstrip_whitespace!(temple[-1])
102
+ end
103
+ when :block
104
+ _block, code, exp = temple
105
+ if code.start_with?(/\s*if\s/)
106
+ # Remove [:whitespace] before `end`
107
+ exp.replace(@multi_flattener.call(exp))
108
+ rstrip_whitespace!(exp)
109
+
110
+ # Remove [:whitespace] before `else` if exists
111
+ else_index = find_else_index(exp)
112
+ if else_index
113
+ whitespace_index = else_index - 1
114
+ while exp[whitespace_index] == [:newline]
115
+ whitespace_index -= 1
116
+ end
117
+ if exp[whitespace_index] == [:whitespace]
118
+ exp.delete_at(whitespace_index)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ def find_else_index(temple)
126
+ multi, *args = temple
127
+ return nil if multi != :multi
128
+
129
+ args.each_with_index do |arg, index|
130
+ if arg[0] == :code && arg[1].match?(/\A\s*else\s*\z/)
131
+ return index + 1
132
+ end
105
133
  end
134
+ nil
106
135
  end
107
136
 
108
137
  def insert_whitespace?(node)
@@ -98,10 +98,8 @@ module Haml
98
98
  def compile_script_result(result, node)
99
99
  if !node.value[:escape_html] && node.value[:preserve]
100
100
  result = find_and_preserve(result)
101
- else
102
- result = "(#{result}).to_s"
103
101
  end
104
- [:escape, node.value[:escape_html], [:dynamic, result]]
102
+ [:escapeany, node.value[:escape_html], [:dynamic, result]]
105
103
  end
106
104
 
107
105
  def find_and_preserve(code)
data/lib/haml/engine.rb CHANGED
@@ -4,10 +4,12 @@ require 'haml/parser'
4
4
  require 'haml/compiler'
5
5
  require 'haml/html'
6
6
  require 'haml/string_splitter'
7
- require 'haml/escapable'
8
- require 'haml/force_escapable'
7
+ require 'haml/escape'
8
+ require 'haml/escape_any'
9
+ require 'haml/force_escape'
9
10
  require 'haml/dynamic_merger'
10
11
  require 'haml/ambles'
12
+ require 'haml/whitespace'
11
13
 
12
14
  module Haml
13
15
  class Engine < Temple::Engine
@@ -31,11 +33,13 @@ module Haml
31
33
  use HTML
32
34
  use StringSplitter
33
35
  filter :StaticAnalyzer
34
- use Escapable
35
- use ForceEscapable
36
+ use Escape
37
+ use EscapeAny
38
+ use ForceEscape
36
39
  filter :ControlFlow
37
40
  use Ambles
38
41
  filter :MultiFlattener
42
+ use Whitespace
39
43
  filter :StaticMerger
40
44
  use DynamicMerger
41
45
  use :Generator, -> { options[:generator] }
@@ -2,7 +2,7 @@
2
2
  require 'haml/util'
3
3
 
4
4
  module Haml
5
- class Escapable < Temple::Filters::Escapable
5
+ class Escape < Temple::Filters::Escapable
6
6
  def initialize(opts = {})
7
7
  super
8
8
  @escape_code = options[:escape_code] ||
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ require 'haml/escape'
3
+
4
+ module Haml
5
+ # This module allows Temple::Filter to dispatch :fescape on `#compile`.
6
+ module EscapeanyDispathcer
7
+ def on_escapeany(flag, exp)
8
+ [:escapeany, flag, compile(exp)]
9
+ end
10
+ end
11
+ ::Temple::Filter.include EscapeanyDispathcer
12
+
13
+ # Unlike Haml::Escape, this calls to_s when not escaped.
14
+ class EscapeAny < Escape
15
+ alias_method :on_escapeany, :on_escape
16
+
17
+ def on_dynamic(value)
18
+ [:dynamic, @escape ? @escape_code % value : "(#{value}).to_s"]
19
+ end
20
+ end
21
+ end
@@ -3,7 +3,7 @@ module Haml
3
3
  class Filters
4
4
  class Erb < TiltBase
5
5
  def compile(node)
6
- compile_with_tilt(node, 'erb')
6
+ precompiled_with_tilt(node, 'erb')
7
7
  end
8
8
  end
9
9
  end
@@ -7,7 +7,11 @@ module Haml
7
7
  def self.render(name, source, indent_width: 0)
8
8
  text = ::Tilt["t.#{name}"].new { source }.render
9
9
  return text if indent_width == 0
10
- text.gsub!(/^/, ' ' * indent_width)
10
+ if text.frozen?
11
+ text.gsub(/^/, ' ' * indent_width)
12
+ else
13
+ text.gsub!(/^/, ' ' * indent_width)
14
+ end
11
15
  end
12
16
 
13
17
  def explicit_require?(needed_registration)
@@ -17,6 +21,12 @@ module Haml
17
21
 
18
22
  private
19
23
 
24
+ # TODO: support interpolation
25
+ def precompiled_with_tilt(node, name)
26
+ src = ::Tilt["t.#{name}"].new { node.value[:text] }.send(:precompiled, {}).first
27
+ [:dynamic, src]
28
+ end
29
+
20
30
  def compile_with_tilt(node, name, indent_width: 0)
21
31
  if ::Haml::Util.contains_interpolation?(node.value[:text])
22
32
  dynamic_compile(node, name, indent_width: indent_width)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require 'haml/escapable'
2
+ require 'haml/escape'
3
3
 
4
4
  module Haml
5
5
  # This module allows Temple::Filter to dispatch :fescape on `#compile`.
@@ -10,8 +10,8 @@ module Haml
10
10
  end
11
11
  ::Temple::Filter.include FescapeDispathcer
12
12
 
13
- # Unlike Haml::Escapable, this escapes value even if it's html_safe.
14
- class ForceEscapable < Escapable
13
+ # Unlike Haml::Escape, this escapes value even if it's html_safe.
14
+ class ForceEscape < Escape
15
15
  def initialize(opts = {})
16
16
  super
17
17
  @escape_code = options[:escape_code] || "::Haml::Util.escape_html((%s))"
@@ -20,8 +20,8 @@ module Haml
20
20
 
21
21
  alias_method :on_fescape, :on_escape
22
22
 
23
- # ForceEscapable doesn't touch :escape expression.
24
- # This method is not used if it's inserted after Haml::Escapable.
23
+ # ForceEscape doesn't touch :escape expression.
24
+ # This method is not used if it's inserted after Haml::Escape.
25
25
  def on_escape(flag, exp)
26
26
  [:escape, flag, compile(exp)]
27
27
  end
@@ -52,4 +52,6 @@ end
52
52
 
53
53
  # Haml extends Haml::Helpers in ActionView each time.
54
54
  # It costs much, so Haml includes a compatible module at first.
55
- ActionView::Base.send :include, Haml::RailsHelpers
55
+ ActiveSupport.on_load(:action_view) do
56
+ include Haml::RailsHelpers
57
+ end
data/lib/haml/util.rb CHANGED
@@ -27,6 +27,7 @@ module Haml
27
27
 
28
28
  # TODO: Remove unescape_interpolation's workaround and get rid of `respond_to?`.
29
29
  def self.escape_html_safe(html)
30
+ html = html.to_s
30
31
  (html.respond_to?(:html_safe?) && html.html_safe?) ? html : escape_html(html)
31
32
  end
32
33
 
data/lib/haml/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Haml
3
- VERSION = '6.0.8'
3
+ VERSION = '6.1.1'
4
4
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Whitespace < Temple::Filter
4
+ def on_whitespace
5
+ [:static, "\n"]
6
+ end
7
+ end
8
+ 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.0.8
4
+ version: 6.1.1
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-10-29 00:00:00.000000000 Z
15
+ date: 2022-12-10 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: temple
@@ -301,7 +301,8 @@ files:
301
301
  - lib/haml/dynamic_merger.rb
302
302
  - lib/haml/engine.rb
303
303
  - lib/haml/error.rb
304
- - lib/haml/escapable.rb
304
+ - lib/haml/escape.rb
305
+ - lib/haml/escape_any.rb
305
306
  - lib/haml/filters.rb
306
307
  - lib/haml/filters/base.rb
307
308
  - lib/haml/filters/cdata.rb
@@ -319,7 +320,7 @@ files:
319
320
  - lib/haml/filters/scss.rb
320
321
  - lib/haml/filters/text_base.rb
321
322
  - lib/haml/filters/tilt_base.rb
322
- - lib/haml/force_escapable.rb
323
+ - lib/haml/force_escape.rb
323
324
  - lib/haml/helpers.rb
324
325
  - lib/haml/html.rb
325
326
  - lib/haml/identity.rb
@@ -334,6 +335,7 @@ files:
334
335
  - lib/haml/temple_line_counter.rb
335
336
  - lib/haml/util.rb
336
337
  - lib/haml/version.rb
338
+ - lib/haml/whitespace.rb
337
339
  homepage: https://haml.info
338
340
  licenses:
339
341
  - MIT
@@ -353,7 +355,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
353
355
  - !ruby/object:Gem::Version
354
356
  version: '0'
355
357
  requirements: []
356
- rubygems_version: 3.3.7
358
+ rubygems_version: 3.4.0.dev
357
359
  signing_key:
358
360
  specification_version: 4
359
361
  summary: An elegant, structured (X)HTML/XML templating engine.