haml 7.4.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a5bc7150b467bde9b4effce4bdc2b568a0b6a5644d7254b69a9de6ea6c807af
4
- data.tar.gz: 172ab49b7e798cb37dd97ebfa037d27bd53dd5f8924f7111d9ac23c1de13d1ba
3
+ metadata.gz: 4dced0d7329423afd97a56b1ce6b32f4c332a9f4e725aed6a41f4e5d7c10bfd7
4
+ data.tar.gz: 985f140fb9f9ae590c0e37ae7d5f06632c5c1f4a522578639e2a98527fb85e20
5
5
  SHA512:
6
- metadata.gz: 4950862786ea326cfe7df4276bd75c99ce9e00cea7f9446b568880bb7a2999ad0b3dec92b4e0b0bfbd6b9b725a847f00ae6ff9f29ce1f0573efdf9ee0a283b91
7
- data.tar.gz: 5ec5253e40f7dfd02fb4e6b537fe2c929590356d1e5130abe211c522e2d0856b7ceaaa1c951d8e7fa672bb4289f7a8284f3e3d384e6eec31552525546e31432a
6
+ metadata.gz: ba4cc15a925752648e293fd712e024c92da5d0e1d827e28719e871e5ffa7a647fc928c46650f7a2c92bf3ad8c67e70f821fd1710de346affb528639f34652af1
7
+ data.tar.gz: 062d2e3a5b523a5450179790f20627920e9086065b13f15591b4472178a3e7ec4672caa299466a428b343a21b5fd7eb85c0549f032b22ba5854aacf1510ad576
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
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
+
3
7
  ## 7.4.0
4
8
 
5
9
  * `Haml::BOOLEAN_ATTRIBUTES` is changed from Array to Set https://github.com/haml/haml/pull/1216
@@ -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
- tags = tags.map { |tag| Regexp.escape(tag) }.join('|')
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, %w(textarea pre code))
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}, %w(textarea pre 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
@@ -3,7 +3,7 @@ module Haml
3
3
  module Helpers
4
4
  def self.preserve(input)
5
5
  s = input.to_s.chomp("\n")
6
- s.gsub!(/\n/, '&#x000A;')
6
+ s.gsub!("\n", '&#x000A;')
7
7
  s.delete!("\r")
8
8
  s
9
9
  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
@@ -1,5 +1,6 @@
1
- # frozen_string_literal: false
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 = %w[textarea pre code].freeze
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
- tags = tags.each_with_object('') do |t, s|
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/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Haml
3
- VERSION = '7.4.0'
3
+ VERSION = '7.4.1'
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: 7.4.0
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