1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Merge branch 'rgba'

Closes gh-21
This commit is contained in:
Nathan Weizenbaum 2009-11-11 21:20:18 -08:00
commit 33b9a21c57
7 changed files with 368 additions and 25 deletions

View file

@ -7,10 +7,19 @@
### Colors ### Colors
Sass now supports functions that return the values of the Sass now supports colors with alpha channels,
constructed via the {Sass::Script::Functions#rgba rgba}
and {Sass::Script::Functions#hsla hsla} functions.
Alpha channels are unaffected by color arithmetic.
However, the {Sass::Script::Functions#opacify opacify}
and {Sass::Script::Functions#transparentize transparentize} functions
allow colors to be made more and less opaque, respectively.
Sass now also supports functions that return the values of the
{Sass::Script::Functions#red red}, {Sass::Script::Functions#red red},
{Sass::Script::Functions#blue blue}, {Sass::Script::Functions#blue blue},
and {Sass::Script::Functions#green green} {Sass::Script::Functions#green green},
and {Sass::Script::Functions#alpha alpha}
components of colors. components of colors.
### Variable Names ### Variable Names

View file

@ -692,7 +692,7 @@ available in that context.
SassScript supports four data types: SassScript supports four data types:
* numbers (e.g. `1.2`, `13`, `10px`) * numbers (e.g. `1.2`, `13`, `10px`)
* strings of text (e.g. `"foo"`, `"bar"`) * strings of text (e.g. `"foo"`, `"bar"`)
* colors (e.g. `blue`, `#04a3f9`) * colors (e.g. `blue`, `#04a3f9`, `rgba(255, 0, 0, 0.5)`)
* booleans (e.g. `true`, `false`) * booleans (e.g. `true`, `false`)
Any text that doesn't fit into one of those types Any text that doesn't fit into one of those types
@ -715,6 +715,8 @@ is compiled to:
### Operations ### Operations
#### Number Operations
SassScript supports the standard arithmetic operations on numbers SassScript supports the standard arithmetic operations on numbers
(`+`, `-`, `*`, `/`, `%`), (`+`, `-`, `*`, `/`, `%`),
and will automatically convert between units if it can: and will automatically convert between units if it can:
@ -734,6 +736,8 @@ and equality operators
(`==`, `!=`) (`==`, `!=`)
are supported for all types. are supported for all types.
#### Color Operations
All arithmetic operations are supported for color values, All arithmetic operations are supported for color values,
where they work piecewise. where they work piecewise.
This means that the operation is performed This means that the operation is performed
@ -762,6 +766,40 @@ and is compiled to:
p { p {
color: #020406; } color: #020406; }
Note that colors with an alpha channel
(those created with the {Sass::Script::Functions#rgba rgba}
or {Sass::Script::Functions#hsla hsla} functions)
must have the same alpha value in order for color arithmetic
to be done with them.
The arithmetic doesn't affect the alpha value.
For example:
p
color = rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75)
is compiled to:
p {
color: rgba(255, 255, 0, 0.75)
The alpha channel of a color can be adjusted using the
{Sass::Script::Functions#opacify opacify} and
{Sass::Script::Functions#transparentize transparentize} functions.
For example:
!translucent-red = rgba(255, 0, 0, 0.5)
p
color = opacify(!translucent-red, 80%)
background-color = transparentize(!translucent-red, 50%)
is compiled to:
p {
color: rgba(255, 0, 0, 0.9)
background-color: rgba(255, 0, 0, 0.25) }
#### String Operations
The `+` operation can be used to concatenate strings: The `+` operation can be used to concatenate strings:
p p

View file

@ -27,6 +27,30 @@ module Sass::Script
# A hash from [red, green, blue] value arrays to color names. # A hash from [red, green, blue] value arrays to color names.
HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]} HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
# Constructs an RGB or RGBA color object.
# The RGB values must be between 0 and 255,
# and the alpha value is generally expected to be between 0 and 1.
# However, the alpha value can be greater than 1
# in order to allow it to be used for color multiplication.
#
# @param rgba [Array<Numeric>] A three-element array of the red, green, blue,
# and optionally alpha values (respectively) of the color
# @raise [Sass::SyntaxError] if any color value isn't between 0 and 255,
# or the alpha value is negative
def initialize(rgba)
@red, @green, @blue = rgba[0...3].map {|c| c.to_i}
@alpha = rgba[3] ? rgba[3].to_f : 1
super(nil)
unless rgb.all? {|c| (0..255).include?(c)}
raise Sass::SyntaxError.new("Color values must be between 0 and 255")
end
unless (0..1).include?(alpha)
raise Sass::SyntaxError.new("Color opacity value must between 0 and 1")
end
end
# The red component of the color. # The red component of the color.
# #
# @return [Fixnum] # @return [Fixnum]
@ -42,16 +66,18 @@ module Sass::Script
# @return [Fixnum] # @return [Fixnum]
attr_reader :blue attr_reader :blue
# @param rgb [Array<Fixnum>] A three-element array of the red, green, and blue values (respectively) # The alpha channel (opacity) of the color.
# of the color # This is 1 unless otherwise defined.
# @raise [Sass::SyntaxError] if any color value isn't between 0 and 255 #
def initialize(rgb) # @return [Fixnum]
rgb = rgb.map {|c| c.to_i} attr_accessor :alpha
raise Sass::SyntaxError.new("Color values must be between 0 and 255") if rgb.any? {|c| c < 0 || c > 255}
@red = rgb[0] # Returns whether this color object is translucent;
@green = rgb[1] # that is, whether the alpha channel is non-1.
@blue = rgb[2] #
super(nil) # @return [Boolean]
def alpha?
alpha < 1
end end
# @deprecated This will be removed in version 2.6. # @deprecated This will be removed in version 2.6.
@ -81,7 +107,8 @@ END
# @return [Bool] True if this literal is the same as the other, # @return [Bool] True if this literal is the same as the other,
# false otherwise # false otherwise
def eq(other) def eq(other)
Sass::Script::Bool.new(other.is_a?(Color) && rgb == other.rgb) Sass::Script::Bool.new(
other.is_a?(Color) && rgb == other.rgb && alpha == other.alpha)
end end
# The SassScript `+` operation. # The SassScript `+` operation.
@ -205,6 +232,7 @@ END
# #
# @return [String] The string representation # @return [String] The string representation
def to_s def to_s
return "rgba(#{rgb.join(', ')}, #{alpha % 1 == 0.0 ? alpha.to_i : alpha})" if alpha?
return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb] return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb]
red, green, blue = rgb.map { |num| num.to_s(16).rjust(2, '0') } red, green, blue = rgb.map { |num| num.to_s(16).rjust(2, '0') }
"##{red}#{green}#{blue}" "##{red}#{green}#{blue}"
@ -224,6 +252,12 @@ END
res = rgb[i].send(operation, other_num ? other.value : other.rgb[i]) res = rgb[i].send(operation, other_num ? other.value : other.rgb[i])
result[i] = [ [res, 255].min, 0 ].max result[i] = [ [res, 255].min, 0 ].max
end end
if !other_num && other.alpha != alpha
raise Sass::SyntaxError.new("Alpha channels must be equal: #{self} #{operation} #{other}")
end
result[3] = alpha
Color.new(result) Color.new(result)
end end
end end

View file

@ -36,11 +36,12 @@ module Sass
# @raise [Sass::SyntaxError] if the function call raises an ArgumentError # @raise [Sass::SyntaxError] if the function call raises an ArgumentError
def perform(environment) def perform(environment)
args = self.args.map {|a| a.perform(environment)} args = self.args.map {|a| a.perform(environment)}
unless Haml::Util.has?(:public_instance_method, Functions, name) && name !~ /^__/ ruby_name = name.gsub('-', '_')
unless Haml::Util.has?(:public_instance_method, Functions, ruby_name) && ruby_name !~ /^__/
return Script::String.new("#{name}(#{args.map {|a| a.perform(environment)}.join(', ')})") return Script::String.new("#{name}(#{args.map {|a| a.perform(environment)}.join(', ')})")
end end
return Functions::EvaluationContext.new(environment.options).send(name, *args) return Functions::EvaluationContext.new(environment.options).send(ruby_name, *args)
rescue ArgumentError => e rescue ArgumentError => e
raise e unless e.backtrace.any? {|t| t =~ /:in `(block in )?(#{name}|perform)'$/} raise e unless e.backtrace.any? {|t| t =~ /:in `(block in )?(#{name}|perform)'$/}
raise Sass::SyntaxError.new("#{e.message} for `#{name}'") raise Sass::SyntaxError.new("#{e.message} for `#{name}'")

View file

@ -11,11 +11,14 @@ module Sass::Script
# \{#hsl} # \{#hsl}
# : Converts an `hsl(hue, saturation, lightness)` triplet into a color. # : Converts an `hsl(hue, saturation, lightness)` triplet into a color.
# #
# \{#hsla}
# : Converts an `hsla(hue, saturation, lightness, alpha)` quadruplet into a color.
#
# \{#rgb} # \{#rgb}
# : Converts an `rgb(red, green, blue)` triplet into a color. # : Converts an `rgb(red, green, blue)` triplet into a color.
# #
# \{#percentage} # \{#rgba}
# : Converts a unitless number to a percentage. # : Converts an `rgb(red, green, blue, alpha)` triplet into a color.
# #
# \{#red} # \{#red}
# : Gets the red component of a color. # : Gets the red component of a color.
@ -26,6 +29,18 @@ module Sass::Script
# \{#blue} # \{#blue}
# : Gets the blue component of a color. # : Gets the blue component of a color.
# #
# \{#alpha} / \{#opacity}
# : Gets the alpha component (opacity) of a color.
#
# \{#opacify} / \{#fade_in #fade-in}
# : Makes a color more opaque.
#
# \{#transparentize} / \{#fade_out #fade-out}
# : Makes a color more transparent.
#
# \{#percentage}
# : Converts a unitless number to a percentage.
#
# \{#round} # \{#round}
# : Rounds a number to the nearest whole number. # : Rounds a number to the nearest whole number.
# #
@ -117,15 +132,36 @@ module Sass::Script
# @param blue # @param blue
# A number between 0 and 255 inclusive # A number between 0 and 255 inclusive
def rgb(red, green, blue) def rgb(red, green, blue)
rgba(red, green, blue, Number.new(1))
end
# Creates a {Color} object from red, green, and blue values,
# as well as an alpha channel indicating opacity.
#
# @param red
# A number between 0 and 255 inclusive
# @param green
# A number between 0 and 255 inclusive
# @param blue
# A number between 0 and 255 inclusive
# @param alpha
# A number between 0 and 1
def rgba(red, green, blue, alpha)
assert_type red, :Number assert_type red, :Number
assert_type green, :Number assert_type green, :Number
assert_type blue, :Number assert_type blue, :Number
assert_type alpha, :Number
[red.value, green.value, blue.value].each do |v| [red.value, green.value, blue.value].each do |v|
next unless v < 0 || v > 255 next if (0..255).include?(v)
raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive") raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
end end
Color.new([red.value, green.value, blue.value])
unless (0..1).include?(alpha.value)
raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
end
Color.new([red.value, green.value, blue.value, alpha.value])
end end
# Creates a {Color} object from hue, saturation, and lightness. # Creates a {Color} object from hue, saturation, and lightness.
@ -140,16 +176,39 @@ module Sass::Script
# @return [Color] The resulting color # @return [Color] The resulting color
# @raise [ArgumentError] if `saturation` or `lightness` are out of bounds # @raise [ArgumentError] if `saturation` or `lightness` are out of bounds
def hsl(hue, saturation, lightness) def hsl(hue, saturation, lightness)
hsla(hue, saturation, lightness, Number.new(1))
end
# Creates a {Color} object from hue, saturation, and lightness,
# as well as an alpha channel indicating opacity.
# Uses the algorithm from the [CSS3 spec](http://www.w3.org/TR/css3-color/#hsl-color).
#
# @param hue [Number] The hue of the color.
# Should be between 0 and 360 degrees, inclusive
# @param saturation [Number] The saturation of the color.
# Must be between `0%` and `100%`, inclusive
# @param lightness [Number] The lightness of the color.
# Must be between `0%` and `100%`, inclusive
# @param alpha [Number] The opacity of the color.
# Must be between 0 and 1, inclusive
# @return [Color] The resulting color
# @raise [ArgumentError] if `saturation`, `lightness`, or `alpha` are out of bounds
def hsla(hue, saturation, lightness, alpha)
assert_type hue, :Number assert_type hue, :Number
assert_type saturation, :Number assert_type saturation, :Number
assert_type lightness, :Number assert_type lightness, :Number
assert_type alpha, :Number
unless (0..1).include?(alpha.value)
raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1")
end
original_s = saturation original_s = saturation
original_l = lightness original_l = lightness
# This algorithm is from http://www.w3.org/TR/css3-color#hsl-color # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
h, s, l = [hue, saturation, lightness].map { |a| a.value } h, s, l = [hue, saturation, lightness].map { |a| a.value }
raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") if s < 0 || s > 100 raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") unless (0..100).include?(s)
raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") if l < 0 || l > 100 raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") unless (0..100).include?(l)
h = (h % 360) / 360.0 h = (h % 360) / 360.0
s /= 100.0 s /= 100.0
@ -157,9 +216,11 @@ module Sass::Script
m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s
m1 = l * 2 - m2 m1 = l * 2 - m2
Color.new([hue_to_rgb(m1, m2, h + 1.0/3), Color.new(
[hue_to_rgb(m1, m2, h + 1.0/3),
hue_to_rgb(m1, m2, h), hue_to_rgb(m1, m2, h),
hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round }) hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round } +
[alpha.value])
end end
# Returns the red component of a color. # Returns the red component of a color.
@ -192,6 +253,68 @@ module Sass::Script
Sass::Script::Number.new(color.blue) Sass::Script::Number.new(color.blue)
end end
# Returns the alpha component (opacity) of a color.
# This is 1 unless otherwise specified.
#
# @param color [Color]
# @return [Number]
# @raise [ArgumentError] If `color` isn't a color
def alpha(color)
assert_type color, :Color
Sass::Script::Number.new(color.alpha)
end
alias_method :opacity, :alpha
# Makes a color more opaque.
# Takes a color and an amount between `0%` and `100%`
# and returns a color that's that much closer to opaque.
#
# For example, `50%` will make the color twice as opaque:
#
# opacify(rgba(0, 0, 0, 0.5), 50%) => rgba(0, 0, 0, 0.75)
# opacify(rgba(0, 0, 0, 0.8), 50%) => rgba(0, 0, 0, 0.9)
# opacify(rgba(0, 0, 0, 0.2), 50%) => rgba(0, 0, 0, 0.8)
#
# Specifically, `opacify(color, n%)` will make the color
# `n%` closer to fully opaque.
def opacify(color, amount)
assert_type color, :Color
assert_type amount, :Number
unless (0..100).include?(amount.value)
raise ArgumentError.new("Amount #{amount} must be between 0% and 100%")
end
color = color.dup
color.alpha += (1 - color.alpha) * (amount.value / 100.0)
color
end
alias_method :fade_in, :opacify
# Makes a color more transparent.
# Takes a color and an amount between `0%` and `100%`
# and returns a color that's that much closer to transparent.
#
# For example, `50%` will make the color twice as transparent:
#
# opacify(rgba(0, 0, 0, 0.5), 50%) => rgba(0, 0, 0, 0.25)
# opacify(rgba(0, 0, 0, 0.8), 50%) => rgba(0, 0, 0, 0.4)
# opacify(rgba(0, 0, 0, 0.2), 50%) => rgba(0, 0, 0, 0.1)
#
# Specifically, `transparentize(color, n%)` will make the color
# `n%` closer to fully transparent.
def transparentize(color, amount)
assert_type color, :Color
assert_type amount, :Number
unless (0..100).include?(amount.value)
raise ArgumentError.new("Amount #{amount} must be between 0% and 100%")
end
color = color.dup
color.alpha *= 1 - (amount.value / 100.0)
color
end
alias_method :fade_out, :transparentize
# Converts a decimal number to a percentage. # Converts a decimal number to a percentage.
# For example: # For example:
# #

View file

@ -27,6 +27,26 @@ class SassFunctionTest < Test::Unit::TestCase
assert_error_message("\"foo\" is not a number for `hsl'", "hsl(10, 10, \"foo\")"); assert_error_message("\"foo\" is not a number for `hsl'", "hsl(10, 10, \"foo\")");
end end
def test_hsla
assert_equal "rgba(51, 204, 204, 0.4)", evaluate("hsla(180, 60%, 50%, 0.4)")
assert_equal "#33cccc", evaluate("hsla(180, 60%, 50%, 1)")
assert_equal "rgba(51, 204, 204, 0)", evaluate("hsla(180, 60%, 50%, 0)")
end
def test_hsla_checks_bounds
assert_error_message("Saturation -114 must be between 0% and 100% for `hsla'", "hsla(10, -114, 12, 1)");
assert_error_message("Lightness 256 must be between 0% and 100% for `hsla'", "hsla(10, 10, 256%, 0)");
assert_error_message("Alpha channel -0.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, -0.1)");
assert_error_message("Alpha channel 1.1 must be between 0 and 1 for `hsla'", "hsla(10, 10, 10, 1.1)");
end
def test_hsla_checks_types
assert_error_message("\"foo\" is not a number for `hsla'", "hsla(\"foo\", 10, 12, 0.3)");
assert_error_message("\"foo\" is not a number for `hsla'", "hsla(10, \"foo\", 12, 0)");
assert_error_message("\"foo\" is not a number for `hsla'", "hsla(10, 10, \"foo\", 1)");
assert_error_message("\"foo\" is not a number for `hsla'", "hsla(10, 10, 10, \"foo\")");
end
def test_percentage def test_percentage
assert_equal("50%", evaluate("percentage(.5)")) assert_equal("50%", evaluate("percentage(.5)"))
assert_equal("100%", evaluate("percentage(1)")) assert_equal("100%", evaluate("percentage(1)"))
@ -95,6 +115,36 @@ class SassFunctionTest < Test::Unit::TestCase
assert_error_message("\"foo\" is not a number for `rgb'", "rgb(10, 10, \"foo\")"); assert_error_message("\"foo\" is not a number for `rgb'", "rgb(10, 10, \"foo\")");
end end
def test_rgba
assert_equal("rgba(18, 52, 86, 0.5)", evaluate("rgba(18, 52, 86, 0.5)"))
assert_equal("#beaded", evaluate("rgba(190, 173, 237, 1)"))
assert_equal("rgba(0, 255, 127, 0)", evaluate("rgba(0, 255, 127, 0)"))
end
def test_rgb_tests_bounds
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
"rgba(256, 1, 1, 0.3)")
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
"rgba(1, 256, 1, 0.3)")
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
"rgba(1, 1, 256, 0.3)")
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgba'",
"rgba(1, 256, 257, 0.3)")
assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgba'",
"rgba(-1, 1, 1, 0.3)")
assert_error_message("Alpha channel -0.2 must be between 0 and 1 inclusive for `rgba'",
"rgba(1, 1, 1, -0.2)")
assert_error_message("Alpha channel 1.2 must be between 0 and 1 inclusive for `rgba'",
"rgba(1, 1, 1, 1.2)")
end
def test_rgba_tests_types
assert_error_message("\"foo\" is not a number for `rgba'", "rgba(\"foo\", 10, 12, 0.2)");
assert_error_message("\"foo\" is not a number for `rgba'", "rgba(10, \"foo\", 12, 0.1)");
assert_error_message("\"foo\" is not a number for `rgba'", "rgba(10, 10, \"foo\", 0)");
assert_error_message("\"foo\" is not a number for `rgba'", "rgba(10, 10, 10, \"foo\")");
end
def test_red def test_red
assert_equal("18", evaluate("red(#123456)")) assert_equal("18", evaluate("red(#123456)"))
end end
@ -119,6 +169,56 @@ class SassFunctionTest < Test::Unit::TestCase
assert_error_message("12 is not a color for `blue'", "blue(12)") assert_error_message("12 is not a color for `blue'", "blue(12)")
end end
def test_alpha
assert_equal("1", evaluate("alpha(#123456)"))
assert_equal("0.34", evaluate("alpha(rgba(0, 1, 2, 0.34))"))
assert_equal("0", evaluate("alpha(hsla(0, 1, 2, 0))"))
end
def test_alpha_exception
assert_error_message("12 is not a color for `alpha'", "alpha(12)")
end
def test_opacify
assert_equal("rgba(0, 0, 0, 0.75)", evaluate("opacify(rgba(0, 0, 0, 0.5), 50%)"))
assert_equal("rgba(0, 0, 0, 0.8)", evaluate("opacify(rgba(0, 0, 0, 0.2), 75)"))
assert_equal("rgba(0, 0, 0, 0.28)", evaluate("fade-in(rgba(0, 0, 0, 0.2), 10px)"))
assert_equal("black", evaluate("fade_in(rgba(0, 0, 0, 0.2), 100%)"))
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("opacify(rgba(0, 0, 0, 0.2), 0%)"))
end
def test_opacify_tests_bounds
assert_error_message("Amount -3012% must be between 0% and 100% for `opacify'",
"opacify(rgba(0, 0, 0, 0.2), -3012%)")
assert_error_message("Amount 101 must be between 0% and 100% for `opacify'",
"opacify(rgba(0, 0, 0, 0.2), 101)")
end
def test_opacify_tests_types
assert_error_message("\"foo\" is not a color for `opacify'", "opacify(\"foo\", 10%)")
assert_error_message("\"foo\" is not a number for `opacify'", "opacify(#fff, \"foo\")")
end
def test_transparentize
assert_equal("rgba(0, 0, 0, 0.25)", evaluate("transparentize(rgba(0, 0, 0, 0.5), 50%)"))
assert_equal("rgba(0, 0, 0, 0.05)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 75)"))
assert_equal("rgba(0, 0, 0, 0.18)", evaluate("fade-out(rgba(0, 0, 0, 0.2), 10px)"))
assert_equal("rgba(0, 0, 0, 0)", evaluate("fade_out(rgba(0, 0, 0, 0.2), 100%)"))
assert_equal("rgba(0, 0, 0, 0.2)", evaluate("transparentize(rgba(0, 0, 0, 0.2), 0%)"))
end
def test_transparentize_tests_bounds
assert_error_message("Amount -3012% must be between 0% and 100% for `transparentize'",
"transparentize(rgba(0, 0, 0, 0.2), -3012%)")
assert_error_message("Amount 101 must be between 0% and 100% for `transparentize'",
"transparentize(rgba(0, 0, 0, 0.2), 101)")
end
def test_transparentize_tests_types
assert_error_message("\"foo\" is not a color for `transparentize'", "transparentize(\"foo\", 10%)")
assert_error_message("\"foo\" is not a number for `transparentize'", "transparentize(#fff, \"foo\")")
end
private private
def evaluate(value) def evaluate(value)

View file

@ -10,6 +10,11 @@ class SassScriptTest < Test::Unit::TestCase
assert_raise(Sass::SyntaxError, "Color values must be between 0 and 255") {Color.new([256, 2, 3])} assert_raise(Sass::SyntaxError, "Color values must be between 0 and 255") {Color.new([256, 2, 3])}
end end
def test_color_checks_rgba_input
assert_raise(Sass::SyntaxError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, 1.1])}
assert_raise(Sass::SyntaxError, "Alpha channel must be between 0 and 1") {Color.new([1, 2, 3, -0.1])}
end
def test_string_escapes def test_string_escapes
assert_equal '"', resolve("\"\\\"\"") assert_equal '"', resolve("\"\\\"\"")
assert_equal "\\", resolve("\"\\\\\"") assert_equal "\\", resolve("\"\\\\\"")
@ -22,6 +27,39 @@ class SassScriptTest < Test::Unit::TestCase
assert_equal "#fffffe", resolve("white - #000001") assert_equal "#fffffe", resolve("white - #000001")
end end
def test_rgba_color_literals
assert_equal Sass::Script::Color.new([1, 2, 3, 0.75]), eval("rgba(1, 2, 3, 0.75)")
assert_equal "rgba(1, 2, 3, 0.75)", resolve("rgba(1, 2, 3, 0.75)")
assert_equal Sass::Script::Color.new([1, 2, 3, 0]), eval("rgba(1, 2, 3, 0)")
assert_equal "rgba(1, 2, 3, 0)", resolve("rgba(1, 2, 3, 0)")
assert_equal Sass::Script::Color.new([1, 2, 3]), eval("rgba(1, 2, 3, 1)")
assert_equal Sass::Script::Color.new([1, 2, 3, 1]), eval("rgba(1, 2, 3, 1)")
assert_equal "#010203", resolve("rgba(1, 2, 3, 1)")
assert_equal "white", resolve("rgba(255, 255, 255, 1)")
end
def test_rgba_color_math
assert_equal "rgba(50, 50, 100, 0.35)", resolve("rgba(1, 1, 2, 0.35) * rgba(50, 50, 50, 0.35)")
assert_equal "rgba(52, 52, 52, 0.25)", resolve("rgba(2, 2, 2, 0.25) + rgba(50, 50, 50, 0.25)")
assert_raise(Sass::SyntaxError, "Alpha channels must be equal: rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)") do
resolve("rgba(1, 2, 3, 0.15) + rgba(50, 50, 50, 0.75)")
end
assert_raise(Sass::SyntaxError, "Alpha channels must be equal: #123456 * rgba(50, 50, 50, 0.75)") do
resolve("#123456 * rgba(50, 50, 50, 0.75)")
end
assert_raise(Sass::SyntaxError, "Alpha channels must be equal: #123456 / #123456") do
resolve("rgba(50, 50, 50, 0.75) / #123456")
end
end
def test_rgba_number_math
assert_equal "rgba(49, 49, 49, 0.75)", resolve("rgba(50, 50, 50, 0.75) - 1")
assert_equal "rgba(100, 100, 100, 0.75)", resolve("rgba(50, 50, 50, 0.75) * 2")
end
def test_implicit_strings def test_implicit_strings
silence_warnings do silence_warnings do
assert_equal Sass::Script::String.new("foo"), eval("foo") assert_equal Sass::Script::String.new("foo"), eval("foo")