haml 5.2.2 → 6.0.0.beta.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 +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/test.yml +13 -9
- data/.gitignore +16 -16
- data/CHANGELOG.md +13 -3
- data/Gemfile +18 -11
- data/MIT-LICENSE +1 -1
- data/README.md +13 -19
- data/Rakefile +95 -93
- data/bin/bench +66 -0
- data/bin/console +11 -0
- data/bin/ruby +3 -0
- data/bin/setup +7 -0
- data/bin/stackprof +27 -0
- data/bin/test +24 -0
- data/exe/haml +6 -0
- data/ext/haml/extconf.rb +10 -0
- data/ext/haml/haml.c +537 -0
- data/ext/haml/hescape.c +108 -0
- data/ext/haml/hescape.h +20 -0
- data/haml.gemspec +39 -37
- data/lib/haml/ambles.rb +20 -0
- data/lib/haml/attribute_builder.rb +135 -179
- data/lib/haml/attribute_compiler.rb +85 -194
- data/lib/haml/attribute_parser.rb +86 -126
- data/lib/haml/cli.rb +154 -0
- data/lib/haml/compiler/children_compiler.rb +126 -0
- data/lib/haml/compiler/comment_compiler.rb +39 -0
- data/lib/haml/compiler/doctype_compiler.rb +46 -0
- data/lib/haml/compiler/script_compiler.rb +116 -0
- data/lib/haml/compiler/silent_script_compiler.rb +24 -0
- data/lib/haml/compiler/tag_compiler.rb +76 -0
- data/lib/haml/compiler.rb +63 -296
- data/lib/haml/dynamic_merger.rb +67 -0
- data/lib/haml/engine.rb +42 -227
- data/lib/haml/error.rb +3 -52
- data/lib/haml/escapable.rb +6 -70
- data/lib/haml/filters/base.rb +12 -0
- data/lib/haml/filters/cdata.rb +20 -0
- data/lib/haml/filters/coffee.rb +17 -0
- data/lib/haml/filters/css.rb +33 -0
- data/lib/haml/filters/erb.rb +10 -0
- data/lib/haml/filters/escaped.rb +22 -0
- data/lib/haml/filters/javascript.rb +33 -0
- data/lib/haml/filters/less.rb +20 -0
- data/lib/haml/filters/markdown.rb +11 -0
- data/lib/haml/filters/plain.rb +29 -0
- data/lib/haml/filters/preserve.rb +22 -0
- data/lib/haml/filters/ruby.rb +10 -0
- data/lib/haml/filters/sass.rb +15 -0
- data/lib/haml/filters/scss.rb +15 -0
- data/lib/haml/filters/text_base.rb +25 -0
- data/lib/haml/filters/tilt_base.rb +49 -0
- data/lib/haml/filters.rb +54 -378
- data/lib/haml/force_escapable.rb +29 -0
- data/lib/haml/haml_error.rb +66 -0
- data/lib/haml/helpers.rb +3 -697
- data/lib/haml/html.rb +22 -0
- data/lib/haml/identity.rb +13 -0
- data/lib/haml/object_ref.rb +30 -0
- data/lib/haml/parser.rb +179 -49
- data/lib/haml/rails_helpers.rb +51 -0
- data/lib/haml/rails_template.rb +55 -0
- data/lib/haml/railtie.rb +7 -45
- data/lib/haml/ruby_expression.rb +32 -0
- data/lib/haml/string_splitter.rb +20 -0
- data/lib/haml/template.rb +15 -34
- data/lib/haml/temple_line_counter.rb +2 -1
- data/lib/haml/util.rb +17 -15
- data/lib/haml/version.rb +1 -2
- data/lib/haml.rb +8 -20
- metadata +211 -57
- data/.gitmodules +0 -3
- data/.yardopts +0 -22
- data/TODO +0 -24
- data/benchmark.rb +0 -70
- data/bin/haml +0 -9
- data/lib/haml/.gitattributes +0 -1
- data/lib/haml/buffer.rb +0 -182
- data/lib/haml/exec.rb +0 -347
- data/lib/haml/generator.rb +0 -42
- data/lib/haml/helpers/action_view_extensions.rb +0 -60
- data/lib/haml/helpers/action_view_mods.rb +0 -132
- data/lib/haml/helpers/action_view_xss_mods.rb +0 -60
- data/lib/haml/helpers/safe_erubi_template.rb +0 -20
- data/lib/haml/helpers/safe_erubis_template.rb +0 -33
- data/lib/haml/helpers/xss_mods.rb +0 -114
- data/lib/haml/options.rb +0 -273
- data/lib/haml/plugin.rb +0 -54
- data/lib/haml/sass_rails_filter.rb +0 -47
- data/lib/haml/template/options.rb +0 -27
- data/lib/haml/temple_engine.rb +0 -124
- data/yard/default/.gitignore +0 -1
- data/yard/default/fulldoc/html/css/common.sass +0 -15
- data/yard/default/layout/html/footer.erb +0 -12
data/lib/haml/engine.rb
CHANGED
@@ -1,238 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
|
2
|
+
require 'temple'
|
5
3
|
require 'haml/parser'
|
6
4
|
require 'haml/compiler'
|
7
|
-
require 'haml/
|
8
|
-
require 'haml/
|
9
|
-
require 'haml/
|
10
|
-
require 'haml/
|
11
|
-
require 'haml/
|
12
|
-
require 'haml/temple_engine'
|
5
|
+
require 'haml/html'
|
6
|
+
require 'haml/escapable'
|
7
|
+
require 'haml/force_escapable'
|
8
|
+
require 'haml/dynamic_merger'
|
9
|
+
require 'haml/ambles'
|
13
10
|
|
14
11
|
module Haml
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def options_for_buffer
|
45
|
-
@options.for_buffer
|
46
|
-
end
|
47
|
-
|
48
|
-
# Precompiles the Haml template.
|
49
|
-
#
|
50
|
-
# @param template [String] The Haml template
|
51
|
-
# @param options [{Symbol => Object}] An options hash;
|
52
|
-
# see {file:REFERENCE.md#options the Haml options documentation}
|
53
|
-
# @raise [Haml::Error] if there's a Haml syntax error in the template
|
54
|
-
def initialize(template, options = {})
|
55
|
-
# Reflect changes of `Haml::Options.defaults` to `Haml::TempleEngine` options, but `#initialize_encoding`
|
56
|
-
# should be run against the arguemnt `options[:encoding]` for backward compatibility with old `Haml::Engine`.
|
57
|
-
options = Options.defaults.dup.tap { |o| o.delete(:encoding) }.merge!(options)
|
58
|
-
@options = Options.new(options)
|
59
|
-
|
60
|
-
@template = check_haml_encoding(template) do |msg, line|
|
61
|
-
raise Haml::Error.new(msg, line)
|
62
|
-
end
|
63
|
-
|
64
|
-
@temple_engine = TempleEngine.new(options)
|
65
|
-
@temple_engine.compile(@template)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Deprecated API for backword compatibility
|
69
|
-
def compiler
|
70
|
-
@temple_engine
|
71
|
-
end
|
72
|
-
|
73
|
-
# Processes the template and returns the result as a string.
|
74
|
-
#
|
75
|
-
# `scope` is the context in which the template is evaluated.
|
76
|
-
# If it's a `Binding`, Haml uses it as the second argument to `Kernel#eval`;
|
77
|
-
# otherwise, Haml just uses its `#instance_eval` context.
|
78
|
-
#
|
79
|
-
# Note that Haml modifies the evaluation context
|
80
|
-
# (either the scope object or the `self` object of the scope binding).
|
81
|
-
# It extends {Haml::Helpers}, and various instance variables are set
|
82
|
-
# (all prefixed with `haml_`).
|
83
|
-
# For example:
|
84
|
-
#
|
85
|
-
# s = "foobar"
|
86
|
-
# Haml::Engine.new("%p= upcase").render(s) #=> "<p>FOOBAR</p>"
|
87
|
-
#
|
88
|
-
# # s now extends Haml::Helpers
|
89
|
-
# s.respond_to?(:html_attrs) #=> true
|
90
|
-
#
|
91
|
-
# `locals` is a hash of local variables to make available to the template.
|
92
|
-
# For example:
|
93
|
-
#
|
94
|
-
# Haml::Engine.new("%p= foo").render(Object.new, :foo => "Hello, world!") #=> "<p>Hello, world!</p>"
|
95
|
-
#
|
96
|
-
# If a block is passed to render,
|
97
|
-
# that block is run when `yield` is called
|
98
|
-
# within the template.
|
99
|
-
#
|
100
|
-
# Due to some Ruby quirks,
|
101
|
-
# if `scope` is a `Binding` object and a block is given,
|
102
|
-
# the evaluation context may not be quite what the user expects.
|
103
|
-
# In particular, it's equivalent to passing `eval("self", scope)` as `scope`.
|
104
|
-
# This won't have an effect in most cases,
|
105
|
-
# but if you're relying on local variables defined in the context of `scope`,
|
106
|
-
# they won't work.
|
107
|
-
#
|
108
|
-
# @param scope [Binding, Object] The context in which the template is evaluated
|
109
|
-
# @param locals [{Symbol => Object}] Local variables that will be made available
|
110
|
-
# to the template
|
111
|
-
# @param block [#to_proc] A block that can be yielded to within the template
|
112
|
-
# @return [String] The rendered template
|
113
|
-
def render(scope = Object.new, locals = {}, &block)
|
114
|
-
parent = scope.instance_variable_defined?(:@haml_buffer) ? scope.instance_variable_get(:@haml_buffer) : nil
|
115
|
-
buffer = Haml::Buffer.new(parent, @options.for_buffer)
|
116
|
-
|
117
|
-
if scope.is_a?(Binding)
|
118
|
-
scope_object = eval("self", scope)
|
119
|
-
scope = scope_object.instance_eval{binding} if block_given?
|
120
|
-
else
|
121
|
-
scope_object = scope
|
122
|
-
scope = scope_object.instance_eval{binding}
|
123
|
-
end
|
124
|
-
|
125
|
-
set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
|
126
|
-
|
127
|
-
scope_object.extend(Haml::Helpers)
|
128
|
-
scope_object.instance_variable_set(:@haml_buffer, buffer)
|
129
|
-
begin
|
130
|
-
eval(@temple_engine.precompiled_with_return_value, scope, @options.filename, @options.line)
|
131
|
-
rescue ::SyntaxError => e
|
132
|
-
raise SyntaxError, e.message
|
133
|
-
end
|
134
|
-
ensure
|
135
|
-
# Get rid of the current buffer
|
136
|
-
scope_object.instance_variable_set(:@haml_buffer, buffer.upper) if buffer
|
137
|
-
end
|
138
|
-
alias_method :to_html, :render
|
139
|
-
|
140
|
-
# Returns a proc that, when called,
|
141
|
-
# renders the template and returns the result as a string.
|
142
|
-
#
|
143
|
-
# `scope` works the same as it does for render.
|
144
|
-
#
|
145
|
-
# The first argument of the returned proc is a hash of local variable names to values.
|
146
|
-
# However, due to an unfortunate Ruby quirk,
|
147
|
-
# the local variables which can be assigned must be pre-declared.
|
148
|
-
# This is done with the `local_names` argument.
|
149
|
-
# For example:
|
150
|
-
#
|
151
|
-
# # This works
|
152
|
-
# Haml::Engine.new("%p= foo").render_proc(Object.new, :foo).call :foo => "Hello!"
|
153
|
-
# #=> "<p>Hello!</p>"
|
154
|
-
#
|
155
|
-
# # This doesn't
|
156
|
-
# Haml::Engine.new("%p= foo").render_proc.call :foo => "Hello!"
|
157
|
-
# #=> NameError: undefined local variable or method `foo'
|
158
|
-
#
|
159
|
-
# The proc doesn't take a block; any yields in the template will fail.
|
160
|
-
#
|
161
|
-
# @param scope [Binding, Object] The context in which the template is evaluated
|
162
|
-
# @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
|
163
|
-
# @return [Proc] The proc that will run the template
|
164
|
-
def render_proc(scope = Object.new, *local_names)
|
165
|
-
if scope.is_a?(Binding)
|
166
|
-
scope_object = eval("self", scope)
|
167
|
-
else
|
168
|
-
scope_object = scope
|
169
|
-
scope = scope_object.instance_eval{binding}
|
170
|
-
end
|
171
|
-
|
172
|
-
begin
|
173
|
-
str = @temple_engine.precompiled_with_ambles(local_names)
|
174
|
-
eval(
|
175
|
-
"Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {}; #{str}}\n",
|
176
|
-
scope,
|
177
|
-
@options.filename,
|
178
|
-
@options.line
|
179
|
-
)
|
180
|
-
rescue ::SyntaxError => e
|
181
|
-
raise SyntaxError, e.message
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
# Defines a method on `object` with the given name
|
186
|
-
# that renders the template and returns the result as a string.
|
187
|
-
#
|
188
|
-
# If `object` is a class or module,
|
189
|
-
# the method will instead be defined as an instance method.
|
190
|
-
# For example:
|
191
|
-
#
|
192
|
-
# t = Time.now
|
193
|
-
# Haml::Engine.new("%p\n Today's date is\n .date= self.to_s").def_method(t, :render)
|
194
|
-
# t.render #=> "<p>\n Today's date is\n <div class='date'>Fri Nov 23 18:28:29 -0800 2007</div>\n</p>\n"
|
195
|
-
#
|
196
|
-
# Haml::Engine.new(".upcased= upcase").def_method(String, :upcased_div)
|
197
|
-
# "foobar".upcased_div #=> "<div class='upcased'>FOOBAR</div>\n"
|
198
|
-
#
|
199
|
-
# The first argument of the defined method is a hash of local variable names to values.
|
200
|
-
# However, due to an unfortunate Ruby quirk,
|
201
|
-
# the local variables which can be assigned must be pre-declared.
|
202
|
-
# This is done with the `local_names` argument.
|
203
|
-
# For example:
|
204
|
-
#
|
205
|
-
# # This works
|
206
|
-
# obj = Object.new
|
207
|
-
# Haml::Engine.new("%p= foo").def_method(obj, :render, :foo)
|
208
|
-
# obj.render(:foo => "Hello!") #=> "<p>Hello!</p>"
|
209
|
-
#
|
210
|
-
# # This doesn't
|
211
|
-
# obj = Object.new
|
212
|
-
# Haml::Engine.new("%p= foo").def_method(obj, :render)
|
213
|
-
# obj.render(:foo => "Hello!") #=> NameError: undefined local variable or method `foo'
|
214
|
-
#
|
215
|
-
# Note that Haml modifies the evaluation context
|
216
|
-
# (either the scope object or the `self` object of the scope binding).
|
217
|
-
# It extends {Haml::Helpers}, and various instance variables are set
|
218
|
-
# (all prefixed with `haml_`).
|
219
|
-
#
|
220
|
-
# @param object [Object, Module] The object on which to define the method
|
221
|
-
# @param name [String, Symbol] The name of the method to define
|
222
|
-
# @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
|
223
|
-
def def_method(object, name, *local_names)
|
224
|
-
method = object.is_a?(Module) ? :module_eval : :instance_eval
|
12
|
+
class Engine < Temple::Engine
|
13
|
+
define_options(
|
14
|
+
:buffer_class,
|
15
|
+
generator: Temple::Generators::ArrayBuffer,
|
16
|
+
format: :html,
|
17
|
+
attr_quote: "'",
|
18
|
+
escape_html: true,
|
19
|
+
escape_attrs: true,
|
20
|
+
autoclose: %w(area base basefont br col command embed frame
|
21
|
+
hr img input isindex keygen link menuitem meta
|
22
|
+
param source track wbr),
|
23
|
+
filename: "",
|
24
|
+
disable_capture: false,
|
25
|
+
)
|
26
|
+
|
27
|
+
use Parser
|
28
|
+
use Compiler
|
29
|
+
use HTML
|
30
|
+
filter :StringSplitter
|
31
|
+
filter :StaticAnalyzer
|
32
|
+
use Escapable
|
33
|
+
use ForceEscapable
|
34
|
+
filter :ControlFlow
|
35
|
+
use Ambles
|
36
|
+
filter :MultiFlattener
|
37
|
+
filter :StaticMerger
|
38
|
+
use DynamicMerger
|
39
|
+
use :Generator, -> { options[:generator] }
|
40
|
+
end
|
225
41
|
|
226
|
-
|
227
|
-
|
42
|
+
# For backward compatibility of Tilt integration. TODO: We should deprecate this
|
43
|
+
# and let Tilt have a native support of Haml 6. At least it generates warnings now.
|
44
|
+
class TempleEngine < Engine
|
45
|
+
def compile(template)
|
46
|
+
@precompiled = call(template)
|
228
47
|
end
|
229
48
|
|
230
|
-
|
231
|
-
|
232
|
-
def set_locals(locals, scope, scope_object)
|
233
|
-
scope_object.instance_variable_set :@_haml_locals, locals
|
234
|
-
set_locals = locals.keys.map { |k| "#{k} = @_haml_locals[#{k.inspect}]" }.join("\n")
|
235
|
-
eval(set_locals, scope)
|
49
|
+
def precompiled_with_ambles(_local_names, after_preamble:)
|
50
|
+
"#{after_preamble.tr("\n", ';')}#{@precompiled}".dup
|
236
51
|
end
|
237
52
|
end
|
238
53
|
end
|
data/lib/haml/error.rb
CHANGED
@@ -1,65 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
module Haml
|
4
|
-
#
|
3
|
+
# TODO: unify Haml::Error (former Hamlit::Error) and Haml::HamlError (former Haml::Error)
|
5
4
|
class Error < StandardError
|
6
|
-
|
7
|
-
MESSAGES = {
|
8
|
-
bad_script_indent: '"%s" is indented at wrong level: expected %d, but was at %d.',
|
9
|
-
cant_run_filter: 'Can\'t run "%s" filter; you must require its dependencies first',
|
10
|
-
cant_use_tabs_and_spaces: "Indentation can't use both tabs and spaces.",
|
11
|
-
deeper_indenting: "The line was indented %d levels deeper than the previous line.",
|
12
|
-
filter_not_defined: 'Filter "%s" is not defined.',
|
13
|
-
gem_install_filter_deps: '"%s" filter\'s %s dependency missing: try installing it or adding it to your Gemfile',
|
14
|
-
illegal_element: "Illegal element: classes and ids must have values.",
|
15
|
-
illegal_nesting_content: "Illegal nesting: nesting within a tag that already has content is illegal.",
|
16
|
-
illegal_nesting_header: "Illegal nesting: nesting within a header command is illegal.",
|
17
|
-
illegal_nesting_line: "Illegal nesting: content can't be both given on the same line as %%%s and nested within it.",
|
18
|
-
illegal_nesting_plain: "Illegal nesting: nesting within plain text is illegal.",
|
19
|
-
illegal_nesting_self_closing: "Illegal nesting: nesting within a self-closing tag is illegal.",
|
20
|
-
inconsistent_indentation: "Inconsistent indentation: %s used for indentation, but the rest of the document was indented using %s.",
|
21
|
-
indenting_at_start: "Indenting at the beginning of the document is illegal.",
|
22
|
-
install_haml_contrib: 'To use the "%s" filter, please install the haml-contrib gem.',
|
23
|
-
invalid_attribute_list: 'Invalid attribute list: %s.',
|
24
|
-
invalid_filter_name: 'Invalid filter name ":%s".',
|
25
|
-
invalid_tag: 'Invalid tag: "%s".',
|
26
|
-
missing_if: 'Got "%s" with no preceding "if"',
|
27
|
-
no_ruby_code: "There's no Ruby code for %s to evaluate.",
|
28
|
-
self_closing_content: "Self-closing tags can't have content.",
|
29
|
-
unbalanced_brackets: 'Unbalanced brackets.',
|
30
|
-
no_end: <<-END
|
31
|
-
You don't need to use "- end" in Haml. Un-indent to close a block:
|
32
|
-
- if foo?
|
33
|
-
%strong Foo!
|
34
|
-
- else
|
35
|
-
Not foo.
|
36
|
-
%p This line is un-indented, so it isn't part of the "if" block
|
37
|
-
END
|
38
|
-
}.freeze
|
39
|
-
|
40
|
-
def self.message(key, *args)
|
41
|
-
string = MESSAGES[key] or raise "[HAML BUG] No error messages for #{key}"
|
42
|
-
(args.empty? ? string : string % args).rstrip
|
43
|
-
end
|
44
|
-
|
45
|
-
# The line of the template on which the error occurred.
|
46
|
-
#
|
47
|
-
# @return [Fixnum]
|
48
5
|
attr_reader :line
|
49
6
|
|
50
|
-
# @param message [String] The error message
|
51
|
-
# @param line [Fixnum] See \{#line}
|
52
7
|
def initialize(message = nil, line = nil)
|
53
8
|
super(message)
|
54
9
|
@line = line
|
55
10
|
end
|
56
11
|
end
|
57
12
|
|
58
|
-
# SyntaxError is the type of exception raised when Haml encounters an
|
59
|
-
# ill-formatted document.
|
60
|
-
# It's not particularly interesting,
|
61
|
-
# except in that it's a subclass of {Haml::Error}.
|
62
13
|
class SyntaxError < Error; end
|
63
|
-
|
64
|
-
class
|
14
|
+
class InternalError < Error; end
|
15
|
+
class FilterNotFound < Error; end
|
65
16
|
end
|
data/lib/haml/escapable.rb
CHANGED
@@ -1,77 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'haml/util'
|
2
3
|
|
3
4
|
module Haml
|
4
|
-
|
5
|
-
|
6
|
-
class Escapable < Temple::Filter
|
7
|
-
# Special value of `flag` to ignore html_safe?
|
8
|
-
EscapeSafeBuffer = Struct.new(:value)
|
9
|
-
|
10
|
-
def initialize(*)
|
5
|
+
class Escapable < Temple::Filters::Escapable
|
6
|
+
def initialize(opts = {})
|
11
7
|
super
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def on_escape(flag, exp)
|
17
|
-
old_escape, old_escape_safe_buffer = @escape, @escape_safe_buffer
|
18
|
-
@escape_safe_buffer = flag.is_a?(EscapeSafeBuffer)
|
19
|
-
@escape = @escape_safe_buffer ? flag.value : flag
|
20
|
-
compile(exp)
|
21
|
-
ensure
|
22
|
-
@escape, @escape_safe_buffer = old_escape, old_escape_safe_buffer
|
23
|
-
end
|
24
|
-
|
25
|
-
# The same as Haml::AttributeBuilder.build_attributes
|
26
|
-
def on_static(value)
|
27
|
-
[:static,
|
28
|
-
if @escape == :once
|
29
|
-
escape_once(value)
|
30
|
-
elsif @escape
|
31
|
-
escape(value)
|
32
|
-
else
|
33
|
-
value
|
34
|
-
end
|
35
|
-
]
|
36
|
-
end
|
37
|
-
|
38
|
-
# The same as Haml::AttributeBuilder.build_attributes
|
39
|
-
def on_dynamic(value)
|
40
|
-
[:dynamic,
|
41
|
-
if @escape == :once
|
42
|
-
escape_once_code(value)
|
43
|
-
elsif @escape
|
44
|
-
escape_code(value)
|
45
|
-
else
|
46
|
-
"(#{value}).to_s"
|
47
|
-
end
|
48
|
-
]
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def escape_once(value)
|
54
|
-
if @escape_safe_buffer
|
55
|
-
::Haml::Helpers.escape_once_without_haml_xss(value)
|
56
|
-
else
|
57
|
-
::Haml::Helpers.escape_once(value)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def escape(value)
|
62
|
-
if @escape_safe_buffer
|
63
|
-
::Haml::Helpers.html_escape_without_haml_xss(value)
|
64
|
-
else
|
65
|
-
::Haml::Helpers.html_escape(value)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def escape_once_code(value)
|
70
|
-
"::Haml::Helpers.escape_once#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))"
|
71
|
-
end
|
72
|
-
|
73
|
-
def escape_code(value)
|
74
|
-
"::Haml::Helpers.html_escape#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))"
|
8
|
+
@escape_code = options[:escape_code] ||
|
9
|
+
"::Haml::Util.escape_html#{options[:use_html_safe] ? '_safe' : ''}((%s))"
|
10
|
+
@escaper = eval("proc {|v| #{@escape_code % 'v'} }")
|
75
11
|
end
|
76
12
|
end
|
77
13
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
class Filters
|
4
|
+
class Cdata < TextBase
|
5
|
+
def compile(node)
|
6
|
+
compile_cdata(node)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def compile_cdata(node)
|
12
|
+
temple = [:multi]
|
13
|
+
temple << [:static, "<![CDATA[\n"]
|
14
|
+
compile_text!(temple, node, ' ')
|
15
|
+
temple << [:static, "\n]]>"]
|
16
|
+
temple
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
class Filters
|
4
|
+
class Coffee < TiltBase
|
5
|
+
def compile(node)
|
6
|
+
require 'tilt/coffee' if explicit_require?('coffee')
|
7
|
+
temple = [:multi]
|
8
|
+
temple << [:static, "<script>\n"]
|
9
|
+
temple << compile_with_tilt(node, 'coffee', indent_width: 2)
|
10
|
+
temple << [:static, "</script>"]
|
11
|
+
temple
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
CoffeeScript = Coffee
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
class Filters
|
4
|
+
class Css < TextBase
|
5
|
+
def compile(node)
|
6
|
+
case @format
|
7
|
+
when :xhtml
|
8
|
+
compile_xhtml(node)
|
9
|
+
else
|
10
|
+
compile_html(node)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def compile_html(node)
|
17
|
+
temple = [:multi]
|
18
|
+
temple << [:static, "<style>\n"]
|
19
|
+
compile_text!(temple, node, ' ')
|
20
|
+
temple << [:static, "\n</style>"]
|
21
|
+
temple
|
22
|
+
end
|
23
|
+
|
24
|
+
def compile_xhtml(node)
|
25
|
+
temple = [:multi]
|
26
|
+
temple << [:static, "<style type='text/css'>\n /*<![CDATA[*/\n"]
|
27
|
+
compile_text!(temple, node, ' ')
|
28
|
+
temple << [:static, "\n /*]]>*/\n</style>"]
|
29
|
+
temple
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
class Filters
|
4
|
+
class Escaped < Base
|
5
|
+
def compile(node)
|
6
|
+
text = node.value[:text].rstrip
|
7
|
+
temple = compile_text(text)
|
8
|
+
[:escape, true, temple]
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def compile_text(text)
|
14
|
+
if ::Haml::Util.contains_interpolation?(text)
|
15
|
+
[:dynamic, ::Haml::Util.unescape_interpolation(text)]
|
16
|
+
else
|
17
|
+
[:static, text]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
class Filters
|
4
|
+
class Javascript < TextBase
|
5
|
+
def compile(node)
|
6
|
+
case @format
|
7
|
+
when :xhtml
|
8
|
+
compile_xhtml(node)
|
9
|
+
else
|
10
|
+
compile_html(node)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def compile_html(node)
|
17
|
+
temple = [:multi]
|
18
|
+
temple << [:static, "<script>\n"]
|
19
|
+
compile_text!(temple, node, ' ')
|
20
|
+
temple << [:static, "\n</script>"]
|
21
|
+
temple
|
22
|
+
end
|
23
|
+
|
24
|
+
def compile_xhtml(node)
|
25
|
+
temple = [:multi]
|
26
|
+
temple << [:static, "<script type='text/javascript'>\n //<![CDATA[\n"]
|
27
|
+
compile_text!(temple, node, ' ')
|
28
|
+
temple << [:static, "\n //]]>\n</script>"]
|
29
|
+
temple
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# LESS support is deprecated since it requires therubyracer.gem,
|
3
|
+
# which is hard to maintain.
|
4
|
+
#
|
5
|
+
# It's not supported in Sprockets 3.0+ too.
|
6
|
+
# https://github.com/sstephenson/sprockets/pull/547
|
7
|
+
module Haml
|
8
|
+
class Filters
|
9
|
+
class Less < TiltBase
|
10
|
+
def compile(node)
|
11
|
+
require 'tilt/less' if explicit_require?('less')
|
12
|
+
temple = [:multi]
|
13
|
+
temple << [:static, "<style>\n"]
|
14
|
+
temple << compile_with_tilt(node, 'less', indent_width: 2)
|
15
|
+
temple << [:static, '</style>']
|
16
|
+
temple
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'haml/string_splitter'
|
3
|
+
|
4
|
+
module Haml
|
5
|
+
class Filters
|
6
|
+
class Plain < Base
|
7
|
+
def compile(node)
|
8
|
+
text = node.value[:text]
|
9
|
+
text = text.rstrip unless ::Haml::Util.contains_interpolation?(text) # for compatibility
|
10
|
+
[:multi, *compile_plain(text)]
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def compile_plain(text)
|
16
|
+
string_literal = ::Haml::Util.unescape_interpolation(text)
|
17
|
+
StringSplitter.compile(string_literal).map do |temple|
|
18
|
+
type, str = temple
|
19
|
+
case type
|
20
|
+
when :dynamic
|
21
|
+
[:escape, false, [:dynamic, str]]
|
22
|
+
else
|
23
|
+
temple
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
class Filters
|
4
|
+
class Preserve < Base
|
5
|
+
def compile(node)
|
6
|
+
text = node.value[:text].rstrip + "\n"
|
7
|
+
text = text.gsub("\n", '
')
|
8
|
+
compile_text(text)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def compile_text(text)
|
14
|
+
if ::Haml::Util.contains_interpolation?(text)
|
15
|
+
[:dynamic, ::Haml::Util.unescape_interpolation(text)]
|
16
|
+
else
|
17
|
+
[:static, text]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|