haml-edge 2.3.80 → 2.3.81

Sign up to get free protection for your applications and to get access to all the features.
data/EDGE_GEM_VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.80
1
+ 2.3.81
data/README.md CHANGED
@@ -49,6 +49,16 @@ To do so, just add
49
49
  to `config/dependencies.rb` (or `config/init.rb` in a flat/very flat Merb application).
50
50
  Then it'll work just like it does in Rails.
51
51
 
52
+ Sass can also be used with any Rack-enabled web framework.
53
+ To do so, just add
54
+
55
+ require 'sass/plugin/rack'
56
+ use Sass::Plugin::Rack
57
+
58
+ to `config.ru`.
59
+ Then any Sass files in `public/stylesheets/sass`
60
+ will be compiled CSS files in `public/stylesheets` on every request.
61
+
52
62
  To use Haml and Sass programatically,
53
63
  check out the [YARD documentation](http://haml-lang.com/docs/yardoc).
54
64
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.80
1
+ 2.3.81
data/lib/haml/filters.rb CHANGED
@@ -200,6 +200,23 @@ END
200
200
  end
201
201
  end
202
202
 
203
+ # Surrounds the filtered text with `<style>` and CDATA tags.
204
+ # Useful for including inline CSS.
205
+ module Css
206
+ include Base
207
+
208
+ # @see Base#render_with_options
209
+ def render_with_options(text, options)
210
+ <<END
211
+ <style type=#{options[:attr_wrapper]}text/css#{options[:attr_wrapper]}>
212
+ /*<![CDATA[*/
213
+ #{text.rstrip.gsub("\n", "\n ")}
214
+ /*]]>*/
215
+ </style>
216
+ END
217
+ end
218
+ end
219
+
203
220
  # Surrounds the filtered text with CDATA tags.
204
221
  module Cdata
205
222
  include Base
data/lib/haml/html.rb CHANGED
@@ -227,7 +227,11 @@ module Haml
227
227
  if name == "script" &&
228
228
  (attr_hash['type'].nil? || attr_hash['type'] == "text/javascript") &&
229
229
  (attr_hash.keys - ['type']).empty?
230
- return script_to_haml(tabs, options)
230
+ return to_haml_filter(:javascript, tabs, options)
231
+ elsif name == "style" &&
232
+ (attr_hash['type'].nil? || attr_hash['type'] == "text/css") &&
233
+ (attr_hash.keys - ['type']).empty?
234
+ return to_haml_filter(:css, tabs, options)
231
235
  end
232
236
 
233
237
  output = tabulate(tabs)
@@ -333,7 +337,7 @@ module Haml
333
337
  end
334
338
  end
335
339
 
336
- def script_to_haml(tabs, options)
340
+ def to_haml_filter(filter, tabs, options)
337
341
  content =
338
342
  if children.first.is_a?(::Hpricot::CData)
339
343
  children.first.content
@@ -348,7 +352,7 @@ module Haml
348
352
  content.gsub!(/^#{original_indent}/, tabulate(tabs + 1))
349
353
  end
350
354
 
351
- "#{tabulate(tabs)}:javascript\n#{content}"
355
+ "#{tabulate(tabs)}:#{filter}\n#{content}"
352
356
  end
353
357
 
354
358
  def static_attribute?(name, options)
@@ -27,11 +27,7 @@ unless defined?(Sass::MERB_LOADED)
27
27
 
28
28
  class Merb::Rack::Application
29
29
  def call_with_sass(env)
30
- if !Sass::Plugin.checked_for_updates ||
31
- Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
32
- Sass::Plugin.update_stylesheets
33
- end
34
-
30
+ Sass::Plugin.check_for_updates
35
31
  call_without_sass(env)
36
32
  end
37
33
  alias_method :call_without_sass, :call
@@ -42,11 +38,7 @@ unless defined?(Sass::MERB_LOADED)
42
38
 
43
39
  class MerbHandler
44
40
  def process_with_sass(request, response)
45
- if !Sass::Plugin.checked_for_updates ||
46
- Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
47
- Sass::Plugin.update_stylesheets
48
- end
49
-
41
+ Sass::Plugin.check_for_updates
50
42
  process_without_sass(request, response)
51
43
  end
52
44
  alias_method :process_without_sass, :process
@@ -0,0 +1,65 @@
1
+ require 'sass/plugin'
2
+
3
+ module Sass
4
+ module Plugin
5
+ # Rack middleware for compiling Sass code.
6
+ #
7
+ # ## Activate
8
+ #
9
+ # require 'sass/plugin/rack'
10
+ # use Sass::Plugin::Rack
11
+ #
12
+ # ## Customize
13
+ #
14
+ # Sass::Plugin.options.merge(
15
+ # :cache_location => './tmp/sass-cache',
16
+ # :never_update => environment != :production,
17
+ # :full_exception => environment != :production)
18
+ #
19
+ # {file:SASS_REFERENCE.md#options See the Reference for more options}.
20
+ #
21
+ # ## Use
22
+ #
23
+ # Put your Sass files in `public/stylesheets/sass`.
24
+ # Your CSS will be generated in `public/stylesheets`,
25
+ # and regenerated every request if necessary.
26
+ # The locations and frequency {file:SASS_REFERENCE.md#options can be customized}.
27
+ # That's all there is to it!
28
+ class Rack
29
+ # Initialize the middleware.
30
+ #
31
+ # @param app [#call] The Rack application
32
+ def initialize(app)
33
+ @app = app
34
+ self.class.disable_native_plugin!
35
+ end
36
+
37
+ # Process a request, checking the Sass stylesheets for changes
38
+ # and updating them if necessary.
39
+ #
40
+ # @param env The Rack request environment
41
+ # @return [(#to_i, Hash<String, String>, Object)] The Rack response
42
+ def call(env)
43
+ Sass::Plugin.check_for_updates
44
+ @app.call(env)
45
+ end
46
+
47
+ # Disable the native Rails or Merb plugins, if they're enabled.
48
+ # This is automatically done once the Rack plugin is activated.
49
+ # This is done so that the stylesheets aren't checked twice for each request.
50
+ def self.disable_native_plugin!
51
+ if defined?(Merb::Rack::Application) &&
52
+ Haml::Util.has?(:instance_method, Merb::Rack::Application, :call_without_sass)
53
+ Merb::Rack::Application.instance_eval {alias_method :call, :call_without_sass}
54
+ end
55
+
56
+ if defined?(ActionDispatch::Callbacks.to_prepare)
57
+ ActionDispatch::Callbacks.instance_eval {undef :__sass_process}
58
+ elsif defined?(ActionController::Base) &&
59
+ Haml::Util.has?(:instance_method, ActionController::Base, :sass_old_process)
60
+ ActionController::Base.instance_eval {alias_method :process, :sass_old_process}
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -9,7 +9,7 @@ unless defined?(Sass::RAILS_LOADED)
9
9
 
10
10
  if defined?(ActionDispatch::Callbacks.to_prepare)
11
11
  # Rails >= 3.0.0
12
- ActionDispatch::Callbacks.to_prepare {Sass::Plugin.check_for_updates}
12
+ ActionDispatch::Callbacks.to_prepare(:sass_process) {Sass::Plugin.check_for_updates}
13
13
  else
14
14
  module ActionController
15
15
  class Base
data/lib/sass/plugin.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'sass/engine'
1
+ require 'sass'
2
2
 
3
3
  module Sass
4
4
  # This module handles the compilation of Sass files.
@@ -7,7 +7,9 @@ module Sass
7
7
  #
8
8
  # This module is used as the primary interface with Sass
9
9
  # when it's used as a plugin for various frameworks.
10
- # Currently Rails and Merb are supported out of the box.
10
+ # All Rack-enabled frameworks are supported out of the box.
11
+ # The plugin is {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
12
+ # Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
11
13
  module Plugin
12
14
  include Haml::Util
13
15
  extend self
@@ -27,13 +27,61 @@ module Sass::Script
27
27
  # A hash from [red, green, blue] value arrays to color names.
28
28
  HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
29
29
 
30
+ # The red component of the color.
31
+ #
32
+ # @return [Fixnum]
33
+ attr_reader :red
34
+
35
+ # The green component of the color.
36
+ #
37
+ # @return [Fixnum]
38
+ attr_reader :green
39
+
40
+ # The blue component of the color.
41
+ #
42
+ # @return [Fixnum]
43
+ attr_reader :blue
44
+
30
45
  # @param rgb [Array<Fixnum>] A three-element array of the red, green, and blue values (respectively)
31
46
  # of the color
32
47
  # @raise [Sass::SyntaxError] if any color value isn't between 0 and 255
33
48
  def initialize(rgb)
34
49
  rgb = rgb.map {|c| c.to_i}
35
50
  raise Sass::SyntaxError.new("Color values must be between 0 and 255") if rgb.any? {|c| c < 0 || c > 255}
36
- super(rgb)
51
+ @red = rgb[0]
52
+ @green = rgb[1]
53
+ @blue = rgb[2]
54
+ super(nil)
55
+ end
56
+
57
+ # @deprecated This will be removed in version 2.6.
58
+ # @see #rgb
59
+ def value
60
+ warn <<END
61
+ DEPRECATION WARNING:
62
+ The Sass::Script::Color #value attribute is deprecated and will be
63
+ removed in version 2.6. Use the #rgb attribute instead.
64
+ END
65
+ rgb
66
+ end
67
+
68
+ # Returns the red, green, and blue components of the color.
69
+ #
70
+ # @return [Array<Fixnum>] A three-element array of the red, green, and blue
71
+ # values (respectively) of the color
72
+ def rgb
73
+ [red, green, blue]
74
+ end
75
+
76
+ # The SassScript `==` operation.
77
+ # **Note that this returns a {Sass::Script::Bool} object,
78
+ # not a Ruby boolean**.
79
+ #
80
+ # @param other [Literal] The right-hand side of the operator
81
+ # @return [Bool] True if this literal is the same as the other,
82
+ # false otherwise
83
+ def eq(other)
84
+ Sass::Script::Bool.new(other.is_a?(Color) && rgb == other.rgb)
37
85
  end
38
86
 
39
87
  # The SassScript `+` operation.
@@ -157,8 +205,8 @@ module Sass::Script
157
205
  #
158
206
  # @return [String] The string representation
159
207
  def to_s
160
- return HTML4_COLORS_REVERSE[@value] if HTML4_COLORS_REVERSE[@value]
161
- red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') }
208
+ return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb]
209
+ red, green, blue = rgb.map { |num| num.to_s(16).rjust(2, '0') }
162
210
  "##{red}#{green}#{blue}"
163
211
  end
164
212
  alias_method :inspect, :to_s
@@ -167,17 +215,16 @@ module Sass::Script
167
215
 
168
216
  def piecewise(other, operation)
169
217
  other_num = other.is_a? Number
170
- other_val = other.value
171
218
  if other_num && !other.unitless?
172
219
  raise Sass::SyntaxError.new("Cannot add a number with units (#{other}) to a color (#{self}).")
173
220
  end
174
221
 
175
- rgb = []
222
+ result = []
176
223
  for i in (0...3)
177
- res = @value[i].send(operation, other_num ? other_val : other_val[i])
178
- rgb[i] = [ [res, 255].min, 0 ].max
224
+ res = rgb[i].send(operation, other_num ? other.value : other.rgb[i])
225
+ result[i] = [ [res, 255].min, 0 ].max
179
226
  end
180
- Color.new(rgb)
227
+ Color.new(result)
181
228
  end
182
229
  end
183
230
  end
@@ -42,7 +42,7 @@ module Sass
42
42
 
43
43
  return Functions::EvaluationContext.new(environment.options).send(name, *args)
44
44
  rescue ArgumentError => e
45
- raise e unless e.backtrace.first =~ /:in `(block in )?(#{name}|perform)'$/
45
+ raise e unless e.backtrace.any? {|t| t =~ /:in `(block in )?(#{name}|perform)'$/}
46
46
  raise Sass::SyntaxError.new("#{e.message} for `#{name}'")
47
47
  end
48
48
  end
@@ -26,10 +26,29 @@ module Sass::Script
26
26
  # \{#abs}
27
27
  # : Returns the absolute value of a number.
28
28
  #
29
- # You can add your own functions to this module,
30
- # but there are a few things to keep in mind.
29
+ # These functions are described in more detail below.
30
+ #
31
+ # ## Adding Custom Functions
32
+ #
33
+ # New Sass functions can be added by adding Ruby methods to this module.
34
+ # For example:
35
+ #
36
+ # module Sass::Script::Functions
37
+ # def reverse(string)
38
+ # assert_type string, :String
39
+ # Sass::Script::String.new(string.value.reverse)
40
+ # end
41
+ # end
42
+ #
43
+ # There are a few things to keep in mind when modifying this module.
31
44
  # First of all, the arguments passed are {Sass::Script::Literal} objects.
32
45
  # Literal objects are also expected to be returned.
46
+ # This means that Ruby values must be unwrapped and wrapped.
47
+ #
48
+ # Most Literal objects support the {Sass::Script::Literal#value value} accessor
49
+ # for getting their Ruby values.
50
+ # Color objects, though, must be accessed using {Sass::Script::Color#rgb rgb},
51
+ # {Sass::Script::Color#red red}, {Sass::Script::Color#blue green}, or {Sass::Script::Color#blue blue}.
33
52
  #
34
53
  # Second, making Ruby functions accessible from Sass introduces the temptation
35
54
  # to do things like database access within stylesheets.
@@ -57,6 +76,22 @@ module Sass::Script
57
76
  def initialize(options)
58
77
  @options = options
59
78
  end
79
+
80
+ # Asserts that the type of a given SassScript value
81
+ # is the expected type (designated by a symbol).
82
+ # For example:
83
+ #
84
+ # assert_type value, :String
85
+ # assert_type value, :Number
86
+ #
87
+ # Valid types are `:Bool`, `:Color`, `:Number`, and `:String`.
88
+ #
89
+ # @param value [Sass::Script::Literal] A SassScript value
90
+ # @param type [Symbol] The name of the type the value is expected to be
91
+ def assert_type(value, type)
92
+ return if value.is_a?(Sass::Script.const_get(type))
93
+ raise ArgumentError.new("#{value.inspect} is not a #{type.to_s.downcase}")
94
+ end
60
95
  end
61
96
 
62
97
  instance_methods.each { |m| undef_method m unless m.to_s =~ /^__/ }
@@ -70,6 +105,10 @@ module Sass::Script
70
105
  # @param blue
71
106
  # A number between 0 and 255 inclusive
72
107
  def rgb(red, green, blue)
108
+ assert_type red, :Number
109
+ assert_type green, :Number
110
+ assert_type blue, :Number
111
+
73
112
  [red.value, green.value, blue.value].each do |v|
74
113
  next unless v < 0 || v > 255
75
114
  raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
@@ -78,7 +117,7 @@ module Sass::Script
78
117
  end
79
118
 
80
119
  # Creates a {Color} object from hue, saturation, and lightness
81
- # as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color).
120
+ # as per the [CSS3 spec](http://www.w3.org/TR/css3-color/#hsl-color).
82
121
  #
83
122
  # @param hue [Number] The hue of the color.
84
123
  # Should be between 0 and 360 degrees, inclusive
@@ -89,6 +128,10 @@ module Sass::Script
89
128
  # @return [Color] The resulting color
90
129
  # @raise [ArgumentError] if `saturation` or `lightness` are out of bounds
91
130
  def hsl(hue, saturation, lightness)
131
+ assert_type hue, :Number
132
+ assert_type saturation, :Number
133
+ assert_type lightness, :Number
134
+
92
135
  original_s = saturation
93
136
  original_l = lightness
94
137
  # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
@@ -107,6 +150,36 @@ module Sass::Script
107
150
  hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round })
