mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Add a boolean datatype to SassScript.
This commit is contained in:
parent
d394f8165f
commit
901e1f378d
6 changed files with 93 additions and 3 deletions
|
@ -1,3 +1,4 @@
|
|||
require 'strscan'
|
||||
require 'sass/constant/operation'
|
||||
require 'sass/constant/literal'
|
||||
|
||||
|
@ -29,16 +30,20 @@ module Sass
|
|||
?* => :times,
|
||||
?/ => :div,
|
||||
?% => :mod,
|
||||
?& => :single_and,
|
||||
?| => :single_or,
|
||||
CONSTANT_CHAR => :const,
|
||||
STRING_CHAR => :str,
|
||||
ESCAPE_CHAR => :esc
|
||||
}
|
||||
|
||||
CONSTANT_CHARS = (SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape(c.chr) }.join
|
||||
|
||||
# The regular expression used to parse constants
|
||||
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+)\s*((?:\|\|)?=)\s*(.+)/
|
||||
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{CONSTANT_CHARS}]+)\s*((?:\|\|)?=)\s*(.+)/
|
||||
|
||||
# The regular expression used to validate constants without matching
|
||||
VALIDATE = /^#{Regexp.escape(CONSTANT_CHAR.chr)}[^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+$/
|
||||
VALIDATE = /^#{Regexp.escape(CONSTANT_CHAR.chr)}[^\s#{CONSTANT_CHARS}]+$/
|
||||
|
||||
# Order of operations hash
|
||||
ORDER = {
|
||||
|
@ -129,12 +134,17 @@ module Sass
|
|||
end
|
||||
|
||||
# Time for a unary op!
|
||||
if ![nil, :open, :close, :const].include?(symbol) && beginning_of_token
|
||||
if ![nil, :open, :close, :const, :single_and, :single_or].include?(symbol) && beginning_of_token
|
||||
beginning_of_token = true
|
||||
to_return << :unary << symbol
|
||||
next
|
||||
end
|
||||
|
||||
if (symbol == :single_and || symbol == :single_or) && last == symbol
|
||||
to_return[-1] = symbol.to_s.gsub(/^single_/, '').to_sym
|
||||
next
|
||||
end
|
||||
|
||||
# Are we looking at an operator?
|
||||
if symbol && (symbol != :mod || str.empty?)
|
||||
str = reset_str.call
|
||||
|
|
19
lib/sass/constant/bool.rb
Normal file
19
lib/sass/constant/bool.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
require 'sass/constant/literal'
|
||||
|
||||
module Sass::Constant
|
||||
class Bool < Literal # :nodoc:
|
||||
|
||||
def parse(value)
|
||||
first, second, unit = value.scan(Literal::NUMBER)[0]
|
||||
@value = value == 'true' ? true : false
|
||||
end
|
||||
|
||||
def to_s
|
||||
@value.to_s
|
||||
end
|
||||
|
||||
def to_bool
|
||||
@value
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,6 +6,7 @@ module Sass::Constant; class Literal; end; end;
|
|||
require 'sass/constant/string'
|
||||
require 'sass/constant/number'
|
||||
require 'sass/constant/color'
|
||||
require 'sass/constant/bool'
|
||||
require 'sass/constant/nil'
|
||||
|
||||
class Sass::Constant::Literal # :nodoc:
|
||||
|
@ -23,6 +24,8 @@ class Sass::Constant::Literal # :nodoc:
|
|||
Sass::Constant::Number.new(value)
|
||||
when COLOR
|
||||
Sass::Constant::Color.new(value)
|
||||
when "true", "false"
|
||||
Sass::Constant::Bool.new(value)
|
||||
when ::Symbol
|
||||
value
|
||||
else
|
||||
|
@ -42,6 +45,14 @@ class Sass::Constant::Literal # :nodoc:
|
|||
self
|
||||
end
|
||||
|
||||
def and(other)
|
||||
to_bool ? other : self
|
||||
end
|
||||
|
||||
def or(other)
|
||||
to_bool ? self : other
|
||||
end
|
||||
|
||||
def concat(other)
|
||||
Sass::Constant::String.from_value("#{self.to_s} #{other.to_s}")
|
||||
end
|
||||
|
@ -58,6 +69,10 @@ class Sass::Constant::Literal # :nodoc:
|
|||
[self]
|
||||
end
|
||||
|
||||
def to_bool
|
||||
true
|
||||
end
|
||||
|
||||
attr_reader :value
|
||||
|
||||
protected
|
||||
|
|
|
@ -9,5 +9,9 @@ module Sass::Constant
|
|||
def to_arglist
|
||||
[]
|
||||
end
|
||||
|
||||
def to_bool
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,9 @@ require 'sass/constant/unary_operation'
|
|||
module Sass::Constant
|
||||
class Operation # :nodoc:
|
||||
def initialize(operand1, operand2, operator)
|
||||
raise Sass::SyntaxError.new("SassScript doesn't support a single-& operator.") if operator == :single_and
|
||||
raise Sass::SyntaxError.new("SassScript doesn't support a single-| operator.") if operator == :single_or
|
||||
|
||||
@operand1 = operand1
|
||||
@operand2 = operand2
|
||||
@operator = operator
|
||||
|
|
|
@ -67,6 +67,8 @@ class SassEngineTest < Test::Unit::TestCase
|
|||
"=a(!foo bar)" => "Invalid constant \"!foo bar\".",
|
||||
"=foo\n bar: baz\n+foo" => ["Attributes aren't allowed at the root of a document.", 2],
|
||||
"a-\#{!b\n c: d" => ["Unbalanced brackets.", 1],
|
||||
"!a = 1 & 2" => "SassScript doesn't support a single-& operator.",
|
||||
"!a = 1 | 2" => "SassScript doesn't support a single-| operator.",
|
||||
|
||||
# Regression tests
|
||||
"a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3],
|
||||
|
@ -369,6 +371,43 @@ a-\#{!a}
|
|||
SASS
|
||||
end
|
||||
|
||||
def test_booleans
|
||||
assert_equal(<<CSS, render(<<SASS))
|
||||
a {
|
||||
b: true;
|
||||
c: false;
|
||||
t1: true;
|
||||
t2: true;
|
||||
t3: true;
|
||||
t4: true;
|
||||
f1: false;
|
||||
f2: false;
|
||||
f3: false;
|
||||
f4: false; }
|
||||
CSS
|
||||
a
|
||||
b = true
|
||||
c = false
|
||||
t1 = true && true
|
||||
t2 = false || true
|
||||
t3 = true || false
|
||||
t4 = true || true
|
||||
f1 = false || false
|
||||
f2 = false && true
|
||||
f3 = true && false
|
||||
f4 = false && false
|
||||
SASS
|
||||
end
|
||||
|
||||
def test_boolean_ops
|
||||
assert_equal("a {\n b: 1;\n c: 2;\n d: 3; }\n", render(<<SASS))
|
||||
a
|
||||
b = false || 1
|
||||
c = 2 || 3
|
||||
d = 2 && 3
|
||||
SASS
|
||||
end
|
||||
|
||||
def test_functions
|
||||
assert_equal("a {\n b: #80ff80; }\n", render("a\n b = hsl(120, 100%, 75%)"))
|
||||
assert_equal("a {\n b: #81ff81; }\n", render("a\n b = hsl(120, 100%, 75%) + #010001"))
|
||||
|
|
Loading…
Reference in a new issue