haml 3.1.0.alpha.19 → 3.1.0.alpha.22
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/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/haml/precompiler.rb +1 -0
- data/lib/haml/template/plugin.rb +16 -6
- data/vendor/sass/doc-src/SASS_CHANGELOG.md +41 -0
- data/vendor/sass/doc-src/SASS_REFERENCE.md +37 -6
- data/vendor/sass/lib/sass.rb +7 -3
- data/vendor/sass/lib/sass/engine.rb +4 -4
- data/vendor/sass/lib/sass/environment.rb +24 -15
- data/vendor/sass/lib/sass/less.rb +31 -12
- data/vendor/sass/lib/sass/plugin/staleness_checker.rb +1 -1
- data/vendor/sass/lib/sass/script/funcall.rb +51 -9
- data/vendor/sass/lib/sass/script/functions.rb +189 -57
- data/vendor/sass/lib/sass/script/node.rb +7 -1
- data/vendor/sass/lib/sass/script/number.rb +21 -15
- data/vendor/sass/lib/sass/script/operation.rb +10 -5
- data/vendor/sass/lib/sass/script/parser.rb +61 -17
- data/vendor/sass/lib/sass/script/string.rb +2 -3
- data/vendor/sass/lib/sass/script/variable.rb +6 -0
- data/vendor/sass/lib/sass/scss/parser.rb +8 -5
- data/vendor/sass/lib/sass/selector/sequence.rb +2 -2
- data/vendor/sass/lib/sass/tree/mixin_node.rb +25 -5
- data/vendor/sass/lib/sass/tree/node.rb +2 -2
- data/vendor/sass/lib/sass/tree/prop_node.rb +9 -6
- data/vendor/sass/lib/sass/tree/rule_node.rb +9 -8
- data/vendor/sass/lib/sass/util.rb +5 -3
- data/vendor/sass/test/sass/conversion_test.rb +14 -0
- data/vendor/sass/test/sass/engine_test.rb +85 -0
- data/vendor/sass/test/sass/functions_test.rb +89 -0
- data/vendor/sass/test/sass/less_conversion_test.rb +24 -3
- data/vendor/sass/test/sass/script_conversion_test.rb +65 -0
- data/vendor/sass/test/sass/scss/scss_test.rb +63 -0
- metadata +2 -2
data/EDGE_GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.0.alpha.
|
1
|
+
3.1.0.alpha.22
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.0.alpha.
|
1
|
+
3.1.0.alpha.22
|
data/lib/haml/precompiler.rb
CHANGED
data/lib/haml/template/plugin.rb
CHANGED
@@ -2,12 +2,17 @@
|
|
2
2
|
# using the > 2.0.1 template handler API.
|
3
3
|
|
4
4
|
module Haml
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
defined?(ActionView::Template
|
5
|
+
# In Rails 3.1+, template handlers don't inherit from anything. In <= 3.0, they do.
|
6
|
+
# To avoid messy logic figuring this out, we just inherit from whatever the ERB handler does.
|
7
|
+
class Plugin < Haml::Util.av_template_class(:Handlers)::ERB.superclass
|
8
|
+
if ((defined?(ActionView::TemplateHandlers) &&
|
9
|
+
defined?(ActionView::TemplateHandlers::Compilable)) ||
|
10
|
+
(defined?(ActionView::Template) &&
|
11
|
+
defined?(ActionView::Template::Handlers) &&
|
12
|
+
defined?(ActionView::Template::Handlers::Compilable))) &&
|
13
|
+
# In Rails 3.1+, we don't need to include Compilable.
|
14
|
+
Haml::Util.av_template_class(:Handlers)::ERB.include?(
|
15
|
+
Haml::Util.av_template_class(:Handlers)::Compilable)
|
11
16
|
include Haml::Util.av_template_class(:Handlers)::Compilable
|
12
17
|
end
|
13
18
|
|
@@ -29,6 +34,11 @@ module Haml
|
|
29
34
|
Haml::Engine.new(source, options).send(:precompiled_with_ambles, [])
|
30
35
|
end
|
31
36
|
|
37
|
+
# In Rails 3.1+, #call takes the place of #compile
|
38
|
+
def self.call(template)
|
39
|
+
new.compile(template)
|
40
|
+
end
|
41
|
+
|
32
42
|
def cache_fragment(block, name = {}, options = nil)
|
33
43
|
@view.fragment_for(block, name, options) do
|
34
44
|
eval("_hamlout.buffer", block.binding)
|
@@ -7,6 +7,37 @@
|
|
7
7
|
|
8
8
|
* Add an {Sass::Script::Functions#invert `invert` function} that takes the inverse of colors.
|
9
9
|
|
10
|
+
* Many performance optimizations have been made by [thedarkone](http://github.com/thedarkone).
|
11
|
+
|
12
|
+
### Keyword Arguments
|
13
|
+
|
14
|
+
Both mixins and Sass functions now support the ability to pass in keyword arguments.
|
15
|
+
For example, with mixins:
|
16
|
+
|
17
|
+
@mixin border-radius($value, $moz: true, $webkit: true, $css3: true) {
|
18
|
+
@if $moz { -moz-border-radius: $value }
|
19
|
+
@if $webkit { -webkit-border-radius: $value }
|
20
|
+
@if $css3 { border-radius: $value }
|
21
|
+
}
|
22
|
+
|
23
|
+
@include border-radius(10px, $webkit: false);
|
24
|
+
|
25
|
+
And with functions:
|
26
|
+
|
27
|
+
p {
|
28
|
+
color: hsl($hue: 180, $saturation: 78%, lightness: 57%);
|
29
|
+
}
|
30
|
+
|
31
|
+
Keyword arguments are of the form `$name: value` and come after normal arguments.
|
32
|
+
They can be used for either optional or required arguments.
|
33
|
+
For mixins, the names are the same as the argument names for the mixins.
|
34
|
+
For functions, the names are defined along with the functions.
|
35
|
+
The argument names for the built-in functions are listed
|
36
|
+
{Sass::Script::Functions in the function documentation}.
|
37
|
+
|
38
|
+
Sass functions defined in Ruby can use the {Sass::Script::Functions.declare} method
|
39
|
+
to declare the names of the arguments they take.
|
40
|
+
|
10
41
|
### Backwards Incompatibilities -- Must Read!
|
11
42
|
|
12
43
|
* When `@import` is given a path without `.sass`, `.scss`, or `.css` extension,
|
@@ -18,6 +49,16 @@
|
|
18
49
|
This flag hasn't been necessary since Rails 2.0.
|
19
50
|
Existing Rails 2.0 installations will continue to work.
|
20
51
|
|
52
|
+
## 3.0.22
|
53
|
+
|
54
|
+
[Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.22).
|
55
|
+
|
56
|
+
* Remove `vendor/sass`, which snuck into the gem by mistake
|
57
|
+
and was causing trouble for Heroku users (thanks to [Jacques Crocker](http://railsjedi.com/)).
|
58
|
+
|
59
|
+
* `sass-convert` now understands better when it's acceptable
|
60
|
+
to remove parentheses from expressions.
|
61
|
+
|
21
62
|
## 3.0.21
|
22
63
|
|
23
64
|
[Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.21).
|
@@ -275,8 +275,9 @@ Available options are:
|
|
275
275
|
This is useful to set if the Sass template is embedded in a Ruby file.
|
276
276
|
|
277
277
|
{#load_paths-option} `:load_paths`
|
278
|
-
: An array of filesystem paths which should be searched
|
278
|
+
: An array of filesystem paths or importers which should be searched
|
279
279
|
for Sass templates imported with the [`@import`](#import) directive.
|
280
|
+
These may be strings, `Pathname` objects, or subclasses of {Sass::Importers::Base}.
|
280
281
|
This defaults to the working directory and, in Rack, Rails, or Merb,
|
281
282
|
whatever `:template_location` is.
|
282
283
|
|
@@ -851,7 +852,7 @@ SassScript defines some useful functions
|
|
851
852
|
that are called using the normal CSS function syntax:
|
852
853
|
|
853
854
|
p {
|
854
|
-
color: hsl(0, 100%,
|
855
|
+
color: hsl(0, 100%, 50%);
|
855
856
|
}
|
856
857
|
|
857
858
|
is compiled to:
|
@@ -859,7 +860,23 @@ is compiled to:
|
|
859
860
|
p {
|
860
861
|
color: #ff0000; }
|
861
862
|
|
862
|
-
|
863
|
+
#### Keyword Arguments
|
864
|
+
|
865
|
+
Sass functions can also be called using explicit keyword arguments.
|
866
|
+
The above example can also be written as:
|
867
|
+
|
868
|
+
p {
|
869
|
+
color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
|
870
|
+
}
|
871
|
+
|
872
|
+
While this is less concise, it can make the stylesheet easier to read.
|
873
|
+
It also allows functions to present more flexible interfaces,
|
874
|
+
providing many arguments without becoming difficult to call.
|
875
|
+
|
876
|
+
Named arguments can be passed in any order, and arguments with default values can be omitted.
|
877
|
+
Since the named arguments are variable names, underscores and dashes can be used interchangeably.
|
878
|
+
|
879
|
+
See {Sass::Script::Functions} for a full listing of Sass functions and their argument names,
|
863
880
|
as well as instructions on defining your own in Ruby.
|
864
881
|
|
865
882
|
### Interpolation: `#{}` {#interpolation_}
|
@@ -1591,6 +1608,21 @@ is compiled to:
|
|
1591
1608
|
border-width: 2in;
|
1592
1609
|
border-style: dashed; }
|
1593
1610
|
|
1611
|
+
#### Keyword Arguments
|
1612
|
+
|
1613
|
+
Mixins can also be included using explicit keyword arguments.
|
1614
|
+
For instance, we the above example could be written as:
|
1615
|
+
|
1616
|
+
p { @include sexy-border($color: blue); }
|
1617
|
+
h1 { @include sexy-border($color: blue, $width: 2in); }
|
1618
|
+
|
1619
|
+
While this is less concise, it can make the stylesheet easier to read.
|
1620
|
+
It also allows functions to present more flexible interfaces,
|
1621
|
+
providing many arguments without becoming difficult to call.
|
1622
|
+
|
1623
|
+
Named arguments can be passed in any order, and arguments with default values can be omitted.
|
1624
|
+
Since the named arguments are variable names, underscores and dashes can be used interchangeably.
|
1625
|
+
|
1594
1626
|
## Output Style
|
1595
1627
|
|
1596
1628
|
Although the default CSS style that Sass outputs is very nice
|
@@ -1682,9 +1714,8 @@ Using these features requires a strong understanding of Ruby.
|
|
1682
1714
|
|
1683
1715
|
### Defining Custom Sass Functions
|
1684
1716
|
|
1685
|
-
|
1686
|
-
|
1687
|
-
documentation](/docs/yardoc/Sass/Script/Functions.html#adding_custom_functions).
|
1717
|
+
Users can define their own Sass functions using the Ruby API.
|
1718
|
+
For more information, see the [source documentation](Sass/Script/Functions.html#adding_custom_functions).
|
1688
1719
|
|
1689
1720
|
### Cache Stores
|
1690
1721
|
|
data/vendor/sass/lib/sass.rb
CHANGED
@@ -43,17 +43,21 @@ module Sass
|
|
43
43
|
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
44
44
|
#
|
45
45
|
# @overload compile_file(filename, options = {})
|
46
|
+
# Return the compiled CSS rather than writing it to a file.
|
47
|
+
#
|
46
48
|
# @return [String] The compiled CSS.
|
47
49
|
#
|
48
50
|
# @overload compile_file(filename, css_filename, options = {})
|
51
|
+
# Write the compiled CSS to a file.
|
52
|
+
#
|
49
53
|
# @param css_filename [String] The location to which to write the compiled CSS.
|
50
54
|
def self.compile_file(filename, *args)
|
51
55
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
52
|
-
css_filename
|
53
|
-
options[:css_filename] = css_filename
|
56
|
+
css_filename = args.shift
|
54
57
|
result = Sass::Engine.for_file(filename, options).render
|
55
58
|
if css_filename
|
56
|
-
|
59
|
+
options[:css_filename] ||= css_filename
|
60
|
+
open(css_filename,"w") {|css_file| css_file.write(result)}
|
57
61
|
nil
|
58
62
|
else
|
59
63
|
result
|
@@ -158,8 +158,8 @@ module Sass
|
|
158
158
|
options[:line_comments] ||= options[:line_numbers]
|
159
159
|
|
160
160
|
options[:load_paths] = options[:load_paths].map do |p|
|
161
|
-
next p unless p.is_a?(String)
|
162
|
-
options[:filesystem_importer].new(p)
|
161
|
+
next p unless p.is_a?(String) || (defined?(Pathname) && p.is_a?(Pathname))
|
162
|
+
options[:filesystem_importer].new(p.to_s)
|
163
163
|
end
|
164
164
|
|
165
165
|
# Backwards compatibility
|
@@ -731,11 +731,11 @@ WARNING
|
|
731
731
|
raise SyntaxError.new("Invalid mixin include \"#{line.text}\".") if name.nil?
|
732
732
|
|
733
733
|
offset = line.offset + line.text.size - arg_string.size
|
734
|
-
args = Script::Parser.new(arg_string.strip, @line, offset, @options).
|
734
|
+
args, keywords = Script::Parser.new(arg_string.strip, @line, offset, @options).
|
735
735
|
parse_mixin_include_arglist
|
736
736
|
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath mixin directives.",
|
737
737
|
:line => @line + 1) unless line.children.empty?
|
738
|
-
Tree::MixinNode.new(name, args)
|
738
|
+
Tree::MixinNode.new(name, args, keywords)
|
739
739
|
end
|
740
740
|
|
741
741
|
def parse_script(script, options = {})
|
@@ -22,12 +22,12 @@ module Sass
|
|
22
22
|
|
23
23
|
# @param parent [Environment] See \{#parent}
|
24
24
|
def initialize(parent = nil)
|
25
|
-
@vars = {}
|
26
|
-
@mixins = {}
|
27
25
|
@parent = parent
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
unless parent
|
27
|
+
@stack = []
|
28
|
+
@mixins_in_use = Set.new
|
29
|
+
set_var("important", Script::String.new("!important"))
|
30
|
+
end
|
31
31
|
end
|
32
32
|
|
33
33
|
# The options hash.
|
@@ -35,7 +35,7 @@ module Sass
|
|
35
35
|
#
|
36
36
|
# @return [{Symbol => Object}]
|
37
37
|
def options
|
38
|
-
@options ||
|
38
|
+
@options || parent_options || {}
|
39
39
|
end
|
40
40
|
|
41
41
|
# Push a new stack frame onto the mixin/include stack.
|
@@ -53,13 +53,13 @@ module Sass
|
|
53
53
|
# `:line`
|
54
54
|
# : The line of the file on which the lexical scope changed. Never nil.
|
55
55
|
def push_frame(frame_info)
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
top_of_stack = stack.last
|
57
|
+
if top_of_stack && top_of_stack.delete(:prepared)
|
58
|
+
top_of_stack.merge!(frame_info)
|
59
59
|
else
|
60
|
-
stack.push(frame_info)
|
60
|
+
stack.push(top_of_stack = frame_info)
|
61
61
|
end
|
62
|
-
mixins_in_use <<
|
62
|
+
mixins_in_use << top_of_stack[:mixin] if top_of_stack[:mixin] && !top_of_stack[:prepared]
|
63
63
|
end
|
64
64
|
|
65
65
|
# Like \{#push\_frame}, but next time a stack frame is pushed,
|
@@ -93,28 +93,36 @@ module Sass
|
|
93
93
|
@mixins_in_use ||= @parent.mixins_in_use
|
94
94
|
end
|
95
95
|
|
96
|
+
private
|
97
|
+
|
98
|
+
def parent_options
|
99
|
+
@parent_options ||= @parent && @parent.options
|
100
|
+
end
|
101
|
+
|
96
102
|
class << self
|
97
103
|
private
|
104
|
+
UNDERSCORE, DASH = '_', '-'
|
98
105
|
|
99
106
|
# Note: when updating this,
|
100
107
|
# update sass/yard/inherited_hash.rb as well.
|
101
108
|
def inherited_hash(name)
|
102
109
|
class_eval <<RUBY, __FILE__, __LINE__ + 1
|
103
110
|
def #{name}(name)
|
104
|
-
_#{name}(name.
|
111
|
+
_#{name}(name.tr(UNDERSCORE, DASH))
|
105
112
|
end
|
106
113
|
|
107
114
|
def _#{name}(name)
|
108
|
-
@#{name}s[name] || @parent && @parent._#{name}(name)
|
115
|
+
(@#{name}s && @#{name}s[name]) || @parent && @parent._#{name}(name)
|
109
116
|
end
|
110
117
|
protected :_#{name}
|
111
118
|
|
112
119
|
def set_#{name}(name, value)
|
113
|
-
name = name.
|
120
|
+
name = name.tr(UNDERSCORE, DASH)
|
114
121
|
@#{name}s[name] = value unless try_set_#{name}(name, value)
|
115
122
|
end
|
116
123
|
|
117
124
|
def try_set_#{name}(name, value)
|
125
|
+
@#{name}s ||= {}
|
118
126
|
if @#{name}s.include?(name)
|
119
127
|
@#{name}s[name] = value
|
120
128
|
true
|
@@ -127,7 +135,8 @@ module Sass
|
|
127
135
|
protected :try_set_#{name}
|
128
136
|
|
129
137
|
def set_local_#{name}(name, value)
|
130
|
-
@#{name}s
|
138
|
+
@#{name}s ||= {}
|
139
|
+
@#{name}s[name.tr(UNDERSCORE, DASH)] = value
|
131
140
|
end
|
132
141
|
RUBY
|
133
142
|
end
|
@@ -246,24 +246,43 @@ WARNING
|
|
246
246
|
private
|
247
247
|
|
248
248
|
LESS_TO_SASS_OPERATORS = {"-" => :minus, "+" => :plus, "*" => :times, "/" => :div, "=" => :single_eq}
|
249
|
+
|
249
250
|
def _to_sass_tree(arr)
|
250
|
-
|
251
|
-
|
251
|
+
e, rest = _to_sass_tree_plus_minus_eq(arr)
|
252
|
+
until rest.empty?
|
253
|
+
e2, rest = _to_sass_tree_plus_minus_eq(rest)
|
254
|
+
e = Sass::Script::Operation.new(e, e2, :concat)
|
255
|
+
end
|
256
|
+
return e
|
252
257
|
end
|
253
258
|
|
254
|
-
def
|
255
|
-
|
256
|
-
|
259
|
+
def _to_sass_tree_plus_minus_eq(arr)
|
260
|
+
e, rest = _to_sass_tree_times_div(arr)
|
261
|
+
while rest[0] && rest[0].is_a?(Operator) && %w[+ - =].include?(rest[0])
|
257
262
|
op = LESS_TO_SASS_OPERATORS[rest[0]]
|
258
|
-
|
259
|
-
|
260
|
-
return _to_sass_tree2(Sass::Script::Operation.new(first, second, op), rest)
|
261
|
-
else
|
262
|
-
return Sass::Script::Operation.new(first, _to_sass_tree(rest[1..-1]), op)
|
263
|
-
end
|
263
|
+
e2, rest = _to_sass_tree_times_div(rest[1..-1])
|
264
|
+
e = Sass::Script::Operation.new(e, e2, op)
|
264
265
|
end
|
266
|
+
return e, rest
|
267
|
+
end
|
265
268
|
|
266
|
-
|
269
|
+
def _to_sass_tree_times_div(arr)
|
270
|
+
e, rest = _to_sass_tree_unary(arr)
|
271
|
+
while rest[0] && rest[0].is_a?(Operator) && %w[* /].include?(rest[0])
|
272
|
+
op = LESS_TO_SASS_OPERATORS[rest[0]]
|
273
|
+
e2, rest = _to_sass_tree_unary(rest[1..-1])
|
274
|
+
e = Sass::Script::Operation.new(e, e2, op)
|
275
|
+
end
|
276
|
+
return e, rest
|
277
|
+
end
|
278
|
+
|
279
|
+
def _to_sass_tree_unary(arr)
|
280
|
+
if arr[0] == "-"
|
281
|
+
first, rest = _sass_split(arr[1..-1])
|
282
|
+
return Sass::Script::UnaryOperation.new(first, :minus), rest
|
283
|
+
else
|
284
|
+
return _sass_split(arr[0..-1])
|
285
|
+
end
|
267
286
|
end
|
268
287
|
|
269
288
|
def _sass_split(arr)
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require 'sass/script/functions'
|
2
|
+
|
2
3
|
module Sass
|
3
4
|
module Script
|
4
5
|
# A SassScript parse node representing a function call.
|
@@ -17,6 +18,11 @@ module Sass
|
|
17
18
|
# @return [Array<Script::Node>]
|
18
19
|
attr_reader :args
|
19
20
|
|
21
|
+
# The keyword arguments to the function.
|
22
|
+
#
|
23
|
+
# @return [{String => Script::Node}]
|
24
|
+
attr_reader :keywords
|
25
|
+
|
20
26
|
# Don't set the context for child nodes if this is `url()`,
|
21
27
|
# since `url()` allows quoted strings.
|
22
28
|
#
|
@@ -27,21 +33,29 @@ module Sass
|
|
27
33
|
end
|
28
34
|
|
29
35
|
# @param name [String] See \{#name}
|
30
|
-
# @param
|
31
|
-
|
36
|
+
# @param args [Array<Script::Node>] See \{#args}
|
37
|
+
# @param keywords [{String => Script::Node}] See \{#keywords}
|
38
|
+
def initialize(name, args, keywords)
|
32
39
|
@name = name
|
33
40
|
@args = args
|
41
|
+
@keywords = keywords
|
34
42
|
super()
|
35
43
|
end
|
36
44
|
|
37
45
|
# @return [String] A string representation of the function call
|
38
46
|
def inspect
|
39
|
-
|
47
|
+
args = @args.map {|a| a.inspect}.join(', ')
|
48
|
+
keywords = @keywords.sort_by {|k, v| k}.
|
49
|
+
map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
|
50
|
+
"#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
|
40
51
|
end
|
41
52
|
|
42
53
|
# @see Node#to_sass
|
43
54
|
def to_sass(opts = {})
|
44
|
-
|
55
|
+
args = @args.map {|a| a.to_sass(opts)}.join(', ')
|
56
|
+
keywords = @keywords.sort_by {|k, v| k}.
|
57
|
+
map {|k, v| "$#{dasherize(k, opts)}: #{v.to_sass(opts)}"}.join(', ')
|
58
|
+
"#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
|
45
59
|
end
|
46
60
|
|
47
61
|
# Returns the arguments to the function.
|
@@ -49,7 +63,7 @@ module Sass
|
|
49
63
|
# @return [Array<Node>]
|
50
64
|
# @see Node#children
|
51
65
|
def children
|
52
|
-
@args
|
66
|
+
@args + @keywords.values
|
53
67
|
end
|
54
68
|
|
55
69
|
protected
|
@@ -60,10 +74,13 @@ module Sass
|
|
60
74
|
# @return [Literal] The SassScript object that is the value of the function call
|
61
75
|
# @raise [Sass::SyntaxError] if the function call raises an ArgumentError
|
62
76
|
def _perform(environment)
|
63
|
-
args =
|
64
|
-
|
77
|
+
args = @args.map {|a| a.perform(environment)}
|
78
|
+
keywords = Sass::Util.map_hash(@keywords) {|k, v| [k, v.perform(environment)]}
|
79
|
+
ruby_name = @name.tr('-', '_')
|
80
|
+
args = construct_ruby_args(ruby_name, args, keywords)
|
81
|
+
|
65
82
|
unless Sass::Util.has?(:public_instance_method, Functions, ruby_name) && ruby_name !~ /^__/
|
66
|
-
opts(Script::String.new("#{name}(#{args.
|
83
|
+
opts(Script::String.new("#{name}(#{args.join(', ')})"))
|
67
84
|
else
|
68
85
|
opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *args))
|
69
86
|
end
|
@@ -71,6 +88,31 @@ module Sass
|
|
71
88
|
raise e unless e.backtrace.any? {|t| t =~ /:in `(block in )?(#{name}|perform)'$/}
|
72
89
|
raise Sass::SyntaxError.new("#{e.message} for `#{name}'")
|
73
90
|
end
|
91
|
+
|
92
|
+
def construct_ruby_args(name, args, keywords)
|
93
|
+
return args if keywords.empty?
|
94
|
+
unless signature = Functions.signature(name.to_sym, args.size, keywords.size)
|
95
|
+
raise Sass::SyntaxError.new("Function #{name} doesn't support keyword arguments")
|
96
|
+
end
|
97
|
+
|
98
|
+
args = args + signature.args[args.size..-1].map do |argname|
|
99
|
+
if keywords.has_key?(argname)
|
100
|
+
keywords.delete(argname)
|
101
|
+
else
|
102
|
+
raise Sass::SyntaxError, "Function #{name} requires an argument named $#{argname}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if keywords.size > 0
|
107
|
+
if signature.var_kwargs
|
108
|
+
args << Sass::Util.map_hash(keywords) {|k, v| [k.to_sym, v]}
|
109
|
+
else
|
110
|
+
raise Sass::SyntaxError, "Function #{name} doesn't take an argument named $#{keywords.keys.sort.first}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
args
|
115
|
+
end
|
74
116
|
end
|
75
117
|
end
|
76
118
|
end
|