108
151
  end
109
152
 
153
+ # Returns the red component of a color.
154
+ #
155
+ # @param color [Color]
156
+ # @return [Number]
157
+ # @raise [ArgumentError] If `color` isn't a color
158
+ def red(color)
159
+ assert_type color, :Color
160
+ Sass::Script::Number.new(color.red)
161
+ end
162
+
163
+ # Returns the green component of a color.
164
+ #
165
+ # @param color [Color]
166
+ # @return [Number]
167
+ # @raise [ArgumentError] If `color` isn't a color
168
+ def green(color)
169
+ assert_type color, :Color
170
+ Sass::Script::Number.new(color.green)
171
+ end
172
+
173
+ # Returns the blue component of a color.
174
+ #
175
+ # @param color [Color]
176
+ # @return [Number]
177
+ # @raise [ArgumentError] If `color` isn't a color
178
+ def blue(color)
179
+ assert_type color, :Color
180
+ Sass::Script::Number.new(color.blue)
181
+ end
182
+
110
183
  # Converts a decimal number to a percentage.
111
184
  # For example:
112
185
  #
@@ -117,7 +190,7 @@ module Sass::Script
117
190
  # @raise [ArgumentError] If `value` isn't a unitless number
118
191
  def percentage(value)
119
192
  unless value.is_a?(Sass::Script::Number) && value.unitless?
