From eeb3f81718b74f091b60e6569223c7662b72c2d0 Mon Sep 17 00:00:00 2001 From: Nathan Weizenbaum Date: Tue, 10 Nov 2009 18:07:38 -0800 Subject: [PATCH] [Sass] Add an hsla function. --- lib/sass/script/functions.rb | 33 ++++++++++++++++++++++++++++----- test/sass/functions_test.rb | 13 +++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/sass/script/functions.rb b/lib/sass/script/functions.rb index de28ebca..fddf93f0 100644 --- a/lib/sass/script/functions.rb +++ b/lib/sass/script/functions.rb @@ -109,12 +109,33 @@ module Sass::Script # @return [Color] The resulting color # @raise [ArgumentError] if `saturation` or `lightness` are out of bounds 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, + # as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsla-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) + unless (0..1).include?(alpha.value) + raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1") + end original_s = saturation original_l = lightness # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color 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("Lightness #{l} must be between 0% and 100%") if l < 0 || l > 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%") unless (0..100).include?(l) h = (h % 360) / 360.0 s /= 100.0 @@ -122,9 +143,11 @@ module Sass::Script m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s m1 = l * 2 - m2 - Color.new([hue_to_rgb(m1, m2, h + 1.0/3), - hue_to_rgb(m1, m2, h), - hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round }) + Color.new( + [hue_to_rgb(m1, m2, h + 1.0/3), + hue_to_rgb(m1, m2, h), + hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round } + + [alpha.value]) end # Converts a decimal number to a percentage. diff --git a/test/sass/functions_test.rb b/test/sass/functions_test.rb index d6e12c6c..8ae0faee 100644 --- a/test/sass/functions_test.rb +++ b/test/sass/functions_test.rb @@ -48,6 +48,19 @@ class SassFunctionTest < Test::Unit::TestCase assert_error_message("Lightness 256 must be between 0% and 100% for `hsl'", "hsl(10, 10, 256%)"); 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_percentage assert_equal("50%", evaluate("percentage(.5)")) assert_equal("100%", evaluate("percentage(1)"))