haml 3.0.0.beta.3 → 3.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/.yardopts +2 -0
- data/REMEMBER +4 -11
- data/Rakefile +24 -2
- data/VERSION +1 -1
- data/lib/haml.rb +5 -2
- data/lib/haml/exec.rb +11 -4
- data/lib/haml/filters.rb +3 -0
- data/lib/haml/helpers.rb +2 -10
- data/lib/haml/helpers/action_view_extensions.rb +4 -2
- data/lib/haml/helpers/action_view_mods.rb +6 -4
- data/lib/haml/html.rb +0 -1
- data/lib/haml/precompiler.rb +37 -30
- data/lib/haml/railtie.rb +6 -2
- data/lib/haml/root.rb +4 -0
- data/lib/haml/template.rb +2 -0
- data/lib/haml/util.rb +74 -0
- data/lib/haml/util/subset_map.rb +101 -0
- data/lib/sass.rb +1 -0
- data/lib/sass/engine.rb +36 -31
- data/lib/sass/files.rb +1 -1
- data/lib/sass/plugin.rb +21 -0
- data/lib/sass/plugin/staleness_checker.rb +9 -9
- data/lib/sass/script.rb +1 -2
- data/lib/sass/script/color.rb +4 -3
- data/lib/sass/script/css_lexer.rb +11 -1
- data/lib/sass/script/css_parser.rb +4 -1
- data/lib/sass/script/funcall.rb +9 -0
- data/lib/sass/script/interpolation.rb +21 -0
- data/lib/sass/script/lexer.rb +30 -13
- data/lib/sass/script/node.rb +1 -1
- data/lib/sass/script/number.rb +4 -5
- data/lib/sass/script/parser.rb +13 -14
- data/lib/sass/script/string.rb +8 -2
- data/lib/sass/script/string_interpolation.rb +27 -4
- data/lib/sass/scss.rb +3 -0
- data/lib/sass/scss/css_parser.rb +5 -3
- data/lib/sass/scss/parser.rb +146 -64
- data/lib/sass/scss/rx.rb +9 -1
- data/lib/sass/scss/sass_parser.rb +11 -0
- data/lib/sass/scss/script_lexer.rb +2 -0
- data/lib/sass/scss/static_parser.rb +48 -0
- data/lib/sass/selector.rb +353 -0
- data/lib/sass/selector/abstract_sequence.rb +40 -0
- data/lib/sass/selector/comma_sequence.rb +80 -0
- data/lib/sass/selector/sequence.rb +194 -0
- data/lib/sass/selector/simple.rb +107 -0
- data/lib/sass/selector/simple_sequence.rb +161 -0
- data/lib/sass/tree/comment_node.rb +1 -0
- data/lib/sass/tree/debug_node.rb +1 -0
- data/lib/sass/tree/directive_node.rb +1 -0
- data/lib/sass/tree/extend_node.rb +60 -0
- data/lib/sass/tree/for_node.rb +1 -0
- data/lib/sass/tree/if_node.rb +2 -0
- data/lib/sass/tree/import_node.rb +2 -0
- data/lib/sass/tree/mixin_def_node.rb +1 -0
- data/lib/sass/tree/mixin_node.rb +21 -5
- data/lib/sass/tree/node.rb +59 -12
- data/lib/sass/tree/prop_node.rb +20 -21
- data/lib/sass/tree/root_node.rb +8 -17
- data/lib/sass/tree/rule_node.rb +49 -100
- data/lib/sass/tree/variable_node.rb +1 -0
- data/lib/sass/tree/warn_node.rb +1 -0
- data/lib/sass/tree/while_node.rb +1 -0
- data/test/haml/engine_test.rb +185 -3
- data/test/haml/helper_test.rb +25 -2
- data/test/haml/template_test.rb +2 -2
- data/test/haml/templates/helpers.haml +13 -0
- data/test/haml/util/subset_map_test.rb +91 -0
- data/test/haml/util_test.rb +25 -0
- data/test/sass/conversion_test.rb +23 -3
- data/test/sass/engine_test.rb +50 -7
- data/test/sass/extend_test.rb +1045 -0
- data/test/sass/results/complex.css +0 -1
- data/test/sass/results/script.css +1 -1
- data/test/sass/script_conversion_test.rb +16 -0
- data/test/sass/script_test.rb +37 -4
- data/test/sass/scss/css_test.rb +17 -3
- data/test/sass/scss/rx_test.rb +1 -1
- data/test/sass/scss/scss_test.rb +30 -0
- data/test/sass/templates/complex.sass +0 -2
- data/test/test_helper.rb +5 -0
- metadata +18 -4
@@ -22,6 +22,7 @@ module Sass
|
|
22
22
|
# *WARNING*: It is important not to retain the instance for too long,
|
23
23
|
# as its instance-level caches are never explicitly expired.
|
24
24
|
class StalenessChecker
|
25
|
+
DELETED = 1.0/0.0 # positive Infinity
|
25
26
|
@dependencies_cache = {}
|
26
27
|
|
27
28
|
class << self
|
@@ -47,15 +48,9 @@ module Sass
|
|
47
48
|
# @param template_file [String] The location of the Sass or SCSS template
|
48
49
|
# that is compiled to `css_file`.
|
49
50
|
def stylesheet_needs_update?(css_file, template_file)
|
50
|
-
template_file = File.expand_path(template_file)
|
51
|
+
template_file, css_mtime = File.expand_path(template_file), mtime(css_file)
|
51
52
|
|
52
|
-
|
53
|
-
@dependencies.delete(template_file)
|
54
|
-
true
|
55
|
-
else
|
56
|
-
css_mtime = mtime(css_file)
|
57
|
-
mtime(template_file) > css_mtime || dependencies_stale?(template_file, css_mtime)
|
58
|
-
end
|
53
|
+
css_mtime == DELETED || dependency_updated?(css_mtime).call(template_file)
|
59
54
|
end
|
60
55
|
|
61
56
|
# Returns whether or not a given CSS file is out of date
|
@@ -87,7 +82,12 @@ module Sass
|
|
87
82
|
end
|
88
83
|
|
89
84
|
def mtime(filename)
|
90
|
-
@mtimes[filename] ||=
|
85
|
+
@mtimes[filename] ||= begin
|
86
|
+
File.mtime(filename).to_i
|
87
|
+
rescue Errno::ENOENT
|
88
|
+
@dependencies.delete(filename)
|
89
|
+
DELETED
|
90
|
+
end
|
91
91
|
end
|
92
92
|
|
93
93
|
def dependencies(filename)
|
data/lib/sass/script.rb
CHANGED
@@ -13,11 +13,9 @@ module Sass
|
|
13
13
|
# This module contains code that handles the parsing and evaluation of SassScript.
|
14
14
|
module Script
|
15
15
|
# The regular expression used to parse variables.
|
16
|
-
# @private
|
17
16
|
MATCH = /^[!\$](#{Sass::SCSS::RX::IDENT})\s*((?:\|\|)?=|:)\s*(.+?)(!(?i:default))?$/
|
18
17
|
|
19
18
|
# The regular expression used to validate variables without matching.
|
20
|
-
# @private
|
21
19
|
VALIDATE = /^[!\$]#{Sass::SCSS::RX::IDENT}$/
|
22
20
|
|
23
21
|
# Parses a string of SassScript
|
@@ -50,6 +48,7 @@ You can use `sass-convert --in-place --from sass2 file.sass' to convert files au
|
|
50
48
|
MESSAGE
|
51
49
|
end
|
52
50
|
|
51
|
+
# @private
|
53
52
|
def self.equals_warning(types, name, val, guarded, line, offset, filename)
|
54
53
|
Haml::Util.haml_warn <<MESSAGE
|
55
54
|
DEPRECATION WARNING:
|
data/lib/sass/script/color.rb
CHANGED
@@ -19,7 +19,6 @@ module Sass::Script
|
|
19
19
|
class << self; include Haml::Util; end
|
20
20
|
|
21
21
|
# A hash from color names to `[red, green, blue]` value arrays.
|
22
|
-
# @private
|
23
22
|
HTML4_COLORS = map_vals({
|
24
23
|
'black' => 0x000000,
|
25
24
|
'silver' => 0xc0c0c0,
|
@@ -39,7 +38,6 @@ module Sass::Script
|
|
39
38
|
'aqua' => 0x00ffff
|
40
39
|
}) {|color| (0..2).map {|n| color >> (n << 3) & 0xff}.reverse}
|
41
40
|
# A hash from `[red, green, blue]` value arrays to color names.
|
42
|
-
# @private
|
43
41
|
HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
|
44
42
|
|
45
43
|
# Constructs an RGB or HSL color object,
|
@@ -108,7 +106,10 @@ module Sass::Script
|
|
108
106
|
end
|
109
107
|
|
110
108
|
[:saturation, :lightness].each do |k|
|
111
|
-
next if @attrs[k].nil?
|
109
|
+
next if @attrs[k].nil?
|
110
|
+
@attrs[k] = 0 if @attrs[k] < 0.00001 && @attrs[k] > -0.00001
|
111
|
+
@attrs[k] = 100 if @attrs[k] - 100 < 0.00001 && @attrs[k] - 100 > -0.00001
|
112
|
+
next if (0..100).include?(@attrs[k])
|
112
113
|
raise Sass::SyntaxError.new("#{k.to_s.capitalize} must be between 0 and 100")
|
113
114
|
end
|
114
115
|
|
@@ -1,11 +1,21 @@
|
|
1
1
|
module Sass
|
2
2
|
module Script
|
3
|
+
# This is a subclass of {Lexer} for use in parsing plain CSS properties.
|
4
|
+
#
|
5
|
+
# @see Sass::SCSS::CssParser
|
3
6
|
class CssLexer < Lexer
|
7
|
+
private
|
8
|
+
|
4
9
|
def token
|
5
10
|
important || super
|
6
11
|
end
|
7
12
|
|
8
|
-
def string(*args)
|
13
|
+
def string(re, *args)
|
14
|
+
if re == :uri
|
15
|
+
return unless uri = scan(URI)
|
16
|
+
return [:string, Script::String.new(uri)]
|
17
|
+
end
|
18
|
+
|
9
19
|
return unless scan(STRING)
|
10
20
|
[:string, Script::String.new((@scanner[1] || @scanner[2]).gsub(/\\(['"])/, '\1'), :string)]
|
11
21
|
end
|
@@ -3,6 +3,9 @@ require 'sass/script/css_lexer'
|
|
3
3
|
|
4
4
|
module Sass
|
5
5
|
module Script
|
6
|
+
# This is a subclass of {Parser} for use in parsing plain CSS properties.
|
7
|
+
#
|
8
|
+
# @see Sass::SCSS::CssParser
|
6
9
|
class CssParser < Parser
|
7
10
|
private
|
8
11
|
|
@@ -21,7 +24,7 @@ module Sass
|
|
21
24
|
# Short-circuit all the SassScript-only productions
|
22
25
|
alias_method :interpolation, :concat
|
23
26
|
alias_method :or_expr, :div
|
24
|
-
alias_method :unary_div, :
|
27
|
+
alias_method :unary_div, :ident
|
25
28
|
alias_method :paren, :string
|
26
29
|
end
|
27
30
|
end
|
data/lib/sass/script/funcall.rb
CHANGED
@@ -17,6 +17,15 @@ module Sass
|
|
17
17
|
# @return [Array<Script::Node>]
|
18
18
|
attr_reader :args
|
19
19
|
|
20
|
+
# Don't set the context for child nodes if this is `url()`,
|
21
|
+
# since `url()` allows quoted strings.
|
22
|
+
#
|
23
|
+
# @param context [Symbol]
|
24
|
+
# @see Node#context=
|
25
|
+
def context=(context)
|
26
|
+
super unless @name == "url"
|
27
|
+
end
|
28
|
+
|
20
29
|
# @param name [String] See \{#name}
|
21
30
|
# @param name [Array<Script::Node>] See \{#args}
|
22
31
|
def initialize(name, args)
|
@@ -1,5 +1,15 @@
|
|
1
1
|
module Sass::Script
|
2
|
+
# A SassScript object representing `#{}` interpolation outside a string.
|
3
|
+
#
|
4
|
+
# @see StringInterpolation
|
2
5
|
class Interpolation < Node
|
6
|
+
# Interpolation in a property is of the form `before #{mid} after`.
|
7
|
+
#
|
8
|
+
# @param before [Node] The SassScript before the interpolation
|
9
|
+
# @param mid [Node] The SassScript within the interpolation
|
10
|
+
# @param after [Node] The SassScript after the interpolation
|
11
|
+
# @param wb [Boolean] Whether there was whitespace between `before` and `#{`
|
12
|
+
# @param wa [Boolean] Whether there was whitespace between `}` and `after`
|
3
13
|
def initialize(before, mid, after, wb, wa)
|
4
14
|
@before = before
|
5
15
|
@mid = mid
|
@@ -8,10 +18,12 @@ module Sass::Script
|
|
8
18
|
@whitespace_after = wa
|
9
19
|
end
|
10
20
|
|
21
|
+
# @return [String] A human-readable s-expression representation of the interpolation
|
11
22
|
def inspect
|
12
23
|
"(interpolation #{@before.inspect} #{@mid.inspect} #{@after.inspect})"
|
13
24
|
end
|
14
25
|
|
26
|
+
# @see Node#to_sass
|
15
27
|
def to_sass(opts = {})
|
16
28
|
res = ""
|
17
29
|
res << @before.to_sass(opts) if @before
|
@@ -22,12 +34,21 @@ module Sass::Script
|
|
22
34
|
res
|
23
35
|
end
|
24
36
|
|
37
|
+
# Returns the three components of the interpolation, `before`, `mid`, and `after`.
|
38
|
+
#
|
39
|
+
# @return [Array<Node>]
|
40
|
+
# @see #initialize
|
41
|
+
# @see Node#children
|
25
42
|
def children
|
26
43
|
[@before, @mid, @after].compact
|
27
44
|
end
|
28
45
|
|
29
46
|
protected
|
30
47
|
|
48
|
+
# Evaluates the interpolation.
|
49
|
+
#
|
50
|
+
# @param environment [Sass::Environment] The environment in which to evaluate the SassScript
|
51
|
+
# @return [Sass::Script::String] The SassScript string that is the value of the interpolation
|
31
52
|
def _perform(environment)
|
32
53
|
res = ""
|
33
54
|
res << @before.perform(environment).to_s if @before
|
data/lib/sass/script/lexer.rb
CHANGED
@@ -40,7 +40,6 @@ module Sass
|
|
40
40
|
attr_reader :offset
|
41
41
|
|
42
42
|
# A hash from operator strings to the corresponding token types.
|
43
|
-
# @private
|
44
43
|
OPERATORS = {
|
45
44
|
'+' => :plus,
|
46
45
|
'-' => :minus,
|
@@ -67,10 +66,8 @@ module Sass
|
|
67
66
|
'{' => :lcurly,
|
68
67
|
}
|
69
68
|
|
70
|
-
# @private
|
71
69
|
OPERATORS_REVERSE = Haml::Util.map_hash(OPERATORS) {|k, v| [v, k]}
|
72
70
|
|
73
|
-
# @private
|
74
71
|
TOKEN_NAMES = Haml::Util.map_hash(OPERATORS_REVERSE) {|k, v| [k, v.inspect]}.merge({
|
75
72
|
:const => "variable (e.g. $foo)",
|
76
73
|
:ident => "identifier (e.g. middle)",
|
@@ -79,22 +76,19 @@ module Sass
|
|
79
76
|
|
80
77
|
# A list of operator strings ordered with longer names first
|
81
78
|
# so that `>` and `<` don't clobber `>=` and `<=`.
|
82
|
-
# @private
|
83
79
|
OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
|
84
80
|
|
85
81
|
# A sub-list of {OP_NAMES} that only includes operators
|
86
82
|
# with identifier names.
|
87
|
-
# @private
|
88
83
|
IDENT_OP_NAMES = OP_NAMES.select {|k, v| k =~ /^\w+/}
|
89
84
|
|
90
85
|
# A hash of regular expressions that are used for tokenizing.
|
91
|
-
# @private
|
92
86
|
REGULAR_EXPRESSIONS = {
|
93
87
|
:whitespace => /\s+/,
|
94
88
|
:comment => COMMENT,
|
95
89
|
:single_line_comment => SINGLE_LINE_COMMENT,
|
96
90
|
:variable => /([!\$])(#{IDENT})/,
|
97
|
-
:ident => IDENT
|
91
|
+
:ident => /(#{IDENT})(\()?/,
|
98
92
|
:number => /(-)?(?:(\d*\.\d+)|(\d+))([a-zA-Z%]+)?/,
|
99
93
|
:color => HEXCOLOR,
|
100
94
|
:bool => /(true|false)\b/,
|
@@ -120,6 +114,8 @@ module Sass
|
|
120
114
|
[:single, false] => string_re("'", "'"),
|
121
115
|
[:double, true] => string_re('', '"'),
|
122
116
|
[:single, true] => string_re('', "'"),
|
117
|
+
[:uri, false] => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|(?=#\{))/,
|
118
|
+
[:uri, true] => /(#{URLCHAR}*?)(#{W}\)|(?=#\{))/,
|
123
119
|
}
|
124
120
|
|
125
121
|
# @param str [String, StringScanner] The source text to lex
|
@@ -179,11 +175,24 @@ module Sass
|
|
179
175
|
@scanner.eos? && @tok.nil?
|
180
176
|
end
|
181
177
|
|
178
|
+
# Raise an error to the effect that `name` was expected in the input stream
|
179
|
+
# and wasn't found.
|
180
|
+
#
|
181
|
+
# This calls \{#unpeek!} to rewind the scanner to immediately after
|
182
|
+
# the last returned token.
|
183
|
+
#
|
184
|
+
# @param name [String] The name of the entity that was expected but not found
|
185
|
+
# @raise [Sass::SyntaxError]
|
182
186
|
def expected!(name)
|
183
187
|
unpeek!
|
184
188
|
Sass::SCSS::Parser.expected(@scanner, name, @line)
|
185
189
|
end
|
186
190
|
|
191
|
+
# Records all non-comment text the lexer consumes within the block
|
192
|
+
# and returns it as a string.
|
193
|
+
#
|
194
|
+
# @yield A block in which text is recorded
|
195
|
+
# @return [String]
|
187
196
|
def str
|
188
197
|
old_pos = @tok ? @tok.pos : @scanner.pos
|
189
198
|
yield
|
@@ -216,8 +225,8 @@ module Sass
|
|
216
225
|
end
|
217
226
|
|
218
227
|
variable || string(:double, false) || string(:single, false) || number ||
|
219
|
-
color || bool ||
|
220
|
-
ident_op || ident || op
|
228
|
+
color || bool || string(:uri, false) || raw(UNICODERANGE) ||
|
229
|
+
special_fun || ident_op || ident || op
|
221
230
|
end
|
222
231
|
|
223
232
|
def variable
|
@@ -236,14 +245,20 @@ module Sass
|
|
236
245
|
end
|
237
246
|
|
238
247
|
def ident
|
239
|
-
return unless
|
240
|
-
[:ident,
|
248
|
+
return unless scan(REGULAR_EXPRESSIONS[:ident])
|
249
|
+
[@scanner[2] ? :funcall : :ident, @scanner[1]]
|
241
250
|
end
|
242
251
|
|
243
252
|
def string(re, open)
|
244
253
|
return unless scan(STRING_REGULAR_EXPRESSIONS[[re, open]])
|
245
254
|
@interpolation_stack << re if @scanner[2].empty? # Started an interpolated section
|
246
|
-
|
255
|
+
str =
|
256
|
+
if re == :uri
|
257
|
+
Script::String.new("#{'url(' unless open}#{@scanner[1]}#{')' unless @scanner[2].empty?}")
|
258
|
+
else
|
259
|
+
Script::String.new(@scanner[1].gsub(/\\(['"]|\#\{)/, '\1'), :string)
|
260
|
+
end
|
261
|
+
[:string, str]
|
247
262
|
end
|
248
263
|
|
249
264
|
def number
|
@@ -269,11 +284,13 @@ module Sass
|
|
269
284
|
return unless str1 = scan(/(calc|expression|progid:[a-z\.]*)\(/i)
|
270
285
|
str2, _ = Haml::Shared.balance(@scanner, ?(, ?), 1)
|
271
286
|
c = str2.count("\n")
|
287
|
+
old_line = @line
|
288
|
+
old_offset = @offset
|
272
289
|
@line += c
|
273
290
|
@offset = (c == 0 ? @offset + str2.size : str2[/\n(.*)/, 1].size)
|
274
291
|
[:special_fun,
|
275
292
|
Haml::Util.merge_adjacent_strings(
|
276
|
-
[str1] + Sass::Engine.parse_interp(str2,
|
293
|
+
[str1] + Sass::Engine.parse_interp(str2, old_line, old_offset, @options)),
|
277
294
|
str1.size + str2.size]
|
278
295
|
end
|
279
296
|
|
data/lib/sass/script/node.rb
CHANGED
data/lib/sass/script/number.rb
CHANGED
@@ -30,6 +30,7 @@ module Sass::Script
|
|
30
30
|
# The precision with which numbers will be printed to CSS files.
|
31
31
|
# For example, if this is `1000.0`,
|
32
32
|
# `3.1415926` will be printed as `3.142`.
|
33
|
+
# @api public
|
33
34
|
PRECISION = 1000.0
|
34
35
|
|
35
36
|
# @param value [Numeric] The value of the number
|
@@ -115,7 +116,7 @@ module Sass::Script
|
|
115
116
|
# @raise [NoMethodError] if `other` is an invalid type
|
116
117
|
def times(other)
|
117
118
|
if other.is_a? Number
|
118
|
-
|
119
|
+
operate(other, :*)
|
119
120
|
elsif other.is_a? Color
|
120
121
|
other.times(self)
|
121
122
|
else
|
@@ -303,7 +304,7 @@ module Sass::Script
|
|
303
304
|
# @return [Boolean] Whether or not this number can be compared with the other.
|
304
305
|
def comparable_to?(other)
|
305
306
|
begin
|
306
|
-
|
307
|
+
operate(other, :+)
|
307
308
|
true
|
308
309
|
rescue Sass::UnitConversionError
|
309
310
|
false
|
@@ -323,7 +324,7 @@ module Sass::Script
|
|
323
324
|
rv
|
324
325
|
end
|
325
326
|
|
326
|
-
|
327
|
+
private
|
327
328
|
|
328
329
|
def operate(other, operation)
|
329
330
|
this = self
|
@@ -381,9 +382,7 @@ module Sass::Script
|
|
381
382
|
end
|
382
383
|
|
383
384
|
# A hash of unit names to their index in the conversion table
|
384
|
-
# @private
|
385
385
|
CONVERTABLE_UNITS = {"in" => 0, "cm" => 1, "pc" => 2, "mm" => 3, "pt" => 4}
|
386
|
-
# @private
|
387
386
|
CONVERSION_TABLE = [[ 1, 2.54, 6, 25.4, 72 ], # in
|
388
387
|
[ nil, 1, 2.36220473, 10, 28.3464567], # cm
|
389
388
|
[ nil, nil, 1, 4.23333333, 12 ], # pc
|
data/lib/sass/script/parser.rb
CHANGED
@@ -120,7 +120,6 @@ module Sass
|
|
120
120
|
new(*args).parse
|
121
121
|
end
|
122
122
|
|
123
|
-
# @private
|
124
123
|
PRECEDENCE = [
|
125
124
|
:comma, :single_eq, :concat, :or, :and,
|
126
125
|
[:eq, :neq],
|
@@ -214,24 +213,24 @@ RUBY
|
|
214
213
|
unary :plus, :unary_minus
|
215
214
|
unary :minus, :unary_div
|
216
215
|
unary :div, :unary_not # For strings, so /foo/bar works
|
217
|
-
unary :not, :
|
216
|
+
unary :not, :ident
|
218
217
|
|
219
|
-
def
|
220
|
-
return
|
218
|
+
def ident
|
219
|
+
return funcall unless @lexer.peek && @lexer.peek.type == :ident
|
221
220
|
return if @stop_at && @stop_at.include?(@lexer.peek.value)
|
222
221
|
|
223
222
|
name = @lexer.next
|
224
|
-
|
225
|
-
|
226
|
-
if color = Color::HTML4_COLORS[name.value]
|
227
|
-
return node(Color.new(color))
|
228
|
-
end
|
229
|
-
node(Script::String.new(name.value, :identifier))
|
230
|
-
else
|
231
|
-
args = fn_arglist || []
|
232
|
-
assert_tok(:rparen)
|
233
|
-
node(Script::Funcall.new(name.value, args))
|
223
|
+
if color = Color::HTML4_COLORS[name.value]
|
224
|
+
return node(Color.new(color))
|
234
225
|
end
|
226
|
+
node(Script::String.new(name.value, :identifier))
|
227
|
+
end
|
228
|
+
|
229
|
+
def funcall
|
230
|
+
return raw unless tok = try_tok(:funcall)
|
231
|
+
args = fn_arglist || []
|
232
|
+
assert_tok(:rparen)
|
233
|
+
node(Script::Funcall.new(tok.value, args))
|
235
234
|
end
|
236
235
|
|
237
236
|
def defn_arglist!(must_have_default)
|
data/lib/sass/script/string.rb
CHANGED
@@ -15,6 +15,10 @@ module Sass::Script
|
|
15
15
|
# @return [Symbol] `:string` or `:identifier`
|
16
16
|
attr_reader :type
|
17
17
|
|
18
|
+
# In addition to setting the \{#context} of the string,
|
19
|
+
# this sets the string to be an identifier if the context is `:equals`.
|
20
|
+
#
|
21
|
+
# @see Node#context=
|
18
22
|
def context=(context)
|
19
23
|
super
|
20
24
|
@type = :identifier if context == :equals
|
@@ -29,6 +33,7 @@ module Sass::Script
|
|
29
33
|
@type = type
|
30
34
|
end
|
31
35
|
|
36
|
+
# @see Literal#plus
|
32
37
|
def plus(other)
|
33
38
|
other_str = other.is_a?(Sass::Script::String) ? other.value : other.to_s
|
34
39
|
Sass::Script::String.new(self.value + other_str, self.type)
|
@@ -47,12 +52,13 @@ module Sass::Script
|
|
47
52
|
def to_sass(opts = {})
|
48
53
|
type = opts[:type] || self.type
|
49
54
|
if type == :identifier
|
50
|
-
if context == :equals && Sass::SCSS::RX
|
55
|
+
if context == :equals && self.value !~ Sass::SCSS::RX::URI &&
|
56
|
+
Sass::SCSS::RX.escape_ident(self.value).include?(?\\)
|
51
57
|
return "unquote(#{Sass::Script::String.new(self.value, :string).to_sass})"
|
52
58
|
elsif context == :equals && self.value.size == 0
|
53
59
|
return %q{""}
|
54
60
|
end
|
55
|
-
return self.value
|
61
|
+
return self.value.gsub("\n", " ")
|
56
62
|
end
|
57
63
|
|
58
64
|
return "\"#{value.gsub('"', "\\\"")}\"" if opts[:quote] == %q{"}
|