hamlit 2.9.5-java → 2.13.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +17 -11
- data/CHANGELOG.md +52 -0
- data/Gemfile +2 -8
- data/LICENSE.txt +26 -23
- data/REFERENCE.md +13 -4
- data/benchmark/dynamic_merger/benchmark.rb +25 -0
- data/benchmark/dynamic_merger/hello.haml +50 -0
- data/benchmark/dynamic_merger/hello.string +50 -0
- data/bin/bench +3 -3
- data/bin/update-haml +125 -0
- data/ext/hamlit/hamlit.c +0 -1
- data/hamlit.gemspec +3 -1
- data/lib/hamlit/attribute_builder.rb +2 -2
- data/lib/hamlit/attribute_compiler.rb +3 -3
- data/lib/hamlit/compiler/children_compiler.rb +18 -4
- data/lib/hamlit/compiler/comment_compiler.rb +8 -5
- data/lib/hamlit/compiler/tag_compiler.rb +0 -4
- data/lib/hamlit/dynamic_merger.rb +67 -0
- data/lib/hamlit/engine.rb +5 -6
- data/lib/hamlit/filters/escaped.rb +1 -1
- data/lib/hamlit/filters/markdown.rb +1 -0
- data/lib/hamlit/filters/plain.rb +0 -4
- 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/html.rb +8 -0
- data/lib/hamlit/parser.rb +6 -2
- data/lib/hamlit/parser/haml_attribute_builder.rb +164 -0
- 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 +41 -59
- data/lib/hamlit/parser/{haml_xss_mods.rb → haml_helpers/xss_mods.rb} +20 -15
- data/lib/hamlit/parser/haml_options.rb +53 -66
- data/lib/hamlit/parser/haml_parser.rb +103 -71
- 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 +10 -78
- data/lib/hamlit/template.rb +1 -1
- data/lib/hamlit/temple_line_counter.rb +31 -0
- data/lib/hamlit/version.rb +1 -1
- metadata +58 -24
- data/lib/hamlit/hamlit.su +0 -0
- data/lib/hamlit/parser/MIT-LICENSE +0 -20
- data/lib/hamlit/parser/README.md +0 -30
@@ -1,31 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Hamlit
|
2
4
|
# An exception raised by Haml code.
|
3
5
|
class HamlError < StandardError
|
4
6
|
|
5
7
|
MESSAGES = {
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
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
|
29
31
|
You don't need to use "- end" in Haml. Un-indent to close a block:
|
30
32
|
- if foo?
|
31
33
|
%strong Foo!
|
@@ -33,7 +35,7 @@ You don't need to use "- end" in Haml. Un-indent to close a block:
|
|
33
35
|
Not foo.
|
34
36
|
%p This line is un-indented, so it isn't part of the "if" block
|
35
37
|
END
|
36
|
-
}
|
38
|
+
}.freeze
|
37
39
|
|
38
40
|
def self.message(key, *args)
|
39
41
|
string = MESSAGES[key] or raise "[HAML BUG] No error messages for #{key}"
|
@@ -56,6 +58,8 @@ END
|
|
56
58
|
# SyntaxError is the type of exception raised when Haml encounters an
|
57
59
|
# ill-formatted document.
|
58
60
|
# It's not particularly interesting,
|
59
|
-
# except in that it's a subclass of {
|
61
|
+
# except in that it's a subclass of {Hamlit::HamlError}.
|
60
62
|
class HamlSyntaxError < HamlError; end
|
63
|
+
|
64
|
+
class HamlInvalidAttributeNameError < HamlSyntaxError; end
|
61
65
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
class Hamlit::HamlEscapable; end
|
@@ -0,0 +1 @@
|
|
1
|
+
class Hamlit::HamlGenerator; end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
4
|
-
require 'hamlit/parser/haml_parser'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
5
4
|
|
6
5
|
module Hamlit
|
7
6
|
# This module contains various helpful methods to make it easier to do various tasks.
|
8
|
-
# {
|
7
|
+
# {Hamlit::HamlHelpers} is automatically included in the context
|
9
8
|
# that a Haml template is parsed in, so all these methods are at your
|
10
9
|
# disposal from within the template.
|
11
10
|
module HamlHelpers
|
@@ -23,10 +22,10 @@ MESSAGE
|
|
23
22
|
|
24
23
|
# Raises an error.
|
25
24
|
#
|
26
|
-
# @raise [
|
25
|
+
# @raise [Hamlit::HamlError] The error
|
27
26
|
def to_s
|
28
|
-
raise
|
29
|
-
rescue
|
27
|
+
raise Hamlit::HamlError.new(@message)
|
28
|
+
rescue Hamlit::HamlError => e
|
30
29
|
e.backtrace.shift
|
31
30
|
|
32
31
|
# If the ErrorReturn is used directly in the template,
|
@@ -45,7 +44,7 @@ MESSAGE
|
|
45
44
|
|
46
45
|
# @return [String] A human-readable string representation
|
47
46
|
def inspect
|
48
|
-
"
|
47
|
+
"Hamlit::HamlHelpers::ErrorReturn(#{@message.inspect})"
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
@@ -69,13 +68,13 @@ MESSAGE
|
|
69
68
|
#
|
70
69
|
# context = Object.new
|
71
70
|
# class << context
|
72
|
-
# include
|
71
|
+
# include Hamlit::HamlHelpers
|
73
72
|
# end
|
74
73
|
# context.init_haml_helpers
|
75
74
|
# context.haml_tag :p, "Stuff"
|
76
75
|
#
|
77
76
|
def init_haml_helpers
|
78
|
-
@haml_buffer =
|
77
|
+
@haml_buffer = Hamlit::HamlBuffer.new(haml_buffer, HamlOptions.new.for_buffer)
|
79
78
|
nil
|
80
79
|
end
|
81
80
|
|
@@ -111,10 +110,7 @@ MESSAGE
|
|
111
110
|
# @yield The block within which to escape newlines
|
112
111
|
def find_and_preserve(input = nil, tags = haml_buffer.options[:preserve], &block)
|
113
112
|
return find_and_preserve(capture_haml(&block), input || tags) if block
|
114
|
-
tags = tags.
|
115
|
-
s << '|' unless s.empty?
|
116
|
-
s << Regexp.escape(t)
|
117
|
-
end
|
113
|
+
tags = tags.map { |tag| Regexp.escape(tag) }.join('|')
|
118
114
|
re = /<(#{tags})([^>]*)>(.*?)(<\/\1>)/im
|
119
115
|
input.to_s.gsub(re) do |s|
|
120
116
|
s =~ re # Can't rely on $1, etc. existing since Rails' SafeBuffer#gsub is incompatible
|
@@ -202,20 +198,19 @@ MESSAGE
|
|
202
198
|
# @yield [item] A block which contains Haml code that goes within list items
|
203
199
|
# @yieldparam item An element of `enum`
|
204
200
|
def list_of(enum, opts={}, &block)
|
205
|
-
opts_attributes = opts.
|
206
|
-
enum.
|
201
|
+
opts_attributes = opts.map { |k, v| " #{k}='#{v}'" }.join
|
202
|
+
enum.map do |i|
|
207
203
|
result = capture_haml(i, &block)
|
208
204
|
|
209
205
|
if result.count("\n") > 1
|
210
206
|
result.gsub!("\n", "\n ")
|
211
|
-
result = "\n #{result.strip
|
207
|
+
result = "\n #{result.strip}\n"
|
212
208
|
else
|
213
209
|
result.strip!
|
214
210
|
end
|
215
211
|
|
216
|
-
|
217
|
-
|
218
|
-
end
|
212
|
+
%Q!<li#{opts_attributes}>#{result}</li>!
|
213
|
+
end.join("\n")
|
219
214
|
end
|
220
215
|
|
221
216
|
# Returns a hash containing default assignments for the `xmlns`, `lang`, and `xml:lang`
|
@@ -389,8 +384,7 @@ MESSAGE
|
|
389
384
|
captured = (value.is_a?(String) ? value : nil)
|
390
385
|
end
|
391
386
|
|
392
|
-
|
393
|
-
return (haml_buffer.options[:ugly] ? captured : prettify(captured))
|
387
|
+
captured
|
394
388
|
end
|
395
389
|
ensure
|
396
390
|
haml_buffer.capture_position = nil
|
@@ -417,7 +411,7 @@ MESSAGE
|
|
417
411
|
# @param newline [Boolean] Whether to add a newline after the text
|
418
412
|
# @param indent [Boolean] Whether to add indentation to the first line
|
419
413
|
def haml_internal_concat(text = "", newline = true, indent = true)
|
420
|
-
if haml_buffer.
|
414
|
+
if haml_buffer.tabulation == 0
|
421
415
|
haml_buffer.buffer << "#{text}#{"\n" if newline}"
|
422
416
|
else
|
423
417
|
haml_buffer.buffer << %[#{haml_indent if indent}#{text.to_s.gsub("\n", "\n#{haml_indent}")}#{"\n" if newline}]
|
@@ -501,7 +495,7 @@ MESSAGE
|
|
501
495
|
attrs.keys.each {|key| attrs[key.to_s] = attrs.delete(key)} unless attrs.empty?
|
502
496
|
name, attrs = merge_name_and_attributes(name.to_s, attrs)
|
503
497
|
|
504
|
-
attributes =
|
498
|
+
attributes = Hamlit::HamlAttributeBuilder.build_attributes(haml_buffer.html?,
|
505
499
|
haml_buffer.options[:attr_wrapper],
|
506
500
|
haml_buffer.options[:escape_attrs],
|
507
501
|
haml_buffer.options[:hyphenate_data_attrs],
|
@@ -513,8 +507,8 @@ MESSAGE
|
|
513
507
|
end
|
514
508
|
|
515
509
|
if flags.include?(:/)
|
516
|
-
raise
|
517
|
-
raise
|
510
|
+
raise HamlError.new(HamlError.message(:self_closing_content)) if text
|
511
|
+
raise HamlError.new(HamlError.message(:illegal_nesting_self_closing)) if block
|
518
512
|
end
|
519
513
|
|
520
514
|
tag = "<#{name}#{attributes}>"
|
@@ -536,7 +530,7 @@ MESSAGE
|
|
536
530
|
end
|
537
531
|
|
538
532
|
if text
|
539
|
-
raise
|
533
|
+
raise HamlError.new(HamlError.message(:illegal_nesting_line, name))
|
540
534
|
end
|
541
535
|
|
542
536
|
if flags.include?(:<)
|
@@ -599,9 +593,9 @@ MESSAGE
|
|
599
593
|
end
|
600
594
|
|
601
595
|
# Characters that need to be escaped to HTML entities from user input
|
602
|
-
HTML_ESCAPE = {
|
596
|
+
HTML_ESCAPE = {'&' => '&', '<' => '<', '>' => '>', '"' => '"', "'" => '''}.freeze
|
603
597
|
|
604
|
-
HTML_ESCAPE_REGEX = /[
|
598
|
+
HTML_ESCAPE_REGEX = /['"><&]/
|
605
599
|
|
606
600
|
# Returns a copy of `text` with ampersands, angle brackets and quotes
|
607
601
|
# escaped into HTML entities.
|
@@ -613,11 +607,13 @@ MESSAGE
|
|
613
607
|
# @param text [String] The string to sanitize
|
614
608
|
# @return [String] The sanitized string
|
615
609
|
def html_escape(text)
|
616
|
-
text
|
617
|
-
text.gsub(HTML_ESCAPE_REGEX, HTML_ESCAPE)
|
610
|
+
CGI.escapeHTML(text.to_s)
|
618
611
|
end
|
619
612
|
|
620
|
-
|
613
|
+
# Always escape text regardless of html_safe?
|
614
|
+
alias_method :html_escape_without_haml_xss, :html_escape
|
615
|
+
|
616
|
+
HTML_ESCAPE_ONCE_REGEX = /['"><]|&(?!(?:[a-zA-Z]+|#(?:\d+|[xX][0-9a-fA-F]+));)/
|
621
617
|
|
622
618
|
# Escapes HTML entities in `text`, but without escaping an ampersand
|
623
619
|
# that is already part of an escaped entity.
|
@@ -629,9 +625,12 @@ MESSAGE
|
|
629
625
|
text.gsub(HTML_ESCAPE_ONCE_REGEX, HTML_ESCAPE)
|
630
626
|
end
|
631
627
|
|
628
|
+
# Always escape text once regardless of html_safe?
|
629
|
+
alias_method :escape_once_without_haml_xss, :escape_once
|
630
|
+
|
632
631
|
# Returns whether or not the current template is a Haml template.
|
633
632
|
#
|
634
|
-
# This function, unlike other {
|
633
|
+
# This function, unlike other {Hamlit::HamlHelpers} functions,
|
635
634
|
# also works in other `ActionView` templates,
|
636
635
|
# where it will always return false.
|
637
636
|
#
|
@@ -656,13 +655,13 @@ MESSAGE
|
|
656
655
|
# skip merging if no ids or classes found in name
|
657
656
|
return name, attributes_hash unless name =~ /^(.+?)?([\.#].*)$/
|
658
657
|
|
659
|
-
return $1 || "div",
|
660
|
-
|
658
|
+
return $1 || "div", HamlAttributeBuilder.merge_attributes!(
|
659
|
+
Hamlit::HamlParser.parse_class_and_id($2), attributes_hash)
|
661
660
|
end
|
662
661
|
|
663
662
|
# Runs a block of code with the given buffer as the currently active buffer.
|
664
663
|
#
|
665
|
-
# @param buffer [
|
664
|
+
# @param buffer [Hamlit::HamlBuffer] The Haml buffer to use temporarily
|
666
665
|
# @yield A block in which the given buffer should be used
|
667
666
|
def with_haml_buffer(buffer)
|
668
667
|
@haml_buffer, old_buffer = buffer, @haml_buffer
|
@@ -675,9 +674,9 @@ MESSAGE
|
|
675
674
|
@haml_buffer = old_buffer
|
676
675
|
end
|
677
676
|
|
678
|
-
# The current {
|
677
|
+
# The current {Hamlit::HamlBuffer} object.
|
679
678
|
#
|
680
|
-
# @return [
|
679
|
+
# @return [Hamlit::HamlBuffer]
|
681
680
|
def haml_buffer
|
682
681
|
@haml_buffer if defined? @haml_buffer
|
683
682
|
end
|
@@ -693,22 +692,6 @@ MESSAGE
|
|
693
692
|
_erbout = _erbout = _hamlout.buffer
|
694
693
|
proc { |*args| proc.call(*args) }
|
695
694
|
end
|
696
|
-
|
697
|
-
def prettify(text)
|
698
|
-
text = text.split(/^/)
|
699
|
-
text.delete('')
|
700
|
-
|
701
|
-
min_tabs = nil
|
702
|
-
text.each do |line|
|
703
|
-
tabs = line.index(/[^ ]/) || line.length
|
704
|
-
min_tabs ||= tabs
|
705
|
-
min_tabs = min_tabs > tabs ? tabs : min_tabs
|
706
|
-
end
|
707
|
-
|
708
|
-
text.each_with_object('') do |line, str|
|
709
|
-
str << line.slice(min_tabs, line.length)
|
710
|
-
end
|
711
|
-
end
|
712
695
|
end
|
713
696
|
end
|
714
697
|
|
@@ -720,8 +703,7 @@ class Object
|
|
720
703
|
# is a proper Haml context.
|
721
704
|
# Because `ActionView` helpers may be included in non-`ActionView::Base` classes,
|
722
705
|
# it's a good idea to define \{#is\_haml?} for all objects.
|
723
|
-
def is_haml?
|
724
|
-
|
725
|
-
end
|
726
|
-
alias :is_haml? :is_haml?
|
706
|
+
# def is_haml?
|
707
|
+
# false
|
708
|
+
# end
|
727
709
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Hamlit
|
2
4
|
module HamlHelpers
|
3
5
|
# This module overrides Haml helpers to work properly
|
@@ -6,12 +8,15 @@ module Hamlit
|
|
6
8
|
# to work with Rails' XSS protection methods.
|
7
9
|
module XssMods
|
8
10
|
def self.included(base)
|
9
|
-
%w[
|
10
|
-
precede succeed capture_haml haml_concat haml_internal_concat haml_indent
|
11
|
-
escape_once].each do |name|
|
11
|
+
%w[find_and_preserve preserve list_of surround
|
12
|
+
precede succeed capture_haml haml_concat haml_internal_concat haml_indent].each do |name|
|
12
13
|
base.send(:alias_method, "#{name}_without_haml_xss", name)
|
13
14
|
base.send(:alias_method, name, "#{name}_with_haml_xss")
|
14
15
|
end
|
16
|
+
# Those two always have _without_haml_xss
|
17
|
+
%w[html_escape escape_once].each do |name|
|
18
|
+
base.send(:alias_method, name, "#{name}_with_haml_xss")
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
# Don't escape text that's already safe,
|
@@ -19,27 +24,27 @@ module Hamlit
|
|
19
24
|
def html_escape_with_haml_xss(text)
|
20
25
|
str = text.to_s
|
21
26
|
return text if str.html_safe?
|
22
|
-
|
27
|
+
Hamlit::HamlUtil.html_safe(html_escape_without_haml_xss(str))
|
23
28
|
end
|
24
29
|
|
25
30
|
# Output is always HTML safe
|
26
31
|
def find_and_preserve_with_haml_xss(*args, &block)
|
27
|
-
|
32
|
+
Hamlit::HamlUtil.html_safe(find_and_preserve_without_haml_xss(*args, &block))
|
28
33
|
end
|
29
34
|
|
30
35
|
# Output is always HTML safe
|
31
36
|
def preserve_with_haml_xss(*args, &block)
|
32
|
-
|
37
|
+
Hamlit::HamlUtil.html_safe(preserve_without_haml_xss(*args, &block))
|
33
38
|
end
|
34
39
|
|
35
40
|
# Output is always HTML safe
|
36
41
|
def list_of_with_haml_xss(*args, &block)
|
37
|
-
|
42
|
+
Hamlit::HamlUtil.html_safe(list_of_without_haml_xss(*args, &block))
|
38
43
|
end
|
39
44
|
|
40
45
|
# Input is escaped, output is always HTML safe
|
41
46
|
def surround_with_haml_xss(front, back = front, &block)
|
42
|
-
|
47
|
+
Hamlit::HamlUtil.html_safe(
|
43
48
|
surround_without_haml_xss(
|
44
49
|
haml_xss_html_escape(front),
|
45
50
|
haml_xss_html_escape(back),
|
@@ -48,21 +53,21 @@ module Hamlit
|
|
48
53
|
|
49
54
|
# Input is escaped, output is always HTML safe
|
50
55
|
def precede_with_haml_xss(str, &block)
|
51
|
-
|
56
|
+
Hamlit::HamlUtil.html_safe(precede_without_haml_xss(haml_xss_html_escape(str), &block))
|
52
57
|
end
|
53
58
|
|
54
59
|
# Input is escaped, output is always HTML safe
|
55
60
|
def succeed_with_haml_xss(str, &block)
|
56
|
-
|
61
|
+
Hamlit::HamlUtil.html_safe(succeed_without_haml_xss(haml_xss_html_escape(str), &block))
|
57
62
|
end
|
58
63
|
|
59
64
|
# Output is always HTML safe
|
60
65
|
def capture_haml_with_haml_xss(*args, &block)
|
61
|
-
|
66
|
+
Hamlit::HamlUtil.html_safe(capture_haml_without_haml_xss(*args, &block))
|
62
67
|
end
|
63
68
|
|
64
69
|
# Input will be escaped unless this is in a `with_raw_haml_concat`
|
65
|
-
# block. See #
|
70
|
+
# block. See #Hamlit::HamlHelpers::ActionViewExtensions#with_raw_haml_concat.
|
66
71
|
def haml_concat_with_haml_xss(text = "")
|
67
72
|
raw = instance_variable_defined?(:@_haml_concat_raw) ? @_haml_concat_raw : false
|
68
73
|
if raw
|
@@ -81,12 +86,12 @@ module Hamlit
|
|
81
86
|
|
82
87
|
# Output is always HTML safe
|
83
88
|
def haml_indent_with_haml_xss
|
84
|
-
|
89
|
+
Hamlit::HamlUtil.html_safe(haml_indent_without_haml_xss)
|
85
90
|
end
|
86
91
|
|
87
92
|
# Output is always HTML safe
|
88
93
|
def escape_once_with_haml_xss(*args)
|
89
|
-
|
94
|
+
Hamlit::HamlUtil.html_safe(escape_once_without_haml_xss(*args))
|
90
95
|
end
|
91
96
|
|
92
97
|
private
|
@@ -94,7 +99,7 @@ module Hamlit
|
|
94
99
|
# Escapes the HTML in the text if and only if
|
95
100
|
# Rails XSS protection is enabled *and* the `:escape_html` option is set.
|
96
101
|
def haml_xss_html_escape(text)
|
97
|
-
return text unless
|
102
|
+
return text unless Hamlit::HamlUtil.rails_xss_safe? && haml_buffer.options[:escape_html]
|
98
103
|
html_escape(text)
|
99
104
|
end
|
100
105
|
end
|
@@ -1,58 +1,45 @@
|
|
1
|
-
|
2
|
-
require 'hamlit/parser/haml_compiler'
|
3
|
-
require 'hamlit/parser/haml_error'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
3
|
module Hamlit
|
6
4
|
# This class encapsulates all of the configuration options that Haml
|
7
5
|
# understands. Please see the {file:REFERENCE.md#options Haml Reference} to
|
8
6
|
# learn how to set the options.
|
9
7
|
class HamlOptions
|
10
|
-
|
11
|
-
@defaults = {
|
12
|
-
:attr_wrapper => "'",
|
13
|
-
:autoclose => %w(area base basefont br col command embed frame
|
14
|
-
hr img input isindex keygen link menuitem meta
|
15
|
-
param source track wbr),
|
16
|
-
:encoding => "UTF-8",
|
17
|
-
:escape_attrs => true,
|
18
|
-
:escape_html => false,
|
19
|
-
:filename => '(haml)',
|
20
|
-
:format => :html5,
|
21
|
-
:hyphenate_data_attrs => true,
|
22
|
-
:line => 1,
|
23
|
-
:mime_type => 'text/html',
|
24
|
-
:preserve => %w(textarea pre code),
|
25
|
-
:remove_whitespace => false,
|
26
|
-
:suppress_eval => false,
|
27
|
-
:ugly => false,
|
28
|
-
:cdata => false,
|
29
|
-
:parser_class => ::Hamlit::HamlParser,
|
30
|
-
:compiler_class => ::Hamlit::HamlCompiler,
|
31
|
-
:trace => false
|
32
|
-
}
|
33
|
-
|
34
8
|
@valid_formats = [:html4, :html5, :xhtml]
|
9
|
+
@buffer_option_keys = [:autoclose, :preserve, :attr_wrapper, :format,
|
10
|
+
:encoding, :escape_html, :escape_filter_interpolations, :escape_attrs, :hyphenate_data_attrs, :cdata]
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# The default option values.
|
14
|
+
# @return Hash
|
15
|
+
def defaults
|
16
|
+
@defaults ||= Hamlit::HamlTempleEngine.options.to_hash.merge(encoding: 'UTF-8')
|
17
|
+
end
|
35
18
|
|
36
|
-
|
37
|
-
|
19
|
+
# An array of valid values for the `:format` option.
|
20
|
+
# @return Array
|
21
|
+
attr_reader :valid_formats
|
38
22
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
23
|
+
# An array of keys that will be used to provide a hash of options to
|
24
|
+
# {Hamlit::HamlBuffer}.
|
25
|
+
# @return Hash
|
26
|
+
attr_reader :buffer_option_keys
|
44
27
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
28
|
+
# Returns a subset of defaults: those that {Hamlit::HamlBuffer} cares about.
|
29
|
+
# @return [{Symbol => Object}] The options hash
|
30
|
+
def buffer_defaults
|
31
|
+
@buffer_defaults ||= buffer_option_keys.inject({}) do |hash, key|
|
32
|
+
hash.merge(key => defaults[key])
|
33
|
+
end
|
34
|
+
end
|
50
35
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
36
|
+
def wrap(options)
|
37
|
+
if options.is_a?(HamlOptions)
|
38
|
+
options
|
39
|
+
else
|
40
|
+
HamlOptions.new(options)
|
41
|
+
end
|
42
|
+
end
|
56
43
|
end
|
57
44
|
|
58
45
|
# The character that should wrap element attributes. This defaults to `'`
|
@@ -95,6 +82,13 @@ module Hamlit
|
|
95
82
|
# Defaults to false.
|
96
83
|
attr_accessor :escape_html
|
97
84
|
|
85
|
+
# Sets whether or not to escape HTML-sensitive characters in interpolated strings.
|
86
|
+
# See also {file:REFERENCE.md#escaping_html Escaping HTML} and
|
87
|
+
# {file:REFERENCE.md#unescaping_html Unescaping HTML}.
|
88
|
+
#
|
89
|
+
# Defaults to the current value of `escape_html`.
|
90
|
+
attr_accessor :escape_filter_interpolations
|
91
|
+
|
98
92
|
# The name of the Haml file being parsed.
|
99
93
|
# This is only used as information when exceptions are raised. This is
|
100
94
|
# automatically assigned when working through ActionView, so it's really
|
@@ -128,7 +122,7 @@ module Hamlit
|
|
128
122
|
attr_accessor :mime_type
|
129
123
|
|
130
124
|
# A list of tag names that should automatically have their newlines
|
131
|
-
# preserved using the {
|
125
|
+
# preserved using the {Hamlit::HamlHelpers#preserve} helper. This means that any
|
132
126
|
# content given on the same line as the tag will be preserved. For example,
|
133
127
|
# `%textarea= "Foo\nBar"` compiles to `<textarea>Foo
Bar</textarea>`.
|
134
128
|
# Defaults to `['textarea', 'pre']`. See also
|
@@ -141,7 +135,7 @@ module Hamlit
|
|
141
135
|
# formatting errors.
|
142
136
|
#
|
143
137
|
# Defaults to `false`.
|
144
|
-
|
138
|
+
attr_accessor :remove_whitespace
|
145
139
|
|
146
140
|
# Whether or not attribute hashes and Ruby scripts designated by `=` or `~`
|
147
141
|
# should be evaluated. If this is `true`, said scripts are rendered as empty
|
@@ -150,13 +144,6 @@ module Hamlit
|
|
150
144
|
# Defaults to `false`.
|
151
145
|
attr_accessor :suppress_eval
|
152
146
|
|
153
|
-
# If set to `true`, Haml makes no attempt to properly indent or format the
|
154
|
-
# HTML output. This significantly improves rendering performance but makes
|
155
|
-
# viewing the source unpleasant.
|
156
|
-
#
|
157
|
-
# Defaults to `true` in Rails production mode, and `false` everywhere else.
|
158
|
-
attr_accessor :ugly
|
159
|
-
|
160
147
|
# Whether to include CDATA sections around javascript and css blocks when
|
161
148
|
# using the `:javascript` or `:css` filters.
|
162
149
|
#
|
@@ -167,10 +154,10 @@ module Hamlit
|
|
167
154
|
# xhtml.
|
168
155
|
attr_accessor :cdata
|
169
156
|
|
170
|
-
# The parser class to use. Defaults to
|
157
|
+
# The parser class to use. Defaults to Hamlit::HamlParser.
|
171
158
|
attr_accessor :parser_class
|
172
159
|
|
173
|
-
# The compiler class to use. Defaults to
|
160
|
+
# The compiler class to use. Defaults to Hamlit::HamlCompiler.
|
174
161
|
attr_accessor :compiler_class
|
175
162
|
|
176
163
|
# Enable template tracing. If true, it will add a 'data-trace' attribute to
|
@@ -181,7 +168,10 @@ module Hamlit
|
|
181
168
|
# the path will be the full path.
|
182
169
|
attr_accessor :trace
|
183
170
|
|
184
|
-
|
171
|
+
# Key is filter name in String and value is Class to use. Defaults to {}.
|
172
|
+
attr_accessor :filters
|
173
|
+
|
174
|
+
def initialize(values = {})
|
185
175
|
defaults.each {|k, v| instance_variable_set :"@#{k}", v}
|
186
176
|
values.each {|k, v| send("#{k}=", v) if defaults.has_key?(k) && !v.nil?}
|
187
177
|
yield if block_given?
|
@@ -200,8 +190,7 @@ module Hamlit
|
|
200
190
|
send "#{key}=", value
|
201
191
|
end
|
202
192
|
|
203
|
-
[:escape_attrs, :hyphenate_data_attrs, :remove_whitespace, :suppress_eval
|
204
|
-
:ugly].each do |method|
|
193
|
+
[:escape_attrs, :hyphenate_data_attrs, :remove_whitespace, :suppress_eval].each do |method|
|
205
194
|
class_eval(<<-END)
|
206
195
|
def #{method}?
|
207
196
|
!! @#{method}
|
@@ -242,7 +231,7 @@ module Hamlit
|
|
242
231
|
|
243
232
|
def format=(value)
|
244
233
|
unless self.class.valid_formats.include?(value)
|
245
|
-
raise
|
234
|
+
raise Hamlit::HamlError, "Invalid output format #{value.inspect}"
|
246
235
|
end
|
247
236
|
@format = value
|
248
237
|
end
|
@@ -252,18 +241,13 @@ module Hamlit
|
|
252
241
|
xhtml? || @cdata
|
253
242
|
end
|
254
243
|
|
255
|
-
def remove_whitespace=(value)
|
256
|
-
@ugly = true if value
|
257
|
-
@remove_whitespace = value
|
258
|
-
end
|
259
|
-
|
260
244
|
def encoding=(value)
|
261
245
|
return unless value
|
262
246
|
@encoding = value.is_a?(Encoding) ? value.name : value.to_s
|
263
247
|
@encoding = "UTF-8" if @encoding.upcase == "US-ASCII"
|
264
248
|
end
|
265
249
|
|
266
|
-
# Returns a subset of options: those that {
|
250
|
+
# Returns a non-default subset of options: those that {Hamlit::HamlBuffer} cares about.
|
267
251
|
# All of the values here are such that when `#inspect` is called on the hash,
|
268
252
|
# it can be `Kernel#eval`ed to get the same result back.
|
269
253
|
#
|
@@ -272,7 +256,10 @@ module Hamlit
|
|
272
256
|
# @return [{Symbol => Object}] The options hash
|
273
257
|
def for_buffer
|
274
258
|
self.class.buffer_option_keys.inject({}) do |hash, key|
|
275
|
-
|
259
|
+
value = public_send(key)
|
260
|
+
if self.class.buffer_defaults[key] != value
|
261
|
+
hash[key] = value
|
262
|
+
end
|
276
263
|
hash
|
277
264
|
end
|
278
265
|
end
|