haml 2.2.17 → 2.2.18
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/.yardopts +3 -0
- data/Rakefile +6 -6
- data/VERSION +1 -1
- data/extra/haml-mode.el +99 -13
- data/extra/sass-mode.el +2 -2
- data/lib/haml/engine.rb +1 -1
- data/lib/haml/exec.rb +13 -5
- data/lib/haml/filters.rb +1 -1
- data/lib/haml/helpers.rb +3 -2
- data/lib/haml/helpers/action_view_mods.rb +2 -1
- data/lib/haml/helpers/xss_mods.rb +43 -13
- data/lib/haml/html.rb +8 -0
- data/lib/haml/precompiler.rb +20 -1
- data/lib/haml/template.rb +2 -2
- data/lib/haml/util.rb +27 -0
- data/lib/sass/engine.rb +42 -2
- data/lib/sass/plugin.rb +5 -4
- data/lib/sass/plugin/rails.rb +2 -2
- data/lib/sass/script.rb +3 -0
- data/lib/sass/script/color.rb +4 -2
- data/lib/sass/script/lexer.rb +8 -5
- data/lib/sass/script/number.rb +2 -0
- data/lib/sass/script/parser.rb +1 -1
- data/lib/sass/tree/rule_node.rb +1 -0
- data/test/haml/engine_test.rb +21 -0
- data/test/haml/helper_test.rb +0 -0
- data/test/haml/html2haml_test.rb +0 -0
- data/test/haml/spec/lua_haml_spec.lua +1 -1
- data/test/haml/spec/tests.json +64 -18
- data/test/haml/template_test.rb +17 -3
- data/test/haml/util_test.rb +0 -0
- data/test/sass/css2sass_test.rb +1 -0
- data/test/sass/engine_test.rb +31 -0
- data/test/sass/functions_test.rb +1 -0
- data/test/sass/plugin_test.rb +28 -17
- data/test/sass/script_test.rb +7 -7
- data/test/sass/to_sass_test.rb +549 -0
- metadata +144 -142
data/lib/haml/precompiler.rb
CHANGED
@@ -8,46 +8,60 @@ module Haml
|
|
8
8
|
include Haml::Util
|
9
9
|
|
10
10
|
# Designates an XHTML/XML element.
|
11
|
+
# @private
|
11
12
|
ELEMENT = ?%
|
12
13
|
|
13
14
|
# Designates a `<div>` element with the given class.
|
15
|
+
# @private
|
14
16
|
DIV_CLASS = ?.
|
15
17
|
|
16
18
|
# Designates a `<div>` element with the given id.
|
19
|
+
# @private
|
17
20
|
DIV_ID = ?#
|
18
21
|
|
19
22
|
# Designates an XHTML/XML comment.
|
23
|
+
# @private
|
20
24
|
COMMENT = ?/
|
21
25
|
|
22
26
|
# Designates an XHTML doctype or script that is never HTML-escaped.
|
27
|
+
# @private
|
23
28
|
DOCTYPE = ?!
|
24
29
|
|
25
30
|
# Designates script, the result of which is output.
|
31
|
+
# @private
|
26
32
|
SCRIPT = ?=
|
27
33
|
|
28
34
|
# Designates script that is always HTML-escaped.
|
35
|
+
# @private
|
29
36
|
SANITIZE = ?&
|
30
37
|
|
31
38
|
# Designates script, the result of which is flattened and output.
|
39
|
+
# @private
|
32
40
|
FLAT_SCRIPT = ?~
|
33
41
|
|
34
42
|
# Designates script which is run but not output.
|
43
|
+
# @private
|
35
44
|
SILENT_SCRIPT = ?-
|
36
45
|
|
37
46
|
# When following SILENT_SCRIPT, designates a comment that is not output.
|
47
|
+
# @private
|
38
48
|
SILENT_COMMENT = ?#
|
39
49
|
|
40
50
|
# Designates a non-parsed line.
|
51
|
+
# @private
|
41
52
|
ESCAPE = ?\\
|
42
53
|
|
43
54
|
# Designates a block of filtered text.
|
55
|
+
# @private
|
44
56
|
FILTER = ?:
|
45
57
|
|
46
58
|
# Designates a non-parsed line. Not actually a character.
|
59
|
+
# @private
|
47
60
|
PLAIN_TEXT = -1
|
48
61
|
|
49
62
|
# Keeps track of the ASCII values of the characters that begin a
|
50
63
|
# specially-interpreted line.
|
64
|
+
# @private
|
51
65
|
SPECIAL_CHARACTERS = [
|
52
66
|
ELEMENT,
|
53
67
|
DIV_CLASS,
|
@@ -64,6 +78,7 @@ module Haml
|
|
64
78
|
|
65
79
|
# The value of the character that designates that a line is part
|
66
80
|
# of a multiline string.
|
81
|
+
# @private
|
67
82
|
MULTILINE_CHAR_VALUE = ?|
|
68
83
|
|
69
84
|
# Regex to match keywords that appear in the middle of a Ruby block
|
@@ -79,12 +94,15 @@ module Haml
|
|
79
94
|
#
|
80
95
|
# The block is ended after `%p no!`, because `else`
|
81
96
|
# is a member of this array.
|
97
|
+
# @private
|
82
98
|
MID_BLOCK_KEYWORD_REGEX = /^-\s*(#{%w[else elsif rescue ensure when end].join('|')})\b/
|
83
99
|
|
84
100
|
# The Regex that matches a Doctype command.
|
101
|
+
# @private
|
85
102
|
DOCTYPE_REGEX = /(\d(?:\.\d)?)?[\s]*([a-z]*)/i
|
86
103
|
|
87
104
|
# The Regex that matches a literal string or symbol value
|
105
|
+
# @private
|
88
106
|
LITERAL_VALUE_REGEX = /:(\w*)|(["'])((?![\\#]|\2).|\\.)*\2/
|
89
107
|
|
90
108
|
private
|
@@ -124,6 +142,7 @@ END
|
|
124
142
|
end.join(';') + ';'
|
125
143
|
end
|
126
144
|
|
145
|
+
# @private
|
127
146
|
class Line < Struct.new(:text, :unstripped, :full, :index, :precompiler, :eod)
|
128
147
|
alias_method :eod?, :eod
|
129
148
|
|
@@ -654,7 +673,7 @@ END
|
|
654
673
|
return name, [:dynamic, var]
|
655
674
|
end
|
656
675
|
|
657
|
-
re = /((?:\\.|\#
|
676
|
+
re = /((?:\\.|\#(?!\{)|[^#{quote}\\#])*)(#{quote}|#\{)/
|
658
677
|
content = []
|
659
678
|
loop do
|
660
679
|
return false unless scanner.scan(re)
|
data/lib/haml/template.rb
CHANGED
@@ -28,7 +28,7 @@ module Haml
|
|
28
28
|
|
29
29
|
Haml::Precompiler.module_eval do
|
30
30
|
def precompiled_method_return_value_with_haml_xss
|
31
|
-
"(#{precompiled_method_return_value_without_haml_xss})
|
31
|
+
"::Haml::Util.html_safe(#{precompiled_method_return_value_without_haml_xss})"
|
32
32
|
end
|
33
33
|
alias_method :precompiled_method_return_value_without_haml_xss, :precompiled_method_return_value
|
34
34
|
alias_method :precompiled_method_return_value, :precompiled_method_return_value_with_haml_xss
|
@@ -39,7 +39,7 @@ module Haml
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
if
|
42
|
+
if Haml::Util.rails_env == "production"
|
43
43
|
Haml::Template.options[:ugly] = true
|
44
44
|
end
|
45
45
|
|
data/lib/haml/util.rb
CHANGED
@@ -146,6 +146,17 @@ module Haml
|
|
146
146
|
return nil
|
147
147
|
end
|
148
148
|
|
149
|
+
# Returns the environment of the Rails application,
|
150
|
+
# if this is running in a Rails context.
|
151
|
+
# Returns `nil` if no such environment is defined.
|
152
|
+
#
|
153
|
+
# @return [String, nil]
|
154
|
+
def rails_env
|
155
|
+
return Rails.env.to_s if defined?(Rails.root)
|
156
|
+
return RAILS_ENV.to_s if defined?(RAILS_ENV)
|
157
|
+
return nil
|
158
|
+
end
|
159
|
+
|
149
160
|
# Returns an ActionView::Template* class.
|
150
161
|
# In pre-3.0 versions of Rails, most of these classes
|
151
162
|
# were of the form `ActionView::TemplateFoo`,
|
@@ -170,6 +181,17 @@ module Haml
|
|
170
181
|
false
|
171
182
|
end
|
172
183
|
|
184
|
+
# Returns the given text, marked as being HTML-safe.
|
185
|
+
# With older versions of the Rails XSS-safety mechanism,
|
186
|
+
# this destructively modifies the HTML-safety of `text`.
|
187
|
+
#
|
188
|
+
# @param text [String]
|
189
|
+
# @return [String] `text`, marked as HTML-safe
|
190
|
+
def html_safe(text)
|
191
|
+
return text.html_safe if defined?(ActiveSupport::SafeBuffer)
|
192
|
+
text.html_safe!
|
193
|
+
end
|
194
|
+
|
173
195
|
# Assert that a given object (usually a String) is HTML safe
|
174
196
|
# according to Rails' XSS handling, if it's loaded.
|
175
197
|
#
|
@@ -179,6 +201,11 @@ module Haml
|
|
179
201
|
raise Haml::Error.new("Expected #{text.inspect} to be HTML-safe.")
|
180
202
|
end
|
181
203
|
|
204
|
+
def rails_safe_buffer_class
|
205
|
+
return ActionView::SafeBuffer if defined?(ActionView::SafeBuffer)
|
206
|
+
ActiveSupport::SafeBuffer
|
207
|
+
end
|
208
|
+
|
182
209
|
## Cross-Ruby-Version Compatibility
|
183
210
|
|
184
211
|
# Whether or not this is running under Ruby 1.8 or lower.
|
data/lib/sass/engine.rb
CHANGED
@@ -76,45 +76,57 @@ module Sass
|
|
76
76
|
end
|
77
77
|
|
78
78
|
# The character that begins a CSS property.
|
79
|
+
# @private
|
79
80
|
PROPERTY_CHAR = ?:
|
80
81
|
|
81
82
|
# The character that designates that
|
82
83
|
# a property should be assigned to a SassScript expression.
|
84
|
+
# @private
|
83
85
|
SCRIPT_CHAR = ?=
|
84
86
|
|
85
87
|
# The character that designates the beginning of a comment,
|
86
88
|
# either Sass or CSS.
|
89
|
+
# @private
|
87
90
|
COMMENT_CHAR = ?/
|
88
91
|
|
89
92
|
# The character that follows the general COMMENT_CHAR and designates a Sass comment,
|
90
93
|
# which is not output as a CSS comment.
|
94
|
+
# @private
|
91
95
|
SASS_COMMENT_CHAR = ?/
|
92
96
|
|
93
97
|
# The character that follows the general COMMENT_CHAR and designates a CSS comment,
|
94
98
|
# which is embedded in the CSS document.
|
99
|
+
# @private
|
95
100
|
CSS_COMMENT_CHAR = ?*
|
96
101
|
|
97
102
|
# The character used to denote a compiler directive.
|
103
|
+
# @private
|
98
104
|
DIRECTIVE_CHAR = ?@
|
99
105
|
|
100
106
|
# Designates a non-parsed rule.
|
107
|
+
# @private
|
101
108
|
ESCAPE_CHAR = ?\\
|
102
109
|
|
103
110
|
# Designates block as mixin definition rather than CSS rules to output
|
111
|
+
# @private
|
104
112
|
MIXIN_DEFINITION_CHAR = ?=
|
105
113
|
|
106
114
|
# Includes named mixin declared using MIXIN_DEFINITION_CHAR
|
115
|
+
# @private
|
107
116
|
MIXIN_INCLUDE_CHAR = ?+
|
108
117
|
|
109
118
|
# The regex that matches properties of the form `name: prop`.
|
119
|
+
# @private
|
110
120
|
PROPERTY_NEW_MATCHER = /^[^\s:"\[]+\s*[=:](\s|$)/
|
111
121
|
|
112
122
|
# The regex that matches and extracts data from
|
113
123
|
# properties of the form `name: prop`.
|
124
|
+
# @private
|
114
125
|
PROPERTY_NEW = /^([^\s=:"]+)(\s*=|:)(?:\s+|$)(.*)/
|
115
126
|
|
116
127
|
# The regex that matches and extracts data from
|
117
128
|
# properties of the form `:name prop`.
|
129
|
+
# @private
|
118
130
|
PROPERTY_OLD = /^:([^\s=:"]+)\s*(=?)(?:\s+|$)(.*)/
|
119
131
|
|
120
132
|
# The default options for Sass::Engine.
|
@@ -132,6 +144,10 @@ module Sass
|
|
132
144
|
@options = DEFAULT_OPTIONS.merge(options.reject {|k, v| v.nil?})
|
133
145
|
@template = template
|
134
146
|
|
147
|
+
# Support both, because the docs said one and the other actually worked
|
148
|
+
# for quite a long time.
|
149
|
+
@options[:line_comments] ||= @options[:line_numbers]
|
150
|
+
|
135
151
|
# Backwards compatibility
|
136
152
|
@options[:property_syntax] ||= @options[:attribute_syntax]
|
137
153
|
case @options[:property_syntax]
|
@@ -166,6 +182,7 @@ module Sass
|
|
166
182
|
|
167
183
|
def tabulate(string)
|
168
184
|
tab_str = nil
|
185
|
+
comment_tab_str = nil
|
169
186
|
first = true
|
170
187
|
lines = []
|
171
188
|
string.gsub(/\r|\n|\r\n|\r\n/, "\n").scan(/^.*?$/).each_with_index do |line, index|
|
@@ -177,6 +194,12 @@ module Sass
|
|
177
194
|
|
178
195
|
line_tab_str = line[/^\s*/]
|
179
196
|
unless line_tab_str.empty?
|
197
|
+
if tab_str.nil?
|
198
|
+
comment_tab_str ||= line_tab_str
|
199
|
+
next if try_comment(line, lines.last, "", comment_tab_str, index)
|
200
|
+
comment_tab_str = nil
|
201
|
+
end
|
202
|
+
|
180
203
|
tab_str ||= line_tab_str
|
181
204
|
|
182
205
|
raise SyntaxError.new("Indenting at the beginning of the document is illegal.", index) if first
|
@@ -190,9 +213,11 @@ module Sass
|
|
190
213
|
next
|
191
214
|
end
|
192
215
|
|
193
|
-
|
194
|
-
|
216
|
+
comment_tab_str ||= line_tab_str
|
217
|
+
if try_comment(line, lines.last, tab_str * (lines.last.tabs + 1), comment_tab_str, index)
|
195
218
|
next
|
219
|
+
else
|
220
|
+
comment_tab_str = nil
|
196
221
|
end
|
197
222
|
|
198
223
|
line_tabs = line_tab_str.scan(tab_str).size
|
@@ -205,6 +230,21 @@ END
|
|
205
230
|
lines
|
206
231
|
end
|
207
232
|
|
233
|
+
def try_comment(line, last, tab_str, comment_tab_str, index)
|
234
|
+
return unless last && last.comment?
|
235
|
+
return unless line =~ /^#{tab_str}/
|
236
|
+
unless line =~ /^(?:#{comment_tab_str})(.*)$/
|
237
|
+
raise SyntaxError.new(<<MSG.strip.gsub("\n", " "), index)
|
238
|
+
Inconsistent indentation:
|
239
|
+
previous line was indented by #{Haml::Shared.human_indentation comment_tab_str},
|
240
|
+
but this line was indented by #{Haml::Shared.human_indentation line[/^\s*/]}.
|
241
|
+
MSG
|
242
|
+
end
|
243
|
+
|
244
|
+
last.text << "\n" << $1
|
245
|
+
true
|
246
|
+
end
|
247
|
+
|
208
248
|
def tree(arr, i = 0)
|
209
249
|
return [], i if arr[i].nil?
|
210
250
|
|
data/lib/sass/plugin.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'sass'
|
2
|
+
require 'rbconfig'
|
2
3
|
|
3
4
|
module Sass
|
4
5
|
# This module handles the compilation of Sass files.
|
@@ -66,7 +67,7 @@ module Sass
|
|
66
67
|
#
|
67
68
|
# Checks each Sass file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
|
68
69
|
# to see if it's been modified more recently than the corresponding CSS file
|
69
|
-
# in {file:SASS_REFERENCE.md#css_location-option
|
70
|
+
# in {file:SASS_REFERENCE.md#css_location-option `:css_location`}.
|
70
71
|
# If it has, it updates the CSS file.
|
71
72
|
def update_stylesheets
|
72
73
|
return if options[:never_update]
|
@@ -103,9 +104,9 @@ module Sass
|
|
103
104
|
mkpath(css_location, name)
|
104
105
|
|
105
106
|
# Finally, write the file
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
flag = 'w'
|
108
|
+
flag = 'wb' if RbConfig::CONFIG['host_os'] =~ /mswin|windows/i && options[:unix_newlines]
|
109
|
+
File.open(css, flag) {|file| file.print(result)}
|
109
110
|
end
|
110
111
|
|
111
112
|
# Create any successive directories required to be able to write a file to: File.join(base,name)
|
data/lib/sass/plugin/rails.rb
CHANGED
@@ -4,8 +4,8 @@ unless defined?(Sass::RAILS_LOADED)
|
|
4
4
|
Sass::Plugin.options.merge!(:template_location => Haml::Util.rails_root + '/public/stylesheets/sass',
|
5
5
|
:css_location => Haml::Util.rails_root + '/public/stylesheets',
|
6
6
|
:cache_location => Haml::Util.rails_root + '/tmp/sass-cache',
|
7
|
-
:always_check =>
|
8
|
-
:full_exception =>
|
7
|
+
:always_check => Haml::Util.rails_env != "production",
|
8
|
+
:full_exception => Haml::Util.rails_env != "production")
|
9
9
|
|
10
10
|
if defined?(ActionDispatch::Callbacks.to_prepare)
|
11
11
|
# Rails >= 3.0.0
|
data/lib/sass/script.rb
CHANGED
@@ -13,12 +13,15 @@ module Sass
|
|
13
13
|
# This module contains code that handles the parsing and evaluation of SassScript.
|
14
14
|
module Script
|
15
15
|
# The character that begins a variable.
|
16
|
+
# @private
|
16
17
|
VARIABLE_CHAR = ?!
|
17
18
|
|
18
19
|
# The regular expression used to parse variables.
|
20
|
+
# @private
|
19
21
|
MATCH = /^!([a-zA-Z_]\w*)\s*((?:\|\|)?=)\s*(.+)/
|
20
22
|
|
21
23
|
# The regular expression used to validate variables without matching.
|
24
|
+
# @private
|
22
25
|
VALIDATE = /^![a-zA-Z_]\w*$/
|
23
26
|
|
24
27
|
# Parses and evaluates a string of SassScript.
|
data/lib/sass/script/color.rb
CHANGED
@@ -6,6 +6,7 @@ module Sass::Script
|
|
6
6
|
class << self; include Haml::Util; end
|
7
7
|
|
8
8
|
# A hash from color names to `[red, green, blue]` value arrays.
|
9
|
+
# @private
|
9
10
|
HTML4_COLORS = map_vals({
|
10
11
|
'black' => 0x000000,
|
11
12
|
'silver' => 0xc0c0c0,
|
@@ -25,6 +26,7 @@ module Sass::Script
|
|
25
26
|
'aqua' => 0x00ffff
|
26
27
|
}) {|color| (0..2).map {|n| color >> (n << 3) & 0xff}.reverse}
|
27
28
|
# A hash from `[red, green, blue]` value arrays to color names.
|
29
|
+
# @private
|
28
30
|
HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
|
29
31
|
|
30
32
|
# Creates a new color from RGB components.
|
@@ -41,13 +43,13 @@ module Sass::Script
|
|
41
43
|
super(rgb.freeze)
|
42
44
|
end
|
43
45
|
|
44
|
-
# @deprecated This will be removed in version 2.
|
46
|
+
# @deprecated This will be removed in version 3.2.
|
45
47
|
# @see #rgb
|
46
48
|
def value
|
47
49
|
warn <<END
|
48
50
|
DEPRECATION WARNING:
|
49
51
|
The Sass::Script::Color #value attribute is deprecated and will be
|
50
|
-
removed in version 2.
|
52
|
+
removed in version 3.2. Use the #rgb attribute instead.
|
51
53
|
END
|
52
54
|
rgb
|
53
55
|
end
|
data/lib/sass/script/lexer.rb
CHANGED
@@ -8,20 +8,21 @@ module Sass
|
|
8
8
|
class Lexer
|
9
9
|
# A struct containing information about an individual token.
|
10
10
|
#
|
11
|
-
# `type`: \[
|
11
|
+
# `type`: \[`Symbol`\]
|
12
12
|
# : The type of token.
|
13
13
|
#
|
14
|
-
# `value`: \[
|
14
|
+
# `value`: \[`Object`\]
|
15
15
|
# : The Ruby object corresponding to the value of the token.
|
16
16
|
#
|
17
|
-
# `line`: \[
|
17
|
+
# `line`: \[`Fixnum`\]
|
18
18
|
# : The line of the source file on which the token appears.
|
19
19
|
#
|
20
|
-
# `offset`: \[
|
20
|
+
# `offset`: \[`Fixnum`\]
|
21
21
|
# : The number of bytes into the line the SassScript token appeared.
|
22
22
|
Token = Struct.new(:type, :value, :line, :offset)
|
23
23
|
|
24
24
|
# A hash from operator strings to the corresponding token types.
|
25
|
+
# @private
|
25
26
|
OPERATORS = {
|
26
27
|
'+' => :plus,
|
27
28
|
'-' => :minus,
|
@@ -47,9 +48,11 @@ module Sass
|
|
47
48
|
|
48
49
|
# A list of operator strings ordered with longer names first
|
49
50
|
# so that `>` and `<` don't clobber `>=` and `<=`.
|
51
|
+
# @private
|
50
52
|
OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
|
51
53
|
|
52
54
|
# A hash of regular expressions that are used for tokenizing.
|
55
|
+
# @private
|
53
56
|
REGULAR_EXPRESSIONS = {
|
54
57
|
:whitespace => /\s*/,
|
55
58
|
:variable => /!(\w+)/,
|
@@ -167,7 +170,7 @@ module Sass
|
|
167
170
|
warn(<<END)
|
168
171
|
DEPRECATION WARNING:
|
169
172
|
On line #{@line}, character #{last_match_position}#{" of '#{@filename}'" if @filename}
|
170
|
-
- will be allowed as part of variable names in version
|
173
|
+
- will be allowed as part of variable names in version 3.0.
|
171
174
|
Please add whitespace to separate it from the previous token.
|
172
175
|
END
|
173
176
|
end
|
data/lib/sass/script/number.rb
CHANGED
@@ -351,7 +351,9 @@ module Sass::Script
|
|
351
351
|
end
|
352
352
|
|
353
353
|
# A hash of unit names to their index in the conversion table
|
354
|
+
# @private
|
354
355
|
CONVERTABLE_UNITS = {"in" => 0, "cm" => 1, "pc" => 2, "mm" => 3, "pt" => 4}
|
356
|
+
# @private
|
355
357
|
CONVERSION_TABLE = [[ 1, 2.54, 6, 25.4, 72 ], # in
|
356
358
|
[ nil, 1, 2.36220473, 10, 28.3464567], # cm
|
357
359
|
[ nil, nil, 1, 4.23333333, 12 ], # pc
|
data/lib/sass/script/parser.rb
CHANGED
@@ -141,7 +141,7 @@ RUBY
|
|
141
141
|
warn(<<END)
|
142
142
|
DEPRECATION WARNING:
|
143
143
|
On line #{name.line}, character #{name.offset}#{" of '#{@filename}'" if @filename}
|
144
|
-
Implicit strings have been deprecated and will be removed in version
|
144
|
+
Implicit strings have been deprecated and will be removed in version 3.0.
|
145
145
|
'#{name.value}' was not quoted. Please add double quotes (e.g. "#{name.value}").
|
146
146
|
END
|
147
147
|
Script::String.new(name.value)
|