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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -1
- data/CHANGELOG.md +14 -1
- data/LICENSE.txt +26 -23
- data/bin/update-haml +125 -0
- data/lib/hamlit/compiler/comment_compiler.rb +1 -0
- data/lib/hamlit/filters/escaped.rb +1 -1
- data/lib/hamlit/filters/markdown.rb +1 -0
- data/lib/hamlit/filters/preserve.rb +1 -1
- data/lib/hamlit/filters/text_base.rb +1 -1
- data/lib/hamlit/filters/tilt_base.rb +1 -1
- data/lib/hamlit/parser.rb +6 -2
- data/lib/hamlit/parser/haml_attribute_builder.rb +1 -1
- data/lib/hamlit/parser/haml_buffer.rb +20 -130
- data/lib/hamlit/parser/haml_compiler.rb +1 -553
- data/lib/hamlit/parser/haml_error.rb +29 -25
- data/lib/hamlit/parser/haml_escapable.rb +1 -0
- data/lib/hamlit/parser/haml_generator.rb +1 -0
- data/lib/hamlit/parser/haml_helpers.rb +35 -59
- data/lib/hamlit/parser/{haml_xss_mods.rb → haml_helpers/xss_mods.rb} +14 -12
- data/lib/hamlit/parser/haml_options.rb +53 -66
- data/lib/hamlit/parser/haml_parser.rb +73 -64
- data/lib/hamlit/parser/haml_temple_engine.rb +123 -0
- data/lib/hamlit/parser/haml_util.rb +10 -40
- data/lib/hamlit/rails_template.rb +1 -1
- data/lib/hamlit/string_splitter.rb +1 -0
- data/lib/hamlit/version.rb +1 -1
- metadata +7 -5
- data/lib/hamlit/parser/MIT-LICENSE +0 -20
- data/lib/hamlit/parser/README.md +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b080bac2aef1f473d967c016e0610d319cd43b89fbaea3a113949ed6dacfd04
|
4
|
+
data.tar.gz: be1115f4778772e95102c2ab995abd7ff7f3f6c9e86ab8eefac26a38b1a20bd2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b5a640a456b34d551d4e65df868d59c027f4566ff357643f2b42458417356599f6d2cb3a9413ff17e431c69d782f2b9e5a603de147e1a6947f646910d8c3bf4
|
7
|
+
data.tar.gz: d13cb779bc02e9914f754054a7b8ab6b2ff6721259b15c87638fbbb2b6a528323b407e22ce4fcdd0a1e91ab1c7f05c5cd7d26e19b96016efaf91b1a188ac6579
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -4,7 +4,9 @@ branches:
|
|
4
4
|
only:
|
5
5
|
- master
|
6
6
|
script:
|
7
|
-
-
|
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
|
data/CHANGELOG.md
CHANGED
@@ -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
|
|
data/LICENSE.txt
CHANGED
@@ -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.
|
data/bin/update-haml
ADDED
@@ -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
|
@@ -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.
|
15
|
+
[:dynamic, ::Hamlit::HamlUtil.unescape_interpolation(text)]
|
16
16
|
else
|
17
17
|
[:static, text]
|
18
18
|
end
|
@@ -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.
|
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.
|
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.
|
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"
|
data/lib/hamlit/parser.rb
CHANGED
@@ -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(
|
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
|
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
|
-
|
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
|
-
|
12
|
-
|
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 {
|
18
|
+
# The options hash passed in from {Hamlit::HamlEngine}.
|
25
19
|
#
|
26
20
|
# @return [{String => Object}]
|
27
|
-
# @see
|
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 {
|
91
|
+
# See {Hamlit::HamlEngine#options\_for\_buffer}
|
98
92
|
def initialize(upper = nil, options = {})
|
99
93
|
@active = true
|
100
94
|
@upper = upper
|
101
|
-
@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
|
-
|
136
|
+
result = {}
|
137
|
+
old.each { |k, v| result[k.to_s] = v }
|
138
|
+
HamlAttributeBuilder.merge_attributes!(attributes, result)
|
199
139
|
end
|
200
|
-
|
201
|
-
|
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|
)(.*?)<\/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(
|
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
|
-
{
|
222
|
+
{ 'id'.freeze => id, 'class'.freeze => class_name }
|
333
223
|
end
|
334
224
|
|
335
225
|
# Changes a word from camel case to underscores.
|