Skip to content

Commit

Permalink
[Sass] Use !default rather than ||: for guarded properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 committed Mar 30, 2010
1 parent a124c63 commit 8ca3be0
Show file tree
Hide file tree
Showing 15 changed files with 65 additions and 43 deletions.
16 changes: 8 additions & 8 deletions lib/sass/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ def parse_property(line, property_regx)
if eq.strip[0] == SCRIPT_CHAR
expr.context = :equals
Script.equals_warning("properties", name,
Sass::Tree::PropNode.val_to_sass(expr), @line,
line.offset + 1, @options[:filename])
Sass::Tree::PropNode.val_to_sass(expr), false,
@line, line.offset + 1, @options[:filename])
end
end
Tree::PropNode.new(
Expand All @@ -425,7 +425,8 @@ def parse_property(line, property_regx)
end

def parse_variable(line)
name, op, value = line.text.scan(Script::MATCH)[0]
name, op, value, default = line.text.scan(Script::MATCH)[0]
guarded = op =~ /^\|\|/
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath variable declarations.",
:line => @line + 1) unless line.children.empty?
raise SyntaxError.new("Invalid variable: \"#{line.text}\".",
Expand All @@ -435,13 +436,12 @@ def parse_variable(line)
expr = parse_script(value, :offset => line.offset + line.text.index(value))
if op =~ /=$/
expr.context = :equals
warning_name = "$#{name}"
warning_name << " ||" if op =~ /^\|\|/
Script.equals_warning("variables", warning_name, expr.to_sass,
@line, line.offset + 1, @options[:filename])
type = guarded ? "variable defaults" : "variables"
Script.equals_warning(type, "$#{name}", expr.to_sass,
guarded, @line, line.offset + 1, @options[:filename])
end

Tree::VariableNode.new(name, expr, op =~ /^\|\|/)
Tree::VariableNode.new(name, expr, default || guarded)
end

def parse_comment(line)
Expand Down
2 changes: 1 addition & 1 deletion lib/sass/repl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def parse_input(environment, text)
case text
when Script::MATCH
name = $1
guarded = $2 == '||='
guarded = $3 == '||=' || $4
val = Script::Parser.parse($3, @line, text.size - $3.size)

unless guarded && environment.var(name)
Expand Down
8 changes: 4 additions & 4 deletions lib/sass/script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module Sass
module Script
# The regular expression used to parse variables.
# @private
MATCH = /^[!\$](#{Sass::SCSS::RX::IDENT})\s*((?:\|\|)?[:=])\s*(.+)/
MATCH = /^[!\$](#{Sass::SCSS::RX::IDENT})\s*((?:\|\|)?=|:)\s*(.+?)(!(?i:default))?$/

# The regular expression used to validate variables without matching.
# @private
Expand Down Expand Up @@ -50,12 +50,12 @@ def self.var_warning(varname, line, offset, filename)
MESSAGE
end

def self.equals_warning(types, name, val, line, offset, filename)
def self.equals_warning(types, name, val, guarded, line, offset, filename)
Haml::Util.haml_warn <<MESSAGE
DEPRECATION WARNING:
On line #{line}#{", character #{offset}" if offset}#{" of '#{filename}'" if filename}
Setting #{types} with = has been deprecated and will be removed in version 3.2.
Use "#{name}: #{val}" instead.
Setting #{types} with #{"||" if guarded}= has been deprecated and will be removed in version 3.2.
Use "#{name}: #{val}#{" !default" if guarded}" instead.
You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
MESSAGE
Expand Down
8 changes: 3 additions & 5 deletions lib/sass/script/css_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
module Sass
module Script
class CssParser < Parser
def initialize(str, line, offset, options = {})
@options = options
@lexer = CssLexer.new(str, line, offset, options)
end

private

# @private
def lexer_class; CssLexer; end

# We need a production that only does /,
# since * and % aren't allowed in plain CSS
production :div, :unary_plus, :div
Expand Down
6 changes: 5 additions & 1 deletion lib/sass/script/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,13 @@ def token
end

def variable
_variable(REGULAR_EXPRESSIONS[:variable])
end

def _variable(rx)
line = @line
offset = @offset
return unless scan(REGULAR_EXPRESSIONS[:variable])
return unless scan(rx)
if @scanner[1] == '!' && @scanner[2] != 'important'
Script.var_warning(@scanner[2], line, offset + 1, @options[:filename])
end
Expand Down
7 changes: 5 additions & 2 deletions lib/sass/script/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def line
# see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
def initialize(str, line, offset, options = {})
@options = options
@lexer = Lexer.new(str, line, offset, options)
@lexer = lexer_class.new(str, line, offset, options)
end

# Parses a SassScript expression within an interpolated segment (`#{}`).
Expand Down Expand Up @@ -182,6 +182,9 @@ def unary_#{op}

private

# @private
def lexer_class; Lexer; end

production :expr, :interpolation, :comma

def interpolation
Expand Down Expand Up @@ -246,7 +249,7 @@ def defn_arglist(must_have_default)
if tok.type == :single_eq
val.context = :equals
Script.equals_warning("mixin argument defaults", "$#{c.value}",
val.to_sass, line, offset, @options[:filename])
val.to_sass, false, line, offset, @options[:filename])
end
elsif must_have_default
raise SyntaxError.new("Required argument #{var.inspect} must come before any optional arguments.")
Expand Down
1 change: 1 addition & 0 deletions lib/sass/scss.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'sass/scss/rx'
require 'sass/scss/script_lexer'
require 'sass/scss/script_parser'
require 'sass/scss/parser'

Expand Down
14 changes: 4 additions & 10 deletions lib/sass/scss/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,16 +243,11 @@ def media_expr
def variable
return unless tok(/\$/)
name = tok!(IDENT)
ss

if tok(/\|/)
tok!(/\|/)
guarded = true
end
ss; tok!(/:/); ss

tok!(/:/)
ss
node(Sass::Tree::VariableNode.new(name, sass_script(:parse), guarded))
expr = sass_script(:parse)
guarded = tok(DEFAULT)
node(Sass::Tree::VariableNode.new(name, expr, guarded))
end

def operator
Expand Down Expand Up @@ -497,7 +492,6 @@ def value
@use_property_exception ||= space || !tok?(IDENT)

return true, Sass::Script::String.new("") if tok?(/\{/)
# expression, space, value
return space, sass_script(:parse)
end

Expand Down
1 change: 1 addition & 0 deletions lib/sass/scss/rx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def self.quote(str, flags = 0)
HASH = /##{NAME}/

IMPORTANT = /!#{W}important/i
DEFAULT = /!#{W}default/i

NUMBER = /#{NUM}(?:#{IDENT}|%)?/

Expand Down
13 changes: 13 additions & 0 deletions lib/sass/scss/script_lexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Sass
module SCSS
# A mixin for subclasses of {Sass::Script::Lexer}
# that makes them usable by {SCSS::Parser} to parse SassScript.
# In particular, the lexer doesn't support `!` for a variable prefix.
module ScriptLexer
def variable
return [:raw, "!important"] if scan(Sass::SCSS::RX::IMPORTANT)
_variable(/(\$)(#{Sass::SCSS::RX::IDENT})/)
end
end
end
end
8 changes: 8 additions & 0 deletions lib/sass/scss/script_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ module SCSS
# that makes them usable by {SCSS::Parser} to parse SassScript.
# In particular, the parser won't raise an error
# when there's more content in the lexer once lexing is done.
# In addition, the parser doesn't support `!` for a variable prefix.
module ScriptParser
private

# @private
def lexer_class
klass = Class.new(super)
klass.send(:include, ScriptLexer)
klass
end

# Instead of raising an error when the parser is done,
# rewind the StringScanner so that it hasn't consumed the final token.
def assert_done
Expand Down
2 changes: 1 addition & 1 deletion lib/sass/tree/variable_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def initialize(name, expr, guarded)
protected

def to_src(tabs, opts, fmt)
"#{' ' * tabs}$#{@name}#{' ||' if @guarded}: #{@expr.to_sass}#{semi fmt}\n"
"#{' ' * tabs}$#{@name}: #{@expr.to_sass}#{' !default' if @guarded}#{semi fmt}\n"
end

# Loads the new variable value into the environment.
Expand Down
10 changes: 5 additions & 5 deletions test/sass/conversion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -761,20 +761,20 @@ def test_variable_definition

def test_guarded_variable_definition
assert_renders <<SASS, <<SCSS
$var1 ||: 12px + 15px
$var1: 12px + 15px !default
foo
$var2 ||: flaz(#abcdef)
$var2: flaz(#abcdef) !default
val: $var1 $var2
SASS
$var1 ||: 12px + 15px;
$var1: 12px + 15px !default;
foo {
$var2 ||: flaz(#abcdef);
$var2: flaz(#abcdef) !default;
val: $var1 $var2; }
SCSS

assert_sass_to_scss '$var ||: 12px $bar baz;', '$var ||= 12px $bar "baz"'
assert_sass_to_scss '$var: 12px $bar baz !default;', '$var ||= 12px $bar "baz"'
end

# Sass 3 Deprecation conversions
Expand Down
8 changes: 4 additions & 4 deletions test/sass/engine_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -822,8 +822,8 @@ def test_equals_warning_for_property_with_division
end

def test_guarded_assign
assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b\n$foo ||: c\nfoo\n a: $foo}))
assert_equal("foo {\n a: b; }\n", render(%Q{$foo ||: b\nfoo\n a: $foo}))
assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b\n$foo: c !default\nfoo\n a: $foo}))
assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b !default\nfoo\n a: $foo}))
end

def test_mixins
Expand Down Expand Up @@ -1168,8 +1168,8 @@ def test_equals_warning_for_guarded_variables
assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SASS))}
DEPRECATION WARNING:
On line 2, character 1 of 'test_equals_warning_for_guarded_variables_inline.sass'
Setting variables with = has been deprecated and will be removed in version 3.2.
Use "$equals-var ||: 2px 3px" instead.
Setting variable defaults with ||= has been deprecated and will be removed in version 3.2.
Use "$equals-var: 2px 3px !default" instead.
You can use `sass-convert --in-place --from sass2 file.sass' to convert files automatically.
WARN
Expand Down
4 changes: 2 additions & 2 deletions test/sass/scss/scss_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_guard_assign
a: 1; }
CSS
$var: 1;
$var ||: 2;
$var: 2 !default;
foo {a: $var}
SCSS
Expand All @@ -77,7 +77,7 @@ def test_guard_assign
foo {
a: 2; }
CSS
$var ||: 2;
$var: 2 !default;
foo {a: $var}
SCSS
Expand Down

0 comments on commit 8ca3be0

Please sign in to comment.