haml-edge 2.3.80 → 2.3.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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