hamlit 2.12.0 → 2.13.0

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: d8a587e57cbdc02c90d18591926efb8bf4fd990d60c31969501418a1eed0d2d9
4
- data.tar.gz: 7f97e39c33bad82a1cc5b4056b8ac0765a2939f2a9c0a6fecfd156daefa98fa3
3
+ metadata.gz: 1b080bac2aef1f473d967c016e0610d319cd43b89fbaea3a113949ed6dacfd04
4
+ data.tar.gz: be1115f4778772e95102c2ab995abd7ff7f3f6c9e86ab8eefac26a38b1a20bd2
5
5
  SHA512:
6
- metadata.gz: dba41938cf6697aeef29f404178de0ccf46cb438402510e989af63593e5ea853627f3f0594fd0359e4b10c68b3c53a7ae64b9c3e2d2f717707e5996006b49721
7
- data.tar.gz: 61ce345a747e0fffee535ecab7caee9b0320858f0243b405643115b97cef012039ed9d72766f5bbd4f1b0cde8fa2ffca7b7cea74a8b9ce2a875106c680f5274d
6
+ metadata.gz: 2b5a640a456b34d551d4e65df868d59c027f4566ff357643f2b42458417356599f6d2cb3a9413ff17e431c69d782f2b9e5a603de147e1a6947f646910d8c3bf4
7
+ data.tar.gz: d13cb779bc02e9914f754054a7b8ab6b2ff6721259b15c87638fbbb2b6a528323b407e22ce4fcdd0a1e91ab1c7f05c5cd7d26e19b96016efaf91b1a188ac6579
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /haml/
10
11
  .sass-cache
11
12
  .ruby-version
12
13
  *.bundle
@@ -4,7 +4,9 @@ branches:
4
4
  only:
5
5
  - master
6
6
  script:
7
- - "RUBYOPT='-w' bundle exec rake $TASK"
7
+ - bundle exec rake $TASK
8
+ env:
9
+ - RUBYOPT='-w'
8
10
  matrix:
9
11
  include:
10
12
  - rvm: 2.3.8
@@ -17,6 +19,8 @@ matrix:
17
19
  env: TASK=test
18
20
  - rvm: 2.7.0
19
21
  env: TASK=test
22
+ - rvm: 2.7.0
23
+ env: TASK=test RUBYOPT='-w --enable-frozen-string-literal'
20
24
  - rvm: ruby-head
21
25
  env: TASK=test
22
26
  - rvm: jruby-9.2.8.0