120
- raise ArgumentError.new("#{value} is not a unitless number")
193
+ raise ArgumentError.new("#{value.inspect} is not a unitless number")
121
194
  end
122
195
  Sass::Script::Number.new(value.value * 100, ['%'])
123
196
  end
@@ -180,10 +253,7 @@ module Sass::Script
180
253
  # another numeric value with the same units.
181
254
  # It yields a number to a block to perform the operation and return a number
182
255
  def numeric_transformation(value)
183
- unless value.is_a?(Sass::Script::Number)
184
- calling_function = Haml::Util.caller_info[2]
185
- raise Sass::SyntaxError.new("#{value} is not a number for `#{calling_function}'")
186
- end
256
+ assert_type value, :Number
187
257
  Sass::Script::Number.new(yield(value.value), value.numerator_units, value.denominator_units)
188
258
  end
189
259
 
@@ -52,11 +52,11 @@ module Sass
52
52
  # A hash of regular expressions that are used for tokenizing.
53
53
  REGULAR_EXPRESSIONS = {
54
54
  :whitespace => /\s*/,
55
- :variable => /!(\w+)/,
56
- :ident => /(\\.|\#\{|[^\s\\+\-*\/%(),=!])+/,
55
+ :variable => /!([\w-]+)/,
56
+ :ident => /(\\.|\#\{|[^\s\\+*\/%(),=!])+/,
57
57
  :string_end => /((?:\\.|\#[^{]|[^"\\#])*)(?:"|(?=#\{))/,
58
58
  :number => /(-)?(?:(\d*\.\d+)|(\d+))([a-zA-Z%]+)?/,
59
- :color => /\##{"([0-9a-fA-F]{1,2})" * 3}|(#{Color::HTML4_COLORS.keys.join("|")})/,
59
+ :color => /\##{"([0-9a-fA-F]{1,2})" * 3}|(#{Color::HTML4_COLORS.keys.join("|")})(?!\()/,
60
60
  :bool => /(true|false)\b/,
61
61
  :op => %r{(#{Regexp.union(*OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + (s =~ /\w$/ ? '(?:\b|$)' : ''))})})}
62
62
  }
@@ -162,16 +162,6 @@ module Sass
162
162
  def op
163
163
  prev_chr = @scanner.string[@scanner.pos - 1].chr
164
164
  return unless op = @scanner.scan(REGULAR_EXPRESSIONS[:op])
165
- if @prev && op == '-' && prev_chr !~ /\s/ &&
166
- [:bool, :ident, :const].include?(@prev.type)
167
- warn(<<END)
168
- DEPRECATION WARNING:
169
- On line #{@line}, character #{last_match_position}#{" of '#{@filename}'" if @filename}
170
- - will be allowed as part of variable names in version 2.4.
171
- Please add whitespace to separate it from the previous token.
172
- END
173
- end
174
-
175
165
  [OPERATORS[op]]
176
166
  end
177
167
 
@@ -909,6 +909,21 @@ END
909
909
  END
910
910
  end
911
911
 
912
+ def test_css_filter
913
+ assert_equal(<<CSS, render(<<SASS))
914
+ <style type='text/css'>
915
+ /*<![CDATA[*/
916
+ #foo {
917
+ bar: baz; }
918
+ /*]]>*/
919
+ </style>
920
+ CSS
921
+ :css
922
+ #foo {
923
+ bar: baz; }
924
+ SASS
925
+ end
926
+
912
927
  def test_local_assigns_dont_modify_class
913
928
  assert_equal("bar\n", render("= foo", :locals => {:foo => 'bar'}))
914
929
  assert_equal(nil, defined?(foo))
@@ -59,6 +59,21 @@ HAML
59
59
  HTML
60
60
  end
61
61
 
62
+ def test_erb_in_style
63
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
64
+ :css
65
+ foo {
66
+ bar: \#{"baz"};
67
+ }
68
+ HAML
69
+ <style type="text/css">
70
+ foo {
71
+ bar: <%= "baz" %>;
72
+ }
73
+ </style>
74
+ HTML
75
+ end
76
+
62
77
  def test_erb_in_line
63
78
  assert_equal 'foo bar #{baz}', render_erb('foo bar <%= baz %>')
64
79
  assert_equal 'foo bar #{baz}! Bang.', render_erb('foo bar <%= baz %>! Bang.')
@@ -198,6 +198,21 @@ HAML
198
198
  HTML
199
199
  end
200
200
 
201
+ def test_style_to_css_filter
202
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
203
+ :css
204
+ foo {
205
+ bar: baz;
206
+ }
207
+ HAML
208
+ <style type="text/css">
209
+ foo {
210
+ bar: baz;
211
+ }
212
+ </style>
213
+ HTML
214
+ end
215
+
201
216
  def test_inline_conditional_comment
202
217
  assert_equal(<<HAML.rstrip, render(<<HTML))
203
218
  /[if foo] bar baz
@@ -0,0 +1,319 @@
1
+ hsl(0, 100%, 50%)
2
+ hsl(60, 100%, 50%)
3
+ hsl(120, 100%, 50%)
4
+ hsl(180, 100%, 50%)
5
+ hsl(240, 100%, 50%)
6
+ hsl(300, 100%, 50%)
7
+ ====
8
+ rgb(255, 0, 0)
9
+ rgb(255, 255, 0)
10
+ rgb(0, 255, 0)
11
+ rgb(0, 255, 255)
12
+ rgb(0, 0, 255)
13
+ rgb(255, 0, 255)
14
+
15
+ hsl(-360, 100%, 50%)
16
+ hsl(-300, 100%, 50%)
17
+ hsl(-240, 100%, 50%)
18
+ hsl(-180, 100%, 50%)
19
+ hsl(-120, 100%, 50%)
20
+ hsl(-60, 100%, 50%)
21
+ ====
22
+ rgb(255, 0, 0)
23
+ rgb(255, 255, 0)
24
+ rgb(0, 255, 0)
25
+ rgb(0, 255, 255)
26
+ rgb(0, 0, 255)
27
+ rgb(255, 0, 255)
28
+
29
+ hsl(360, 100%, 50%)
30
+ hsl(420, 100%, 50%)
31
+ hsl(480, 100%, 50%)
32
+ hsl(540, 100%, 50%)
33
+ hsl(600, 100%, 50%)
34
+ hsl(660, 100%, 50%)
35
+ ====
36
+ rgb(255, 0, 0)
37
+ rgb(255, 255, 0)
38
+ rgb(0, 255, 0)
39
+ rgb(0, 255, 255)
40
+ rgb(0, 0, 255)
41
+ rgb(255, 0, 255)
42
+
43
+ hsl(6120, 100%, 50%)
44
+ hsl(-9660, 100%, 50%)
45
+ hsl(99840, 100%, 50%)
46
+ hsl(-900, 100%, 50%)
47
+ hsl(-104880, 100%, 50%)
48
+ hsl(2820, 100%, 50%)
49
+ ====
50
+ rgb(255, 0, 0)
51
+ rgb(255, 255, 0)
52
+ rgb(0, 255, 0)
53
+ rgb(0, 255, 255)
54
+ rgb(0, 0, 255)
55
+ rgb(255, 0, 255)
56
+
57
+ hsl(0, 100%, 50%)
58
+ hsl(12, 100%, 50%)
59
+ hsl(24, 100%, 50%)
60
+ hsl(36, 100%, 50%)
61
+ hsl(48, 100%, 50%)
62
+ hsl(60, 100%, 50%)
63
+ hsl(72, 100%, 50%)
64
+ hsl(84, 100%, 50%)
65
+ hsl(96, 100%, 50%)
66
+ hsl(108, 100%, 50%)
67
+ hsl(120, 100%, 50%)
68
+ ====
69
+ rgb(255, 0, 0)
70
+ rgb(255, 51, 0)
71
+ rgb(255, 102, 0)
72
+ rgb(255, 153, 0)
73
+ rgb(255, 204, 0)
74
+ rgb(255, 255, 0)
75
+ rgb(204, 255, 0)
76
+ rgb(153, 255, 0)
77
+ rgb(102, 255, 0)
78
+ rgb(51, 255, 0)
79
+ rgb(0, 255, 0)
80
+
81
+ hsl(120, 100%, 50%)
82
+ hsl(132, 100%, 50%)
83
+ hsl(144, 100%, 50%)
84
+ hsl(156, 100%, 50%)
85
+ hsl(168, 100%, 50%)
86
+ hsl(180, 100%, 50%)
87
+ hsl(192, 100%, 50%)
88
+ hsl(204, 100%, 50%)
89
+ hsl(216, 100%, 50%)
90
+ hsl(228, 100%, 50%)
91
+ hsl(240, 100%, 50%)
92
+ ====
93
+ rgb(0, 255, 0)
94
+ rgb(0, 255, 51)
95
+ rgb(0, 255, 102)
96
+ rgb(0, 255, 153)
97
+ rgb(0, 255, 204)
98
+ rgb(0, 255, 255)
99
+ rgb(0, 204, 255)
100
+ rgb(0, 153, 255)
101
+ rgb(0, 102, 255)
102
+ rgb(0, 51, 255)
103
+ rgb(0, 0, 255)
104
+
105
+ hsl(240, 100%, 50%)
106
+ hsl(252, 100%, 50%)
107
+ hsl(264, 100%, 50%)
108
+ hsl(276, 100%, 50%)
109
+ hsl(288, 100%, 50%)
110
+ hsl(300, 100%, 50%)
111
+ hsl(312, 100%, 50%)
112
+ hsl(324, 100%, 50%)
113
+ hsl(336, 100%, 50%)
114
+ hsl(348, 100%, 50%)
115
+ hsl(360, 100%, 50%)
116
+ ====
117
+ rgb(0, 0, 255)
118
+ rgb(51, 0, 255)
119
+ rgb(102, 0, 255)
120
+ rgb(153, 0, 255)
121
+ rgb(204, 0, 255)
122
+ rgb(255, 0, 255)
123
+ rgb(255, 0, 204)
124
+ rgb(255, 0, 153)
125
+ rgb(255, 0, 102)
126
+ rgb(255, 0, 51)
127
+ rgb(255, 0, 0)
128
+
129
+ hsl(0, 20%, 50%)
130
+ hsl(0, 60%, 50%)
131
+ hsl(0, 100%, 50%)
132
+ ====
133
+ rgb(153, 102, 102)
134
+ rgb(204, 51, 51)
135
+ rgb(255, 0, 0)
136
+
137
+ hsl(60, 20%, 50%)
138
+ hsl(60, 60%, 50%)
139
+ hsl(60, 100%, 50%)
140
+ ====
141
+ rgb(153, 153, 102)
142
+ rgb(204, 204, 51)
143
+ rgb(255, 255, 0)
144
+
145
+ hsl(120, 20%, 50%)
146
+ hsl(120, 60%, 50%)
147
+ hsl(120, 100%, 50%)
148
+ ====
149
+ rgb(102, 153, 102)
150
+ rgb(51, 204, 51)
151
+ rgb(0, 255, 0)
152
+
153
+ hsl(180, 20%, 50%)
154
+ hsl(180, 60%, 50%)
155
+ hsl(180, 100%, 50%)
156
+ ====
157
+ rgb(102, 153, 153)
158
+ rgb(51, 204, 204)
159
+ rgb(0, 255, 255)
160
+
161
+ hsl(240, 20%, 50%)
162
+ hsl(240, 60%, 50%)
163
+ hsl(240, 100%, 50%)
164
+ ====
165
+ rgb(102, 102, 153)
166
+ rgb(51, 51, 204)
167
+ rgb(0, 0, 255)
168
+
169
+ hsl(300, 20%, 50%)
170
+ hsl(300, 60%, 50%)
171
+ hsl(300, 100%, 50%)
172
+ ====
173
+ rgb(153, 102, 153)
174
+ rgb(204, 51, 204)
175
+ rgb(255, 0, 255)
176
+
177
+ hsl(0, 100%, 0%)
178
+ hsl(0, 100%, 10%)
179
+ hsl(0, 100%, 20%)
180
+ hsl(0, 100%, 30%)
181
+ hsl(0, 100%, 40%)
182
+ hsl(0, 100%, 50%)
183
+ hsl(0, 100%, 60%)
184
+ hsl(0, 100%, 70%)
185
+ hsl(0, 100%, 80%)
186
+ hsl(0, 100%, 90%)
187
+ hsl(0, 100%, 100%)
188
+ ====
189
+ rgb(0, 0, 0)
190
+ rgb(51, 0, 0)
191
+ rgb(102, 0, 0)
192
+ rgb(153, 0, 0)
193
+ rgb(204, 0, 0)
194
+ rgb(255, 0, 0)
195
+ rgb(255, 51, 51)
196
+ rgb(255, 102, 102)
197
+ rgb(255, 153, 153)
198
+ rgb(255, 204, 204)
199
+ rgb(255, 255, 255)
200
+
201
+ hsl(60, 100%, 0%)
202
+ hsl(60, 100%, 10%)
203
+ hsl(60, 100%, 20%)
204
+ hsl(60, 100%, 30%)
205
+ hsl(60, 100%, 40%)
206
+ hsl(60, 100%, 50%)
207
+ hsl(60, 100%, 60%)
208
+ hsl(60, 100%, 70%)
209
+ hsl(60, 100%, 80%)
210
+ hsl(60, 100%, 90%)
211
+ hsl(60, 100%, 100%)
212
+ ====
213
+ rgb(0, 0, 0)
214
+ rgb(51, 51, 0)
215
+ rgb(102, 102, 0)
216
+ rgb(153, 153, 0)
217
+ rgb(204, 204, 0)
218
+ rgb(255, 255, 0)
219
+ rgb(255, 255, 51)
220
+ rgb(255, 255, 102)
221
+ rgb(255, 255, 153)
222
+ rgb(255, 255, 204)
223
+ rgb(255, 255, 255)
224
+
225
+ hsl(120, 100%, 0%)
226
+ hsl(120, 100%, 10%)
227
+ hsl(120, 100%, 20%)
228
+ hsl(120, 100%, 30%)
229
+ hsl(120, 100%, 40%)
230
+ hsl(120, 100%, 50%)
231
+ hsl(120, 100%, 60%)
232
+ hsl(120, 100%, 70%)
233
+ hsl(120, 100%, 80%)
234
+ hsl(120, 100%, 90%)
235
+ hsl(120, 100%, 100%)
236
+ ====
237
+ rgb(0, 0, 0)
238
+ rgb(0, 51, 0)
239
+ rgb(0, 102, 0)
240
+ rgb(0, 153, 0)
241
+ rgb(0, 204, 0)
242
+ rgb(0, 255, 0)
243
+ rgb(51, 255, 51)
244
+ rgb(102, 255, 102)
245
+ rgb(153, 255, 153)
246
+ rgb(204, 255, 204)
247
+ rgb(255, 255, 255)
248
+
249
+ hsl(180, 100%, 0%)
250
+ hsl(180, 100%, 10%)
251
+ hsl(180, 100%, 20%)
252
+ hsl(180, 100%, 30%)
253
+ hsl(180, 100%, 40%)
254
+ hsl(180, 100%, 50%)
255
+ hsl(180, 100%, 60%)
256
+ hsl(180, 100%, 70%)
257
+ hsl(180, 100%, 80%)
258
+ hsl(180, 100%, 90%)
259
+ hsl(180, 100%, 100%)
260
+ ====
261
+ rgb(0, 0, 0)
262
+ rgb(0, 51, 51)
263
+ rgb(0, 102, 102)
264
+ rgb(0, 153, 153)
265
+ rgb(0, 204, 204)
266
+ rgb(0, 255, 255)
267
+ rgb(51, 255, 255)
268
+ rgb(102, 255, 255)
269
+ rgb(153, 255, 255)
270
+ rgb(204, 255, 255)
271
+ rgb(255, 255, 255)
272
+
273
+ hsl(240, 100%, 0%)
274
+ hsl(240, 100%, 10%)
275
+ hsl(240, 100%, 20%)
276
+ hsl(240, 100%, 30%)
277
+ hsl(240, 100%, 40%)
278
+ hsl(240, 100%, 50%)
279
+ hsl(240, 100%, 60%)
280
+ hsl(240, 100%, 70%)
281
+ hsl(240, 100%, 80%)
282
+ hsl(240, 100%, 90%)
283
+ hsl(240, 100%, 100%)
284
+ ====
285
+ rgb(0, 0, 0)
286
+ rgb(0, 0, 51)
287
+ rgb(0, 0, 102)
288
+ rgb(0, 0, 153)
289
+ rgb(0, 0, 204)
290
+ rgb(0, 0, 255)
291
+ rgb(51, 51, 255)
292
+ rgb(102, 102, 255)
293
+ rgb(153, 153, 255)
294
+ rgb(204, 204, 255)
295
+ rgb(255, 255, 255)
296
+
297
+ hsl(300, 100%, 0%)
298
+ hsl(300, 100%, 10%)
299
+ hsl(300, 100%, 20%)
300
+ hsl(300, 100%, 30%)
301
+ hsl(300, 100%, 40%)
302
+ hsl(300, 100%, 50%)
303
+ hsl(300, 100%, 60%)
304
+ hsl(300, 100%, 70%)
305
+ hsl(300, 100%, 80%)
306
+ hsl(300, 100%, 90%)
307
+ hsl(300, 100%, 100%)
308
+ ====
309
+ rgb(0, 0, 0)
310
+ rgb(51, 0, 51)
311
+ rgb(102, 0, 102)
312
+ rgb(153, 0, 153)
313
+ rgb(204, 0, 204)
314
+ rgb(255, 0, 255)
315
+ rgb(255, 51, 255)
316
+ rgb(255, 102, 255)
317
+ rgb(255, 153, 255)
318
+ rgb(255, 204, 255)
319
+ rgb(255, 255, 255)
@@ -3,44 +3,17 @@ require File.dirname(__FILE__) + '/../../lib/sass'
3
3
  require 'sass/script'
4
4
 
5
5
  class SassFunctionTest < Test::Unit::TestCase
6
- def test_hsl
7
- # These tests adapted from the w3c browser tests
8
- # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm
9
- red = [255, 0, 0]
10
- assert_rgb_hsl(red, ['0', '100%', '50%'])
11
- assert_rgb_hsl(red, ['-360', '100%', '50%'])
12
- assert_rgb_hsl(red, ['360', '100%', '50%'])
13
- assert_rgb_hsl(red, ['6120', '100%', '50%'])
14
-
15
- yellow = [255, 255, 0]
16
- assert_rgb_hsl(yellow, ['60', '100%', '50%'])
17
- assert_rgb_hsl(yellow, ['-300', '100%', '50%'])
18
- assert_rgb_hsl(yellow, ['420', '100%', '50%'])
19
- assert_rgb_hsl(yellow, ['-9660', '100%', '50%'])
20
-
21
- green = [0, 255, 0]
22
- assert_rgb_hsl(green, ['120', '100%', '50%'])
23
- assert_rgb_hsl(green, ['-240', '100%', '50%'])
24
- assert_rgb_hsl(green, ['480', '100%', '50%'])
25
- assert_rgb_hsl(green, ['99840', '100%', '50%'])
26
-
27
- cyan = [0, 255, 255]
28
- assert_rgb_hsl(cyan, ['180', '100%', '50%'])
29
- assert_rgb_hsl(cyan, ['-180', '100%', '50%'])
30
- assert_rgb_hsl(cyan, ['540', '100%', '50%'])
31
- assert_rgb_hsl(cyan, ['-900', '100%', '50%'])
32
-
33
- blue = [0, 0, 255]
34
- assert_rgb_hsl(blue, ['240', '100%', '50%'])
35
- assert_rgb_hsl(blue, ['-120', '100%', '50%'])
36
- assert_rgb_hsl(blue, ['600', '100%', '50%'])
37
- assert_rgb_hsl(blue, ['-104880', '100%', '50%'])
38
-
39
- purple = [255, 0, 255]
40
- assert_rgb_hsl(purple, ['300', '100%', '50%'])
41
- assert_rgb_hsl(purple, ['-60', '100%', '50%'])
42
- assert_rgb_hsl(purple, ['660', '100%', '50%'])
43
- assert_rgb_hsl(purple, ['2820', '100%', '50%'])
6
+ # Tests taken from:
7
+ # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm
8
+ # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-values-b.htm
9
+ File.read(File.dirname(__FILE__) + "/data/hsl-rgb.txt").split("\n\n").each do |chunk|
10
+ hsls, rgbs = chunk.strip.split("====")
11
+ hsls.strip.split("\n").zip(rgbs.strip.split("\n")) do |hsl, rgb|
12
+ method = "test_hsl: #{hsl} = #{rgb}"
13
+ define_method(method) do
14
+ assert_equal(evaluate(rgb), evaluate(hsl))
15
+ end
16
+ end
44
17
  end
45
18
 
46
19
  def test_hsl_checks_bounds
@@ -48,13 +21,22 @@ class SassFunctionTest < Test::Unit::TestCase
48
21
  assert_error_message("Lightness 256 must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)");
49
22
  end
50
23
 
24
+ def test_hsl_checks_types
25
+ assert_error_message("\"foo\" is not a number for `hsl'", "hsl(\"foo\", 10, 12)");
26
+ assert_error_message("\"foo\" is not a number for `hsl'", "hsl(10, \"foo\", 12)");
27
+ assert_error_message("\"foo\" is not a number for `hsl'", "hsl(10, 10, \"foo\")");
28
+ end
29
+
51
30
  def test_percentage
52
31
  assert_equal("50%", evaluate("percentage(.5)"))
53
32
  assert_equal("100%", evaluate("percentage(1)"))
54
33
  assert_equal("25%", evaluate("percentage(25px / 100px)"))
34
+ end
35
+
36
+ def test_percentage_checks_types
55
37
  assert_error_message("25px is not a unitless number for `percentage'", "percentage(25px)")
56
38
  assert_error_message("#cccccc is not a unitless number for `percentage'", "percentage(#ccc)")
57
- assert_error_message("string is not a unitless number for `percentage'", %Q{percentage("string")})
39
+ assert_error_message("\"string\" is not a unitless number for `percentage'", %Q{percentage("string")})
58
40
  end
59
41
 
60
42
  def test_round
@@ -69,14 +51,14 @@ class SassFunctionTest < Test::Unit::TestCase
69
51
  assert_equal("4", evaluate("floor(4.8)"))
70
52
  assert_equal("4px", evaluate("floor(4.8px)"))
71
53
 
72
- assert_error_message("foo is not a number for `floor'", "floor(\"foo\")")
54
+ assert_error_message("\"foo\" is not a number for `floor'", "floor(\"foo\")")
73
55
  end
74
56
 
75
57
  def test_ceil
76
58
  assert_equal("5", evaluate("ceil(4.1)"))
77
59
  assert_equal("5px", evaluate("ceil(4.8px)"))
78
60
 
79
- assert_error_message("a is not a number for `ceil'", "ceil(\"a\")")
61
+ assert_error_message("\"a\" is not a number for `ceil'", "ceil(\"a\")")
80
62
  end
81
63
 
82
64
  def test_abs
@@ -92,7 +74,9 @@ class SassFunctionTest < Test::Unit::TestCase
92
74
  assert_equal("#123456", evaluate("rgb(18, 52, 86)"))
93
75
  assert_equal("#beaded", evaluate("rgb(190, 173, 237)"))
94
76
  assert_equal("#00ff7f", evaluate("rgb(0, 255, 127)"))
77
+ end
95
78
 
79
+ def test_rgb_tests_bounds
96
80
  assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
97
81
  "rgb(256, 1, 1)")
98
82
  assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
@@ -105,13 +89,38 @@ class SassFunctionTest < Test::Unit::TestCase
105
89
  "rgb(-1, 1, 1)")
106
90
  end
107
91
 
108
- private
92
+ def test_rgb_tests_types
93
+ assert_error_message("\"foo\" is not a number for `rgb'", "rgb(\"foo\", 10, 12)");
94
+ assert_error_message("\"foo\" is not a number for `rgb'", "rgb(10, \"foo\", 12)");
95
+ assert_error_message("\"foo\" is not a number for `rgb'", "rgb(10, 10, \"foo\")");
96
+ end
109
97
 
110
- def assert_rgb_hsl(rgb, hsl)
111
- hsl = hsl.map {|v| Sass::Script::Parser.parse v, 0, 0 }
112
- assert_equal(rgb, Sass::Script::Functions::EvaluationContext.new({}).hsl(*hsl).value)
98
+ def test_red
99
+ assert_equal("18", evaluate("red(#123456)"))
113
100
  end
114
101
 
102
+ def test_red_exception
103
+ assert_error_message("12 is not a color for `red'", "red(12)")
104
+ end
105
+
106
+ def test_green
107
+ assert_equal("52", evaluate("green(#123456)"))
108
+ end
109
+
110
+ def test_green_exception
111
+ assert_error_message("12 is not a color for `green'", "green(12)")
112
+ end
113
+
114
+ def test_blue
115
+ assert_equal("86", evaluate("blue(#123456)"))
116
+ end
117
+
118
+ def test_blue_exception
119
+ assert_error_message("12 is not a color for `blue'", "blue(12)")
120
+ end
121
+
122
+ private
123
+
115
124
  def evaluate(value)
116
125
  Sass::Script::Parser.parse(value, 0, 0).perform(Sass::Environment.new).to_s
117
126
  end
@@ -102,22 +102,8 @@ WARN
102
102
  assert_equal "public_instance_methods()", resolve("public_instance_methods()")
103
103
  end
104
104
 
105
- def test_hyphen_warning
106
- a = Sass::Script::String.new("a")
107
- b = Sass::Script::String.new("b")
108
- assert_warning(<<WARN) {eval("!a-!b", {}, env("a" => a, "b" => b))}
109
- DEPRECATION WARNING:
110
- On line 1, character 3 of 'test_hyphen_warning_inline.sass'
111
- - will be allowed as part of variable names in version 2.4.
112
- Please add whitespace to separate it from the previous token.
113
- WARN
114
-
115
- assert_warning(<<WARN) {eval("true-false")}
116
- DEPRECATION WARNING:
117
- On line 1, character 5 of 'test_hyphen_warning_inline.sass'
118
- - will be allowed as part of variable names in version 2.4.
119
- Please add whitespace to separate it from the previous token.
120
- WARN
105
+ def test_hyphenated_variables
106
+ assert_equal("a-b", resolve("!a-b", {}, env("a-b" => Sass::Script::String.new("a-b"))))
121
107
  end
122
108
 
123
109
  def test_ruby_equality
@@ -225,6 +211,12 @@ WARN
225
211
  assert_equal "true", resolve("1.1cm == 11mm")
226
212
  end
227
213
 
214
+ # Regression Tests
215
+
216
+ def test_funcall_has_higher_precedence_than_color_name
217
+ assert_equal "teal(12)", resolve("teal(12)")
218
+ end
219
+
228
220
  private
229
221
 
230
222
  def resolve(str, opts = {}, environment = env)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml-edge
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.80
4
+ version: 2.3.81
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -86,6 +86,7 @@ files:
86
86
  - lib/sass/plugin
87
87
  - lib/sass/plugin/merb.rb
88
88
  - lib/sass/plugin/rails.rb
89
+ - lib/sass/plugin/rack.rb
89
90
  - lib/sass/repl.rb
90
91
  - lib/sass/script.rb
91
92
  - lib/sass/script
@@ -197,6 +198,8 @@ files:
197
198
  - test/sass/css2sass_test.rb
198
199
  - test/sass/engine_test.rb
199
200
  - test/sass/functions_test.rb
201
+ - test/sass/data
202
+ - test/sass/data/hsl-rgb.txt
200
203
  - test/sass/more_results
201
204
  - test/sass/more_results/more1.css
202
205
  - test/sass/more_results/more1_with_line_comments.css