haml 3.0.16 → 3.0.17
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/VERSION +1 -1
- data/lib/haml/engine.rb +1 -1
- data/lib/haml/exec.rb +13 -3
- data/lib/haml/util.rb +1 -1
- data/lib/sass/script/color.rb +1 -1
- data/lib/sass/script/lexer.rb +1 -1
- data/lib/sass/scss/css_parser.rb +9 -0
- data/lib/sass/scss/parser.rb +6 -8
- data/lib/sass/scss/static_parser.rb +1 -3
- data/lib/sass/tree/prop_node.rb +1 -1
- data/test/haml/engine_test.rb +3 -1
- data/test/sass/conversion_test.rb +1 -1
- data/test/sass/engine_test.rb +1 -1
- data/test/sass/script_test.rb +13 -13
- data/test/sass/scss/scss_test.rb +27 -7
- data/test/test_helper.rb +9 -0
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.
|
1
|
+
3.0.17
|
data/lib/haml/engine.rb
CHANGED
@@ -99,7 +99,7 @@ module Haml
|
|
99
99
|
@index = 0
|
100
100
|
|
101
101
|
unless [:xhtml, :html4, :html5].include?(@options[:format])
|
102
|
-
raise Haml::Error, "Invalid format #{@options[:format].inspect}"
|
102
|
+
raise Haml::Error, "Invalid output format #{@options[:format].inspect}"
|
103
103
|
end
|
104
104
|
|
105
105
|
if @options[:encoding] && @options[:encoding].is_a?(Encoding)
|
data/lib/haml/exec.rb
CHANGED
@@ -161,7 +161,7 @@ module Haml
|
|
161
161
|
raise err if @options[:trace] || dep.nil? || dep.empty?
|
162
162
|
$stderr.puts <<MESSAGE
|
163
163
|
Required dependency #{dep} not found!
|
164
|
-
|
164
|
+
Run "gem install #{dep}" to get it.
|
165
165
|
Use --trace for backtrace.
|
166
166
|
MESSAGE
|
167
167
|
exit 1
|
@@ -388,6 +388,12 @@ END
|
|
388
388
|
::Sass::Plugin.options.merge! @options[:for_engine]
|
389
389
|
::Sass::Plugin.options[:unix_newlines] = @options[:unix_newlines]
|
390
390
|
|
391
|
+
raise <<MSG if @args.empty?
|
392
|
+
What files should I watch? Did you mean something like:
|
393
|
+
sass --watch input.sass:output.css
|
394
|
+
sass --watch input-dir:output-dir
|
395
|
+
MSG
|
396
|
+
|
391
397
|
if !colon_path?(@args[0]) && probably_dest_dir?(@args[1])
|
392
398
|
flag = @options[:update] ? "--update" : "--watch"
|
393
399
|
err =
|
@@ -396,9 +402,9 @@ END
|
|
396
402
|
elsif @args[1] =~ /\.css$/
|
397
403
|
"is a CSS file"
|
398
404
|
end
|
399
|
-
|
405
|
+
raise <<MSG if err
|
400
406
|
File #{@args[1]} #{err}.
|
401
|
-
|
407
|
+
Did you mean: sass #{flag} #{@args[0]}:#{@args[1]}
|
402
408
|
MSG
|
403
409
|
end
|
404
410
|
|
@@ -416,15 +422,18 @@ MSG
|
|
416
422
|
end
|
417
423
|
end
|
418
424
|
|
425
|
+
had_error = false
|
419
426
|
::Sass::Plugin.on_creating_directory {|dirname| puts_action :directory, :green, dirname}
|
420
427
|
::Sass::Plugin.on_deleting_css {|filename| puts_action :delete, :yellow, filename}
|
421
428
|
::Sass::Plugin.on_compilation_error do |error, _, _|
|
422
429
|
raise error unless error.is_a?(::Sass::SyntaxError)
|
430
|
+
had_error = true
|
423
431
|
puts_action :error, :red, "#{error.sass_filename} (Line #{error.sass_line}: #{error.message})"
|
424
432
|
end
|
425
433
|
|
426
434
|
if @options[:update]
|
427
435
|
::Sass::Plugin.update_stylesheets(files)
|
436
|
+
exit 1 if had_error
|
428
437
|
return
|
429
438
|
end
|
430
439
|
|
@@ -456,6 +465,7 @@ MSG
|
|
456
465
|
# Whether path is likely to be meant as the destination
|
457
466
|
# in a source:dest pair.
|
458
467
|
def probably_dest_dir?(path)
|
468
|
+
return false unless path
|
459
469
|
return false if colon_path?(path)
|
460
470
|
return Dir.glob(File.join(path, "*.s[ca]ss")).empty?
|
461
471
|
end
|
data/lib/haml/util.rb
CHANGED
data/lib/sass/script/color.rb
CHANGED
data/lib/sass/script/lexer.rb
CHANGED
@@ -278,7 +278,7 @@ module Sass
|
|
278
278
|
|
279
279
|
def color
|
280
280
|
return unless s = scan(REGULAR_EXPRESSIONS[:color])
|
281
|
-
raise Sass::SyntaxError.new(<<MESSAGE) unless s.size == 4 || s.size == 7
|
281
|
+
raise Sass::SyntaxError.new(<<MESSAGE.rstrip) unless s.size == 4 || s.size == 7
|
282
282
|
Colors must have either three or six digits: '#{s}'
|
283
283
|
MESSAGE
|
284
284
|
value = s.scan(/^#(..?)(..?)(..?)$/).first.
|
data/lib/sass/scss/css_parser.rb
CHANGED
@@ -7,6 +7,15 @@ module Sass
|
|
7
7
|
# parent references, nested selectors, and so forth.
|
8
8
|
# It does support all the same CSS hacks as the SCSS parser, though.
|
9
9
|
class CssParser < StaticParser
|
10
|
+
# Parse a selector, and return its value as a string.
|
11
|
+
#
|
12
|
+
# @return [String, nil] The parsed selector, or nil if no selector was parsed
|
13
|
+
# @raise [Sass::SyntaxError] if there's a syntax error in the selector
|
14
|
+
def parse_selector_string
|
15
|
+
init_scanner!
|
16
|
+
str {return unless selector}
|
17
|
+
end
|
18
|
+
|
10
19
|
private
|
11
20
|
|
12
21
|
def parent_selector; nil; end
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -109,11 +109,10 @@ module Sass
|
|
109
109
|
return dir
|
110
110
|
end
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
end
|
112
|
+
# Most at-rules take expressions (e.g. @import),
|
113
|
+
# but some (e.g. @page) take selector-like arguments
|
114
|
+
val = str {break unless expr}
|
115
|
+
val ||= CssParser.new(@scanner, @line).parse_selector_string
|
117
116
|
node = node(Sass::Tree::DirectiveNode.new("@#{name} #{val}".strip))
|
118
117
|
|
119
118
|
if tok(/\{/)
|
@@ -644,11 +643,10 @@ MESSAGE
|
|
644
643
|
unless e = tok(NUMBER) ||
|
645
644
|
tok(URI) ||
|
646
645
|
function ||
|
647
|
-
|
646
|
+
tok(STRING) ||
|
648
647
|
tok(UNICODERANGE) ||
|
649
648
|
tok(IDENT) ||
|
650
|
-
tok(HEXCOLOR)
|
651
|
-
interpolation
|
649
|
+
tok(HEXCOLOR)
|
652
650
|
|
653
651
|
return unless op = unary_operator
|
654
652
|
@expected = "number or function"
|
@@ -8,11 +8,9 @@ module Sass
|
|
8
8
|
class StaticParser < Parser
|
9
9
|
# Parses the text as a selector.
|
10
10
|
#
|
11
|
-
# @param line [Fixnum] The line on which the selector appears.
|
12
|
-
# Used for error reporting
|
13
11
|
# @param filename [String, nil] The file in which the selector appears,
|
14
12
|
# or nil if there is no such file.
|
15
|
-
# Used for error reporting
|
13
|
+
# Used for error reporting.
|
16
14
|
# @return [Selector::CommaSequence] The parsed selector
|
17
15
|
# @raise [Sass::SyntaxError] if there's a syntax error in the selector
|
18
16
|
def parse_selector(filename)
|
data/lib/sass/tree/prop_node.rb
CHANGED
@@ -167,7 +167,7 @@ module Sass::Tree
|
|
167
167
|
def declaration(tabs = 0, opts = {:old => @prop_syntax == :old}, fmt = :sass)
|
168
168
|
name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass(opts)}}"}.join
|
169
169
|
if name[0] == ?:
|
170
|
-
raise Sass::SyntaxError.new("The \"
|
170
|
+
raise Sass::SyntaxError.new("The \"#{name}: #{self.class.val_to_sass(value, opts)}\" hack is not allowed in the Sass indented syntax")
|
171
171
|
end
|
172
172
|
|
173
173
|
old = opts[:old] && fmt == :sass
|
data/test/haml/engine_test.rb
CHANGED
@@ -1236,7 +1236,9 @@ SASS
|
|
1236
1236
|
end
|
1237
1237
|
|
1238
1238
|
def test_arbitrary_output_option
|
1239
|
-
|
1239
|
+
assert_raise_message(Haml::Error, "Invalid output format :html1") do
|
1240
|
+
engine("%br", :format => :html1)
|
1241
|
+
end
|
1240
1242
|
end
|
1241
1243
|
|
1242
1244
|
def test_static_hashes
|
@@ -1031,7 +1031,7 @@ SCSS
|
|
1031
1031
|
end
|
1032
1032
|
|
1033
1033
|
def test_disallowed_colon_hack
|
1034
|
-
|
1034
|
+
assert_raise_message(Sass::SyntaxError, 'The ":name: val" hack is not allowed in the Sass indented syntax') do
|
1035
1035
|
to_sass("foo {:name: val;}", :syntax => :scss)
|
1036
1036
|
end
|
1037
1037
|
end
|
data/test/sass/engine_test.rb
CHANGED
@@ -2057,7 +2057,7 @@ SASS
|
|
2057
2057
|
end
|
2058
2058
|
|
2059
2059
|
def test_mixin_no_arg_error
|
2060
|
-
|
2060
|
+
assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "($bar,": expected variable (e.g. $foo), was ")"') do
|
2061
2061
|
render(<<SASS)
|
2062
2062
|
=foo($bar,)
|
2063
2063
|
bip: bap
|
data/test/sass/script_test.rb
CHANGED
@@ -13,13 +13,13 @@ class SassScriptTest < Test::Unit::TestCase
|
|
13
13
|
include Sass::Script
|
14
14
|
|
15
15
|
def test_color_checks_input
|
16
|
-
|
17
|
-
|
16
|
+
assert_raise_message(Sass::SyntaxError, "Blue value must be between 0 and 255") {Color.new([1, 2, -1])}
|
17
|
+
assert_raise_message(Sass::SyntaxError, "Red value must be between 0 and 255") {Color.new([256, 2, 3])}
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_color_checks_rgba_input
|
21
|
-
|
22
|
-
|
21
|
+
assert_raise_message(Sass::SyntaxError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
|
22
|
+
assert_raise_message(Sass::SyntaxError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_string_escapes
|
@@ -63,13 +63,13 @@ class SassScriptTest < Test::Unit::TestCase
|
|
63
63
|
assert_equal "rgba(50, 50, 100, 0.35)", resolve("rgba(1, 1, 2, 0.35) * rgba(50, 50, 50, 0.35)")
|
64
64
|
assert_equal "rgba(52, 52, 52, 0.25)", resolve("rgba(2, 2, 2, 0.25) + rgba(50, 50, 50, 0.25)")
|
65
65
|
|
66
|
-
|
66
|
+
assert_raise_message(Sass::SyntaxError, "Alpha channels must be equal: rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)") do
|
67
67
|
resolve("rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)")
|
68
68
|
end
|
69
|
-
|
69
|
+
assert_raise_message(Sass::SyntaxError, "Alpha channels must be equal: #123456 * rgba(50, 50, 50, 0.75)") do
|
70
70
|
resolve("#123456 * rgba(50, 50, 50, 0.75)")
|
71
71
|
end
|
72
|
-
|
72
|
+
assert_raise_message(Sass::SyntaxError, "Alpha channels must be equal: rgba(50, 50, 50, 0.75) / #123456") do
|
73
73
|
resolve("rgba(50, 50, 50, 0.75) / #123456")
|
74
74
|
end
|
75
75
|
end
|
@@ -360,15 +360,15 @@ SASS
|
|
360
360
|
end
|
361
361
|
|
362
362
|
def test_colors_with_wrong_number_of_digits
|
363
|
-
|
363
|
+
assert_raise_message(Sass::SyntaxError,
|
364
364
|
"Colors must have either three or six digits: '#0'") {eval("#0")}
|
365
|
-
|
365
|
+
assert_raise_message(Sass::SyntaxError,
|
366
366
|
"Colors must have either three or six digits: '#12'") {eval("#12")}
|
367
|
-
|
367
|
+
assert_raise_message(Sass::SyntaxError,
|
368
368
|
"Colors must have either three or six digits: '#abcd'") {eval("#abcd")}
|
369
|
-
|
369
|
+
assert_raise_message(Sass::SyntaxError,
|
370
370
|
"Colors must have either three or six digits: '#abcdE'") {eval("#abcdE")}
|
371
|
-
|
371
|
+
assert_raise_message(Sass::SyntaxError,
|
372
372
|
"Colors must have either three or six digits: '#abcdEFA'") {eval("#abcdEFA")}
|
373
373
|
end
|
374
374
|
|
@@ -386,7 +386,7 @@ SASS
|
|
386
386
|
end
|
387
387
|
|
388
388
|
def test_misplaced_comma_in_funcall
|
389
|
-
|
389
|
+
assert_raise_message(Sass::SyntaxError,
|
390
390
|
'Invalid CSS after "foo(bar, ": expected function argument, was ")"') {eval('foo(bar, )')}
|
391
391
|
end
|
392
392
|
|
data/test/sass/scss/scss_test.rb
CHANGED
@@ -965,7 +965,7 @@ SCSS
|
|
965
965
|
end
|
966
966
|
|
967
967
|
def test_parent_in_mid_selector_error
|
968
|
-
|
968
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
|
969
969
|
Invalid CSS after ".foo": expected "{", was "&.bar"
|
970
970
|
|
971
971
|
In Sass 3, the parent selector & can only be used where element names are valid,
|
@@ -978,8 +978,8 @@ SCSS
|
|
978
978
|
end
|
979
979
|
|
980
980
|
def test_parent_in_mid_selector_error
|
981
|
-
|
982
|
-
Invalid CSS after ".foo.bar": expected "{", was "&"
|
981
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
|
982
|
+
Invalid CSS after " .foo.bar": expected "{", was "& {a: b}"
|
983
983
|
|
984
984
|
In Sass 3, the parent selector & can only be used where element names are valid,
|
985
985
|
since it could potentially be replaced by an element name.
|
@@ -991,8 +991,8 @@ SCSS
|
|
991
991
|
end
|
992
992
|
|
993
993
|
def test_double_parent_selector_error
|
994
|
-
|
995
|
-
Invalid CSS after "&": expected "{", was "&"
|
994
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
|
995
|
+
Invalid CSS after " &": expected "{", was "& {a: b}"
|
996
996
|
|
997
997
|
In Sass 3, the parent selector & can only be used where element names are valid,
|
998
998
|
since it could potentially be replaced by an element name.
|
@@ -1003,6 +1003,26 @@ flim {
|
|
1003
1003
|
SCSS
|
1004
1004
|
end
|
1005
1005
|
|
1006
|
+
def test_no_interpolation_in_media_queries
|
1007
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
1008
|
+
Invalid CSS after "...nd (min-width: ": expected expression (e.g. 1px, bold), was "\#{100}px) {"
|
1009
|
+
MESSAGE
|
1010
|
+
@media screen and (min-width: \#{100}px) {
|
1011
|
+
foo {bar: baz}
|
1012
|
+
}
|
1013
|
+
SCSS
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
def test_no_interpolation_in_unrecognized_directives
|
1017
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
1018
|
+
Invalid CSS after "@foo ": expected selector or at-rule, was "\#{100} {"
|
1019
|
+
MESSAGE
|
1020
|
+
@foo \#{100} {
|
1021
|
+
foo {bar: baz}
|
1022
|
+
}
|
1023
|
+
SCSS
|
1024
|
+
end
|
1025
|
+
|
1006
1026
|
# Regression
|
1007
1027
|
|
1008
1028
|
def test_weird_added_space
|
@@ -1029,8 +1049,8 @@ SCSS
|
|
1029
1049
|
end
|
1030
1050
|
|
1031
1051
|
def test_extra_comma_in_mixin_arglist_error
|
1032
|
-
|
1033
|
-
Invalid CSS after "
|
1052
|
+
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
1053
|
+
Invalid CSS after "...clude foo(bar, ": expected mixin argument, was ");"
|
1034
1054
|
MESSAGE
|
1035
1055
|
@mixin foo($a1, $a2) {
|
1036
1056
|
baz: $a1 $a2;
|
data/test/test_helper.rb
CHANGED
@@ -78,4 +78,13 @@ class Test::Unit::TestCase
|
|
78
78
|
return '' unless Haml::Util.ap_geq?("3.0.0.rc")
|
79
79
|
return '<div style="margin:0;padding:0;display:inline"><input name="_snowman" type="hidden" value="☃" /></div>'
|
80
80
|
end
|
81
|
+
|
82
|
+
def assert_raise_message(klass, message)
|
83
|
+
yield
|
84
|
+
rescue Exception => e
|
85
|
+
assert_instance_of(klass, e)
|
86
|
+
assert_equal(message, e.message)
|
87
|
+
else
|
88
|
+
flunk "Expected exception #{klass}, none raised"
|
89
|
+
end
|
81
90
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Weizenbaum
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2010-08-
|
14
|
+
date: 2010-08-14 00:00:00 -07:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|