@@ -4,11 +4,24 @@ 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.13.0](https://github.com/k0kubun/hamlit/compare/v2.12.0...v2.13.0) - 2020-10-2
8
+
9
+ ### Added
10
+
11
+ - Support `--enable-frozen-string-literal` [#162](https://github.com/k0kubun/hamlit/issues/162).
12
+ *Thanks to @aliismayilov*
13
+
14
+ ### Changed
15
+
16
+ - Upgrade the Haml parser from Haml 4.0 to 5.2 [#163](https://github.com/k0kubun/hamlit/issues/163).
17
+ - Allow `@` as tag's class name.
18
+ - Fix NameError on an `InvalidAttributeNameError` reference introduced at Hamlit v2.12.0.
19
+
7
20
  ## [2.12.0](https://github.com/k0kubun/hamlit/compare/v2.11.1...v2.12.0) - 2020-09-30
8
21
 
9
22
  ### Changed
10
23
 
11
- - Class names are no longer ordered alphabetically
24
+ - Class names are no longer ordered alphabetically.
12
25
  *Thanks to @aliismayilov*
13
26
  - This is compatible with [Haml 5.2](https://github.com/haml/haml/blob/v5.2.0/CHANGELOG.md#52)
14
27
 
@@ -1,3 +1,29 @@
1
+ Copyright (c) 2006-2019 Hampton Catlin and Natalie Weizenbaum
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ ===
23
+
24
+ The above license is applied to lib/hamlit/parser/*.rb and test/haml/*.
25
+ Everything else is licensed under:
26
+
1
27
  The MIT License (MIT)
2
28
 
3
29
  Copyright (c) 2015 Takashi Kokubun
@@ -19,26 +45,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
45
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
46
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
47
  THE SOFTWARE.
22
-
23
- lib/hamlit/parser/*.rb and test/haml/* are:
24
-
25
- Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
26
-
27
- Permission is hereby granted, free of charge, to any person obtaining
28
- a copy of this software and associated documentation files (the
29
- "Software"), to deal in the Software without restriction, including
30
- without limitation the rights to use, copy, modify, merge, publish,
31
- distribute, sublicense, and/or sell copies of the Software, and to
32
- permit persons to whom the Software is furnished to do so, subject to
33
- the following conditions:
34
-
35
- The above copyright notice and this permission notice shall be
36
- included in all copies or substantial portions of the Software.
37
-
38
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
39
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
41
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
42
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
43
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
44
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ HAML_REPO = 'haml/haml'
6
+ HAML_VERSION = 'v5.2.0'
7
+
8
+ module GitHubFetcher
9
+ def self.fetch(repo, tag:, path:)
10
+ Dir.mktmpdir do |dir|
11
+ Dir.chdir(dir) do
12
+ url = "https://github.com/#{repo}/archive/#{tag}.tar.gz"
13
+ system("curl -L --fail --retry 3 --retry-delay 1 #{url} -o - | tar zxf -")
14
+ FileUtils.mv("#{File.basename(repo)}-#{tag.sub(/\Av/, '')}", path)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ class LicenseBuilder
21
+ DELIMITER = "\n==="
22
+
23
+ def initialize(haml_license:, hamlit_license:)
24
+ @haml_license = haml_license
25
+ @hamlit_license = hamlit_license
26
+ end
27
+
28
+ def build
29
+ license = [
30
+ File.read(@haml_license),
31
+ File.read(@hamlit_license).split(DELIMITER, 2).last,
32
+ ].join(DELIMITER)
33
+ File.write(@hamlit_license, license)
34
+ end
35
+ end
36
+
37
+ # Generate lib/hamlit/parser from haml
38
+ class HamlitParserBuilder
39
+ TARGET_FILES = [
40
+ 'attribute_builder.rb',
41
+ 'buffer.rb',
42
+ 'error.rb',
43
+ 'helpers.rb',
44
+ 'options.rb',
45
+ 'temple_engine.rb',
46
+ # TODO: make the upstream sharable first
47
+ # 'parser.rb',
48
+ 'util.rb',
49
+ 'helpers/xss_mods.rb',
50
+ ]
51
+
52
+ # Classes which are just referenced by Options and not really used by the parser
53
+ DUMMY_CLASSES = {
54
+ 'compiler.rb' => 'Compiler',
55
+ 'escapable.rb' => 'Escapable',
56
+ 'generator.rb' => 'Generator',
57
+ }
58
+
59
+ def initialize(haml:, hamlit_parser:)
60
+ @haml = haml
61
+ @hamlit_parser = hamlit_parser
62
+ end
63
+
64
+ def build
65
+ TARGET_FILES.each do |file|
66
+ src_path = File.join(@haml, file)
67
+ dest_path = File.join(@hamlit_parser, "haml_#{file}")
68
+
69
+ FileUtils.mkdir_p(File.dirname(dest_path))
70
+ FileUtils.cp(src_path, dest_path)
71
+
72
+ src = File.read(dest_path)
73
+ patch_source!(src, file: file)
74
+ File.write(dest_path, src)
75
+ end
76
+
77
+ DUMMY_CLASSES.each do |file, klass|
78
+ dest_path = File.join(@hamlit_parser, "haml_#{file}")
79
+ src = "class Hamlit::Haml#{klass}; end"
80
+ File.write(dest_path, src)
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def patch_source!(src, file:)
87
+ # Use Hamlit::HamlFoo instead of Haml::Foo
88
+ src.gsub!(/^module Haml\n((?: #[^\n]+\n)*) (module|class) ([^ ]+)/, "module Hamlit\n\\1 \\2 Haml\\3")
89
+ src.gsub!(/\bHaml::/, 'Hamlit::Haml')
90
+
91
+ # Prefix Haml to references without Haml::
92
+ src.gsub!(/\b(AttributeBuilder|Error|InvalidAttributeNameError|Options|Parser|SyntaxError)\./, 'Haml\0')
93
+ src.gsub!(/\brescue SyntaxError /, 'rescue HamlSyntaxError ')
94
+
95
+ # Hamlit should not rely on Haml
96
+ src.gsub!(/^require 'haml\/([^']+)'/, "require 'hamlit/parser/haml_\\1'")
97
+
98
+ case file
99
+ when 'error.rb'
100
+ src.gsub!(/^ class ([^ ]+) < ([^ ]+);/, ' class Haml\1 < Haml\2;')
101
+ when 'helpers.rb'
102
+ src.gsub!(/^ def is_haml\?\n false\n end/m) { |str| str.gsub(/^ /, ' # ') } # not needed for the parser
103
+ when 'options.rb'
104
+ src.gsub!(/\.is_a\?\(Options\)/, '.is_a?(HamlOptions)')
105
+ when 'temple_engine.rb'
106
+ src.gsub!(/\buse (Generator|Escapable)$/, 'use Haml\1')
107
+ end
108
+ end
109
+ end
110
+
111
+ FileUtils.rm_rf(haml = File.expand_path('../haml', __dir__))
112
+ GitHubFetcher.fetch(HAML_REPO, tag: HAML_VERSION, path: haml)
113
+
114
+ hamlit = File.expand_path('..', __dir__)
115
+ LicenseBuilder.new(
116
+ haml_license: File.join(haml, 'MIT-LICENSE'),
117
+ hamlit_license: File.join(hamlit, 'LICENSE.txt'),
118
+ ).build
119
+
120
+ hamlit_parser = File.join(hamlit, 'lib/hamlit/parser')
121
+ # TODO: FileUtils.rm_rf(hamlit_parser = File.join(hamlit, 'lib/hamlit/parser'))
122
+ HamlitParserBuilder.new(
123
+ haml: File.join(haml, 'lib/haml'),
124
+ hamlit_parser: hamlit_parser,
125
+ ).build
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Hamlit
2
3
  class Compiler
3
4
  class CommentCompiler
@@ -12,7 +12,7 @@ module Hamlit
12
12
 
13
13
  def compile_text(text)
14
14
  if ::Hamlit::HamlUtil.contains_interpolation?(text)
15
- [:dynamic, ::Hamlit::HamlUtil.slow_unescape_interpolation(text)]
15
+ [:dynamic, ::Hamlit::HamlUtil.unescape_interpolation(text)]
16
16
  else
17
17
  [:static, text]
18
18
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Hamlit
2
3
  class Filters
3
4
  class Markdown < TiltBase
@@ -12,7 +12,7 @@ module Hamlit
12
12
 
13
13
  def compile_text(text)
14
14
  if ::Hamlit::HamlUtil.contains_interpolation?(text)
15
- [:dynamic, ::Hamlit::HamlUtil.slow_unescape_interpolation(text)]
15
+ [:dynamic, ::Hamlit::HamlUtil.unescape_interpolation(text)]
16
16
  else
17
17
  [:static, text]
18
18
  end
@@ -6,7 +6,7 @@ module Hamlit
6
6
  text = node.value[:text].rstrip.gsub(/^/, prefix)
7
7
  if ::Hamlit::HamlUtil.contains_interpolation?(node.value[:text])
8
8
  # original: Haml::Filters#compile
9
- text = ::Hamlit::HamlUtil.slow_unescape_interpolation(text).gsub(/(\\+)n/) do |s|
9
+ text = ::Hamlit::HamlUtil.unescape_interpolation(text).gsub(/(\\+)n/) do |s|
10
10
  escapes = $1.size
11
11
  next s if escapes % 2 == 0
12
12
  "#{'\\' * (escapes - 1)}\n"
@@ -35,7 +35,7 @@ module Hamlit
35
35
 
36
36
  def dynamic_compile(node, name, indent_width: 0)
37
37
  # original: Haml::Filters#compile
38
- text = ::Hamlit::HamlUtil.slow_unescape_interpolation(node.value[:text]).gsub(/(\\+)n/) do |s|
38
+ text = ::Hamlit::HamlUtil.unescape_interpolation(node.value[:text]).gsub(/(\\+)n/) do |s|
39
39
  escapes = $1.size
40
40
  next s if escapes % 2 == 0
41
41
  "#{'\\' * (escapes - 1)}\n"
@@ -2,13 +2,17 @@
2
2
  # Hamlit::Parser uses original Haml::Parser to generate Haml AST.
3
3
  # hamlit/parser/haml_* are modules originally in haml gem.
4
4
 
5
+ require 'hamlit/parser/haml_attribute_builder'
5
6
  require 'hamlit/parser/haml_error'
6
7
  require 'hamlit/parser/haml_util'
8
+ require 'hamlit/parser/haml_helpers'
7
9
  require 'hamlit/parser/haml_buffer'
8
10
  require 'hamlit/parser/haml_compiler'
9
11
  require 'hamlit/parser/haml_parser'
10
- require 'hamlit/parser/haml_helpers'
11
12
  require 'hamlit/parser/haml_options'
13
+ require 'hamlit/parser/haml_escapable'
14
+ require 'hamlit/parser/haml_generator'
15
+ require 'hamlit/parser/haml_temple_engine'
12
16
 
13
17
  module Hamlit
14
18
  class Parser
@@ -29,7 +33,7 @@ module Hamlit
29
33
  template = Hamlit::HamlUtil.check_haml_encoding(template) do |msg, line|
30
34
  raise Hamlit::Error.new(msg, line)
31
35
  end
32
- HamlParser.new(template, HamlOptions.new(@options)).parse
36
+ HamlParser.new(HamlOptions.new(@options)).call(template)
33
37
  rescue ::Hamlit::HamlError => e
34
38
  error_with_lineno(e)
35
39
  end
@@ -98,7 +98,7 @@ module Hamlit
98
98
  def verify_attribute_names!(attribute_names)
99
99
  attribute_names.each do |attribute_name|
100
100
  if attribute_name =~ INVALID_ATTRIBUTE_NAME_REGEX
101
- raise InvalidAttributeNameError.new("Invalid attribute name '#{attribute_name}' was rendered")
101
+ raise HamlInvalidAttributeNameError.new("Invalid attribute name '#{attribute_name}' was rendered")
102
102
  end
103
103
  end
104
104
  end
@@ -1,6 +1,4 @@
1
- require 'hamlit/parser/haml_helpers'
2
- require 'hamlit/parser/haml_util'
3
- require 'hamlit/parser/haml_compiler'
1
+ # frozen_string_literal: true
4
2
 
5
3
  module Hamlit
6
4
  # This class is used only internally. It holds the buffer of HTML that
@@ -8,12 +6,8 @@ module Hamlit
8
6
  # It's called from within the precompiled code,
9
7
  # and helps reduce the amount of processing done within `instance_eval`ed code.
10
8
  class HamlBuffer
11
- ID_KEY = 'id'.freeze
12
- CLASS_KEY = 'class'.freeze
13
- DATA_KEY = 'data'.freeze
14
-
15
- include ::Hamlit::HamlHelpers
16
- include ::Hamlit::HamlUtil
9
+ include Hamlit::HamlHelpers
10
+ include Hamlit::HamlUtil
17
11
 
18
12
  # The string that holds the compiled HTML. This is aliased as
19
13
  # `_erbout` for compatibility with ERB-specific code.
@@ -21,10 +15,10 @@ module Hamlit
21
15
  # @return [String]
22
16
  attr_accessor :buffer
23
17
 
24
- # The options hash passed in from {Haml::Engine}.
18
+ # The options hash passed in from {Hamlit::HamlEngine}.
25
19
  #
26
20
  # @return [{String => Object}]
27
- # @see Haml::Options#for_buffer
21
+ # @see Hamlit::HamlOptions#for_buffer
28
22
  attr_accessor :options
29
23
 
30
24
  # The {Buffer} for the enclosing Haml document.
@@ -94,11 +88,12 @@ module Hamlit
94
88
 
95
89
  # @param upper [Buffer] The parent buffer
96
90
  # @param options [{Symbol => Object}] An options hash.
97
- # See {Haml::Engine#options\_for\_buffer}
91
+ # See {Hamlit::HamlEngine#options\_for\_buffer}
98
92
  def initialize(upper = nil, options = {})
99
93
  @active = true
100
94
  @upper = upper
101
- @options = options
95
+ @options = HamlOptions.buffer_defaults
96
+ @options = @options.merge(options) unless options.empty?
102
97
  @buffer = new_encoded_string
103
98
  @tabulation = 0
104
99
 
@@ -135,70 +130,15 @@ module Hamlit
135
130
  @real_tabs += tab_change
136
131
  end
137
132
 
138
- # the number of arguments here is insane, but passing in an options hash instead of named arguments
139
- # causes a significant performance regression
140
- def format_script(result, preserve_script, in_tag, preserve_tag, escape_html, nuke_inner_whitespace, interpolated, ugly)
141
- result_name = escape_html ? html_escape(result.to_s) : result.to_s
142
-
143
- if ugly
144
- result = nuke_inner_whitespace ? result_name.strip : result_name
145
- result = preserve(result, preserve_script, preserve_tag)
146
- fix_textareas!(result) if toplevel? && result.include?('<textarea')
147
- return result
148
- end
149
-
150
- # If we're interpolated,
151
- # then the custom tabulation is handled in #push_text.
152
- # The easiest way to avoid it here is to reset @tabulation.
153
- if interpolated
154
- old_tabulation = @tabulation
155
- @tabulation = 0
156
- end
157
-
158
- in_tag_no_nuke = in_tag && !nuke_inner_whitespace
159
- preserved_no_nuke = in_tag_no_nuke && preserve_tag
160
- tabulation = !preserved_no_nuke && @real_tabs
161
-
162
- result = nuke_inner_whitespace ? result_name.strip : result_name.rstrip
163
- result = preserve(result, preserve_script, preserve_tag)
164
-
165
- has_newline = !preserved_no_nuke && result.include?("\n")
166
-
167
- if in_tag_no_nuke && (preserve_tag || !has_newline)
168
- @real_tabs -= 1
169
- @tabulation = old_tabulation if interpolated
170
- return result
171
- end
172
-
173
- unless preserved_no_nuke
174
- # Precompiled tabulation may be wrong
175
- result = "#{tabs}#{result}" if !interpolated && !in_tag && @tabulation > 0
176
-
177
- if has_newline
178
- result.gsub! "\n", "\n#{tabs(tabulation)}"
179
-
180
- # Add tabulation if it wasn't precompiled
181
- result = "#{tabs(tabulation)}#{result}" if in_tag_no_nuke
182
- end
183
-
184
- fix_textareas!(result) if toplevel? && result.include?('<textarea')
185
-
186
- if in_tag_no_nuke
187
- result = "\n#{result}\n#{tabs(tabulation-1)}"
188
- @real_tabs -= 1
189
- end
190
- @tabulation = old_tabulation if interpolated
191
- result
192
- end
193
- end
194
-
195
133
  def attributes(class_id, obj_ref, *attributes_hashes)
196
134
  attributes = class_id
197
135
  attributes_hashes.each do |old|
198
- self.class.merge_attrs(attributes, Hash[old.map {|k, v| [k.to_s, v]}])
136
+ result = {}
137
+ old.each { |k, v| result[k.to_s] = v }
138
+ HamlAttributeBuilder.merge_attributes!(attributes, result)
199
139
  end
200
- self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
201
- ::Hamlit::HamlCompiler.build_attributes(
140
+ HamlAttributeBuilder.merge_attributes!(attributes, parse_object_ref(obj_ref)) if obj_ref
141
+ HamlAttributeBuilder.build_attributes(
202
142
  html?, @options[:attr_wrapper], @options[:escape_attrs], @options[:hyphenate_data_attrs], attributes)
203
143
  end
204
144
 
@@ -213,61 +153,6 @@ module Hamlit
213
153
  buffer << buffer.slice!(capture_position..-1).rstrip
214
154
  end
215
155
 
216
- # Merges two attribute hashes.
217
- # This is the same as `to.merge!(from)`,
218
- # except that it merges id, class, and data attributes.
219
- #
220
- # ids are concatenated with `"_"`,
221
- # and classes are concatenated with `" "`.
222
- # data hashes are simply merged.
223
- #
224
- # Destructively modifies both `to` and `from`.
225
- #
226
- # @param to [{String => String}] The attribute hash to merge into
227
- # @param from [{String => #to_s}] The attribute hash to merge from
228
- # @return [{String => String}] `to`, after being merged
229
- def self.merge_attrs(to, from)
230
- from[ID_KEY] = ::Hamlit::HamlCompiler.filter_and_join(from[ID_KEY], '_') if from[ID_KEY]
231
- if to[ID_KEY] && from[ID_KEY]
232
- to[ID_KEY] << "_#{from.delete(ID_KEY)}"
233
- elsif to[ID_KEY] || from[ID_KEY]
234
- from[ID_KEY] ||= to[ID_KEY]
235
- end
236
-
237
- from[CLASS_KEY] = ::Hamlit::HamlCompiler.filter_and_join(from[CLASS_KEY], ' ') if from[CLASS_KEY]
238
- if to[CLASS_KEY] && from[CLASS_KEY]
239
- # Make sure we don't duplicate class names
240
- from[CLASS_KEY] = (from[CLASS_KEY].to_s.split(' ') | to[CLASS_KEY].split(' ')).sort.join(' ')
241
- elsif to[CLASS_KEY] || from[CLASS_KEY]
242
- from[CLASS_KEY] ||= to[CLASS_KEY]
243
- end
244
-
245
- from.keys.each do |key|
246
- next unless from[key].kind_of?(Hash) || to[key].kind_of?(Hash)
247
-
248
- from_data = from.delete(key)
249
- # forces to_data & from_data into a hash
250
- from_data = { nil => from_data } if from_data && !from_data.is_a?(Hash)
251
- to[key] = { nil => to[key] } if to[key] && !to[key].is_a?(Hash)
252
-
253
- if from_data && !to[key]
254
- to[key] = from_data
255
- elsif from_data && to[key]
256
- to[key].merge! from_data
257
- end
258
- end
259
-
260
- to.merge!(from)
261
- end
262
-
263
- private
264
-
265
- def preserve(result, preserve_script, preserve_tag)
266
- return ::Hamlit::HamlHelpers.preserve(result) if preserve_tag
267
- return ::Hamlit::HamlHelpers.find_and_preserve(result, options[:preserve]) if preserve_script
268
- result
269
- end
270
-
271
156
  # Works like #{find_and_preserve}, but allows the first newline after a
272
157
  # preserved opening tag to remain unencoded, and then outdents the content.
273
158
  # This change was motivated primarily by the change in Rails 3.2.3 to emit
@@ -277,6 +162,8 @@ module Hamlit
277
162
  # @since Haml 4.0.1
278
163
  # @private
279
164
  def fix_textareas!(input)
165
+ return input unless input.include?('<textarea'.freeze)
166
+
280
167
  pattern = /<(textarea)([^>]*)>(\n|&#x000A;)(.*?)<\/textarea>/im
281
168
  input.gsub!(pattern) do |s|
282
169
  match = pattern.match(s)
@@ -288,10 +175,13 @@ module Hamlit
288
175
  end
289
176
  "<#{match[1]}#{match[2]}>\n#{content}</#{match[1]}>"
290
177
  end
178
+ input
291
179
  end
292
180
 
181
+ private
182
+
293
183
  def new_encoded_string
294
- "".encode(Encoding.find(options[:encoding]))
184
+ "".encode(options[:encoding])
295
185
  end
296
186
 
297
187
  @@tab_cache = {}
@@ -329,7 +219,7 @@ module Hamlit
329
219
  id = "#{ prefix }_#{ id }"
330
220
  end
331
221
 
332
- {ID_KEY => id, CLASS_KEY => class_name}
222
+ { 'id'.freeze => id, 'class'.freeze => class_name }
333
223
  end
334
224
 
335
225
  # Changes a word from camel case to underscores.