sass 3.4.25 → 3.5.0.pre.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/README.md +1 -1
- data/Rakefile +13 -157
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass.rb +3 -10
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +2 -3
- data/lib/sass/engine.rb +46 -32
- data/lib/sass/environment.rb +27 -6
- data/lib/sass/error.rb +5 -5
- data/lib/sass/exec/base.rb +3 -12
- data/lib/sass/features.rb +1 -0
- data/lib/sass/importers/filesystem.rb +2 -2
- data/lib/sass/plugin.rb +1 -1
- data/lib/sass/plugin/compiler.rb +21 -51
- data/lib/sass/plugin/configuration.rb +1 -1
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/staleness_checker.rb +3 -3
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/script/functions.rb +238 -47
- data/lib/sass/script/lexer.rb +8 -6
- data/lib/sass/script/parser.rb +76 -75
- data/lib/sass/script/tree/funcall.rb +35 -30
- data/lib/sass/script/tree/list_literal.rb +23 -8
- data/lib/sass/script/tree/map_literal.rb +2 -2
- data/lib/sass/script/tree/node.rb +2 -10
- data/lib/sass/script/tree/operation.rb +16 -50
- data/lib/sass/script/value.rb +2 -0
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +20 -3
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +10 -10
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +16 -7
- data/lib/sass/script/value/list.rb +33 -12
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +3 -3
- data/lib/sass/script/value/string.rb +12 -5
- data/lib/sass/scss/parser.rb +101 -45
- data/lib/sass/scss/rx.rb +5 -11
- data/lib/sass/scss/static_parser.rb +0 -7
- data/lib/sass/selector.rb +4 -0
- data/lib/sass/selector/abstract_sequence.rb +5 -5
- data/lib/sass/selector/comma_sequence.rb +3 -15
- data/lib/sass/selector/pseudo.rb +4 -0
- data/lib/sass/selector/sequence.rb +30 -3
- data/lib/sass/selector/simple.rb +13 -7
- data/lib/sass/selector/simple_sequence.rb +1 -1
- data/lib/sass/shared.rb +3 -5
- data/lib/sass/source/map.rb +4 -4
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +21 -1
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/node.rb +3 -3
- data/lib/sass/tree/prop_node.rb +46 -54
- data/lib/sass/tree/rule_node.rb +7 -15
- data/lib/sass/tree/visitors/check_nesting.rb +1 -1
- data/lib/sass/tree/visitors/convert.rb +2 -3
- data/lib/sass/tree/visitors/cssize.rb +1 -10
- data/lib/sass/tree/visitors/deep_copy.rb +2 -2
- data/lib/sass/tree/visitors/perform.rb +23 -12
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +46 -12
- data/lib/sass/util.rb +16 -321
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/version.rb +2 -2
- data/test/sass-spec.yml +1 -1
- data/test/sass/compiler_test.rb +4 -14
- data/test/sass/conversion_test.rb +113 -162
- data/test/sass/css2sass_test.rb +17 -19
- data/test/sass/css_variable_test.rb +176 -70
- data/test/sass/encoding_test.rb +2 -32
- data/test/sass/engine_test.rb +114 -65
- data/test/sass/extend_test.rb +37 -51
- data/test/sass/functions_test.rb +57 -15
- data/test/sass/importer_test.rb +2 -2
- data/test/sass/more_templates/more1.sass +10 -10
- data/test/sass/more_templates/more_import.sass +2 -2
- data/test/sass/plugin_test.rb +9 -12
- data/test/sass/script_conversion_test.rb +9 -0
- data/test/sass/script_test.rb +38 -48
- data/test/sass/scss/css_test.rb +5 -19
- data/test/sass/scss/scss_test.rb +58 -39
- data/test/sass/source_map_test.rb +26 -28
- data/test/sass/templates/_partial.sass +1 -1
- data/test/sass/templates/basic.sass +10 -10
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/bork5.sass +1 -1
- data/test/sass/templates/compact.sass +10 -10
- data/test/sass/templates/complex.sass +187 -187
- data/test/sass/templates/compressed.sass +10 -10
- data/test/sass/templates/expanded.sass +10 -10
- data/test/sass/templates/import.sass +2 -2
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/mixins.sass +22 -22
- data/test/sass/templates/multiline.sass +4 -4
- data/test/sass/templates/nested.sass +13 -13
- data/test/sass/templates/parent_ref.sass +12 -12
- data/test/sass/templates/script.sass +70 -70
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
- data/test/sass/templates/subdir/subdir.sass +3 -3
- data/test/sass/templates/units.sass +10 -10
- data/test/sass/util/multibyte_string_scanner_test.rb +139 -149
- data/test/sass/util_test.rb +0 -36
- data/test/test_helper.rb +39 -0
- metadata +30 -57
- data/extra/sass-spec-ref.sh +0 -32
- data/lib/sass/deprecation.rb +0 -55
- data/lib/sass/script/css_variable_warning.rb +0 -52
- data/lib/sass/util/cross_platform_random.rb +0 -19
- data/lib/sass/util/ordered_hash.rb +0 -192
- data/test/sass/results/import_charset_1_8.css +0 -5
- data/test/sass/templates/import_charset_1_8.sass +0 -6
- data/vendor/listen/CHANGELOG.md +0 -1
- data/vendor/listen/CONTRIBUTING.md +0 -38
- data/vendor/listen/Gemfile +0 -20
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/LICENSE +0 -20
- data/vendor/listen/README.md +0 -349
- data/vendor/listen/Rakefile +0 -5
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen.rb +0 -54
- data/vendor/listen/lib/listen/adapter.rb +0 -327
- data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
- data/vendor/listen/lib/listen/directory_record.rb +0 -406
- data/vendor/listen/lib/listen/listener.rb +0 -323
- data/vendor/listen/lib/listen/turnstile.rb +0 -32
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/listen.gemspec +0 -28
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
- data/vendor/listen/spec/listen/listener_spec.rb +0 -258
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -67
- data/vendor/listen/spec/spec_helper.rb +0 -25
- data/vendor/listen/spec/support/adapter_helper.rb +0 -666
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -179
- data/vendor/listen/spec/support/platform_helper.rb +0 -15
data/lib/sass/environment.rb
CHANGED
@@ -81,7 +81,7 @@ module Sass
|
|
81
81
|
inherited_hash_reader :function
|
82
82
|
|
83
83
|
# @param options [{Symbol => Object}] The options hash. See
|
84
|
-
# {file:SASS_REFERENCE.md#
|
84
|
+
# {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
85
85
|
# @param parent [Environment] See \{#parent}
|
86
86
|
def initialize(parent = nil, options = nil)
|
87
87
|
@parent = parent
|
@@ -175,6 +175,10 @@ module Sass
|
|
175
175
|
|
176
176
|
# A read-only wrapper for a lexical environment for SassScript.
|
177
177
|
class ReadOnlyEnvironment < BaseEnvironment
|
178
|
+
def initialize(parent = nil, options = nil)
|
179
|
+
super
|
180
|
+
@content_cached = nil
|
181
|
+
end
|
178
182
|
# The read-only environment of the caller of this environment's mixin or function.
|
179
183
|
#
|
180
184
|
# @see BaseEnvironment#caller
|
@@ -185,14 +189,31 @@ module Sass
|
|
185
189
|
@caller ||= env.is_a?(ReadOnlyEnvironment) ? env : ReadOnlyEnvironment.new(env, env.options)
|
186
190
|
end
|
187
191
|
|
188
|
-
# The
|
192
|
+
# The content passed to this environment. If the content's environment isn't already
|
193
|
+
# read-only, it's made read-only.
|
189
194
|
#
|
190
195
|
# @see BaseEnvironment#content
|
191
|
-
#
|
196
|
+
#
|
197
|
+
# @return {[Array<Sass::Tree::Node>, ReadOnlyEnvironment]?} The content nodes and
|
198
|
+
# the lexical environment of the content block.
|
199
|
+
# Returns `nil` when there is no content in this environment.
|
192
200
|
def content
|
193
|
-
|
194
|
-
|
195
|
-
|
201
|
+
# Return the cached content from a previous invocation if any
|
202
|
+
return @content if @content_cached
|
203
|
+
# get the content with a read-write environment from the superclass
|
204
|
+
read_write_content = super
|
205
|
+
if read_write_content
|
206
|
+
tree, env = read_write_content
|
207
|
+
# make the content's environment read-only
|
208
|
+
if env && !env.is_a?(ReadOnlyEnvironment)
|
209
|
+
env = ReadOnlyEnvironment.new(env, env.options)
|
210
|
+
end
|
211
|
+
@content_cached = true
|
212
|
+
@content = [tree, env]
|
213
|
+
else
|
214
|
+
@content_cached = true
|
215
|
+
@content = nil
|
216
|
+
end
|
196
217
|
end
|
197
218
|
end
|
198
219
|
|
data/lib/sass/error.rb
CHANGED
@@ -69,14 +69,14 @@ module Sass
|
|
69
69
|
# The name of the mixin in which the error occurred.
|
70
70
|
# This could be `nil` if the error occurred outside a mixin.
|
71
71
|
#
|
72
|
-
# @return [
|
72
|
+
# @return [Fixnum]
|
73
73
|
def sass_mixin
|
74
74
|
sass_backtrace.first[:mixin]
|
75
75
|
end
|
76
76
|
|
77
77
|
# The line of the Sass template on which the error occurred.
|
78
78
|
#
|
79
|
-
# @return [
|
79
|
+
# @return [Fixnum]
|
80
80
|
def sass_line
|
81
81
|
sass_backtrace.first[:line]
|
82
82
|
end
|
@@ -142,7 +142,7 @@ module Sass
|
|
142
142
|
msg = lines[0] + lines[1..-1].
|
143
143
|
map {|l| "\n" + (" " * "Error: ".size) + l}.join
|
144
144
|
"Error: #{msg}" +
|
145
|
-
|
145
|
+
sass_backtrace.each_with_index.map do |entry, i|
|
146
146
|
"\n #{i == 0 ? 'on' : 'from'} line #{entry[:line]}" +
|
147
147
|
" of #{entry[:filename] || default_filename}" +
|
148
148
|
(entry[:mixin] ? ", in `#{entry[:mixin]}'" : "")
|
@@ -153,7 +153,7 @@ module Sass
|
|
153
153
|
# Returns an error report for an exception in CSS format.
|
154
154
|
#
|
155
155
|
# @param e [Exception]
|
156
|
-
# @param line_offset [
|
156
|
+
# @param line_offset [Fixnum] The number of the first line of the Sass template.
|
157
157
|
# @return [String] The error report
|
158
158
|
# @raise [Exception] `e`, if the
|
159
159
|
# {file:SASS_REFERENCE.md#full_exception-option `:full_exception`} option
|
@@ -186,7 +186,7 @@ END
|
|
186
186
|
section = e.sass_template.rstrip.split("\n")[min...line_num + 5]
|
187
187
|
return e.sass_backtrace_str if section.nil? || section.empty?
|
188
188
|
|
189
|
-
e.sass_backtrace_str + "\n\n" +
|
189
|
+
e.sass_backtrace_str + "\n\n" + section.each_with_index.
|
190
190
|
map {|line, i| "#{line_offset + min + i}: #{line}"}.join("\n")
|
191
191
|
end
|
192
192
|
end
|
data/lib/sass/exec/base.rb
CHANGED
@@ -23,7 +23,7 @@ module Sass::Exec
|
|
23
23
|
# at_exit is a bit of a hack, but it allows us to rethrow when --trace
|
24
24
|
# is active and get both the built-in exception formatting and the
|
25
25
|
# correct exit code.
|
26
|
-
at_exit {exit
|
26
|
+
at_exit {exit 65} if e.is_a?(Sass::SyntaxError)
|
27
27
|
|
28
28
|
raise e if @options[:trace] || e.is_a?(SystemExit)
|
29
29
|
|
@@ -90,18 +90,9 @@ module Sass::Exec
|
|
90
90
|
#
|
91
91
|
# @param opts [OptionParser]
|
92
92
|
def encoding_option(opts)
|
93
|
-
encoding_desc =
|
94
|
-
'Does not work in Ruby 1.8.'
|
95
|
-
else
|
96
|
-
'Specify the default encoding for input files.'
|
97
|
-
end
|
93
|
+
encoding_desc = 'Specify the default encoding for input files.'
|
98
94
|
opts.on('-E', '--default-encoding ENCODING', encoding_desc) do |encoding|
|
99
|
-
|
100
|
-
$stderr.puts "Specifying the encoding is not supported in ruby 1.8."
|
101
|
-
exit 1
|
102
|
-
else
|
103
|
-
Encoding.default_external = encoding
|
104
|
-
end
|
95
|
+
Encoding.default_external = encoding
|
105
96
|
end
|
106
97
|
end
|
107
98
|
|
data/lib/sass/features.rb
CHANGED
@@ -67,7 +67,7 @@ module Sass
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def public_url(name, sourcemap_directory)
|
70
|
-
file_pathname = Sass::Util.cleanpath(
|
70
|
+
file_pathname = Sass::Util.cleanpath(File.absolute_path(name, @root))
|
71
71
|
return Sass::Util.file_uri_from_path(file_pathname) if sourcemap_directory.nil?
|
72
72
|
|
73
73
|
sourcemap_pathname = Sass::Util.cleanpath(sourcemap_directory)
|
@@ -133,7 +133,7 @@ module Sass
|
|
133
133
|
|
134
134
|
REDUNDANT_DIRECTORY = /#{Regexp.escape(File::SEPARATOR)}\.#{Regexp.escape(File::SEPARATOR)}/
|
135
135
|
# Given a base directory and an `@import`ed name,
|
136
|
-
# finds an
|
136
|
+
# finds an existent file that matches the name.
|
137
137
|
#
|
138
138
|
# @param dir [String] The directory relative to which to search.
|
139
139
|
# @param name [String] The filename to search for.
|
data/lib/sass/plugin.rb
CHANGED
@@ -12,7 +12,7 @@ module Sass
|
|
12
12
|
# when it's used as a plugin for various frameworks.
|
13
13
|
# All Rack-enabled frameworks are supported out of the box.
|
14
14
|
# The plugin is
|
15
|
-
# {file:SASS_REFERENCE.md#
|
15
|
+
# {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
|
16
16
|
# Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
|
17
17
|
#
|
18
18
|
# This module has a large set of callbacks available
|
data/lib/sass/plugin/compiler.rb
CHANGED
@@ -31,7 +31,7 @@ module Sass::Plugin
|
|
31
31
|
# Creates a new compiler.
|
32
32
|
#
|
33
33
|
# @param opts [{Symbol => Object}]
|
34
|
-
# See {file:SASS_REFERENCE.md#
|
34
|
+
# See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
35
35
|
def initialize(opts = {})
|
36
36
|
@watched_files = Set.new
|
37
37
|
options.merge!(opts)
|
@@ -303,42 +303,30 @@ module Sass::Plugin
|
|
303
303
|
directories += @inferred_directories
|
304
304
|
directories = remove_redundant_directories(directories)
|
305
305
|
|
306
|
-
# A Listen version prior to 2.0 will write a test file to a directory to
|
307
|
-
# see if a watcher supports watching that directory. That breaks horribly
|
308
|
-
# on read-only directories, so we filter those out.
|
309
|
-
unless Sass::Util.listen_geq_2?
|
310
|
-
directories = directories.select {|d| File.directory?(d) && File.writable?(d)}
|
311
|
-
end
|
312
|
-
|
313
306
|
# TODO: Keep better track of what depends on what
|
314
307
|
# so we don't have to run a global update every time anything changes.
|
315
308
|
# XXX The :additional_watch_paths option exists for Compass to use until
|
316
309
|
# a deprecated feature is removed. It may be removed without warning.
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
# In Listen 2.0.0 and on, :force_polling is an option. In earlier
|
326
|
-
# versions, it's a method on the listener (called below).
|
327
|
-
listener_args.last[:force_polling] = true
|
328
|
-
end
|
310
|
+
directories += Array(options[:additional_watch_paths])
|
311
|
+
|
312
|
+
options = {
|
313
|
+
:relative_paths => false,
|
314
|
+
# The native windows listener is much slower than the polling option, according to
|
315
|
+
# https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e
|
316
|
+
:force_polling => @options[:poll] || Sass::Util.windows?
|
317
|
+
}
|
329
318
|
|
330
|
-
listener = create_listener(*
|
319
|
+
listener = create_listener(*directories, options) do |modified, added, removed|
|
331
320
|
on_file_changed(individual_files, modified, added, removed)
|
332
321
|
yield(modified, added, removed) if block_given?
|
333
322
|
end
|
334
323
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
324
|
+
begin
|
325
|
+
listener.start
|
326
|
+
sleep
|
327
|
+
rescue Interrupt
|
328
|
+
# Squelch Interrupt for clean exit from Listen::Listener
|
339
329
|
end
|
340
|
-
|
341
|
-
listen_to(listener)
|
342
330
|
end
|
343
331
|
|
344
332
|
# Non-destructively modifies \{#options} so that default values are properly set,
|
@@ -387,28 +375,10 @@ module Sass::Plugin
|
|
387
375
|
|
388
376
|
private
|
389
377
|
|
378
|
+
# This is mocked out in compiler_test.rb.
|
390
379
|
def create_listener(*args, &block)
|
391
|
-
|
392
|
-
|
393
|
-
# Work around guard/listen#243.
|
394
|
-
options = args.pop if args.last.is_a?(Hash)
|
395
|
-
args.map do |dir|
|
396
|
-
Listen.to(dir, options, &block)
|
397
|
-
end
|
398
|
-
else
|
399
|
-
Listen::Listener.new(*args, &block)
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
def listen_to(listener)
|
404
|
-
if Sass::Util.listen_geq_2?
|
405
|
-
listener.map {|l| l.start}
|
406
|
-
sleep
|
407
|
-
else
|
408
|
-
listener.start!
|
409
|
-
end
|
410
|
-
rescue Interrupt
|
411
|
-
# Squelch Interrupt for clean exit from Listen::Listener
|
380
|
+
require 'listen'
|
381
|
+
Listen.to(*args, &block)
|
412
382
|
end
|
413
383
|
|
414
384
|
def remove_redundant_directories(directories)
|
@@ -494,7 +464,7 @@ module Sass::Plugin
|
|
494
464
|
rendered = engine.render
|
495
465
|
end
|
496
466
|
rescue StandardError => e
|
497
|
-
|
467
|
+
compilation_error_occurred = true
|
498
468
|
run_compilation_error e, filename, css, sourcemap
|
499
469
|
raise e unless options[:full_exception]
|
500
470
|
rendered = Sass::SyntaxError.exception_to_css(e, options[:line] || 1)
|
@@ -507,14 +477,14 @@ module Sass::Plugin
|
|
507
477
|
mapping.to_json(
|
508
478
|
:css_path => css, :sourcemap_path => sourcemap, :type => options[:sourcemap]))
|
509
479
|
end
|
510
|
-
run_updated_stylesheet(filename, css, sourcemap) unless
|
480
|
+
run_updated_stylesheet(filename, css, sourcemap) unless compilation_error_occurred
|
511
481
|
end
|
512
482
|
|
513
483
|
def write_file(fileName, content)
|
514
484
|
flag = 'w'
|
515
485
|
flag = 'wb' if Sass::Util.windows? && options[:unix_newlines]
|
516
486
|
File.open(fileName, flag) do |file|
|
517
|
-
file.set_encoding(content.encoding)
|
487
|
+
file.set_encoding(content.encoding)
|
518
488
|
file.print(content)
|
519
489
|
end
|
520
490
|
end
|
data/lib/sass/plugin/rack.rb
CHANGED
@@ -9,19 +9,19 @@ module Sass
|
|
9
9
|
#
|
10
10
|
# ## Customize
|
11
11
|
#
|
12
|
-
# Sass::Plugin.options.merge
|
12
|
+
# Sass::Plugin.options.merge(
|
13
13
|
# :cache_location => './tmp/sass-cache',
|
14
14
|
# :never_update => environment != :production,
|
15
15
|
# :full_exception => environment != :production)
|
16
16
|
#
|
17
|
-
# {file:SASS_REFERENCE.md#
|
17
|
+
# {file:SASS_REFERENCE.md#options See the Reference for more options}.
|
18
18
|
#
|
19
19
|
# ## Use
|
20
20
|
#
|
21
21
|
# Put your Sass files in `public/stylesheets/sass`.
|
22
22
|
# Your CSS will be generated in `public/stylesheets`,
|
23
23
|
# and regenerated every request if necessary.
|
24
|
-
# The locations and frequency {file:SASS_REFERENCE.md#
|
24
|
+
# The locations and frequency {file:SASS_REFERENCE.md#options can be customized}.
|
25
25
|
# That's all there is to it!
|
26
26
|
class Rack
|
27
27
|
# The delay, in seconds, between update checks.
|
@@ -39,7 +39,7 @@ module Sass
|
|
39
39
|
# for checking the staleness of several stylesheets at once.
|
40
40
|
#
|
41
41
|
# @param options [{Symbol => Object}]
|
42
|
-
# See {file:SASS_REFERENCE.md#
|
42
|
+
# See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
43
43
|
def initialize(options)
|
44
44
|
# URIs that are being actively checked for staleness. Protects against
|
45
45
|
# import loops.
|
@@ -72,7 +72,7 @@ module Sass
|
|
72
72
|
# Returns whether a Sass or SCSS stylesheet has been modified since a given time.
|
73
73
|
#
|
74
74
|
# @param template_file [String] The location of the Sass or SCSS template.
|
75
|
-
# @param mtime [
|
75
|
+
# @param mtime [Fixnum] The modification time to check against.
|
76
76
|
# @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
|
77
77
|
# Defaults to the filesystem importer.
|
78
78
|
# @return [Boolean] Whether the stylesheet has been modified.
|
@@ -103,7 +103,7 @@ module Sass
|
|
103
103
|
# so it's better to use when checking multiple stylesheets at once.
|
104
104
|
#
|
105
105
|
# @param template_file [String] The location of the Sass or SCSS template.
|
106
|
-
# @param mtime [
|
106
|
+
# @param mtime [Fixnum] The modification time to check against.
|
107
107
|
# @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
|
108
108
|
# Defaults to the filesystem importer.
|
109
109
|
# @return [Boolean] Whether the stylesheet has been modified.
|
data/lib/sass/railtie.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Rails 3.0.0.beta.2+, < 3.1
|
2
|
-
if defined?(ActiveSupport) &&
|
2
|
+
if defined?(ActiveSupport) && ActiveSupport.public_methods.include?(:on_load) &&
|
3
3
|
!Sass::Util.ap_geq?('3.1.0.beta')
|
4
4
|
require 'sass/plugin/configuration'
|
5
5
|
ActiveSupport.on_load(:before_configuration) do
|
data/lib/sass/script.rb
CHANGED
@@ -16,12 +16,12 @@ module Sass
|
|
16
16
|
# Parses a string of SassScript
|
17
17
|
#
|
18
18
|
# @param value [String] The SassScript
|
19
|
-
# @param line [
|
19
|
+
# @param line [Fixnum] The number of the line on which the SassScript appeared.
|
20
20
|
# Used for error reporting
|
21
|
-
# @param offset [
|
21
|
+
# @param offset [Fixnum] The number of characters in on `line` that the SassScript started.
|
22
22
|
# Used for error reporting
|
23
23
|
# @param options [{Symbol => Object}] An options hash;
|
24
|
-
# see {file:SASS_REFERENCE.md#
|
24
|
+
# see {file:SASS_REFERENCE.md#options the Sass options documentation}
|
25
25
|
# @return [Script::Tree::Node] The root node of the parse tree
|
26
26
|
def self.parse(value, line, offset, options = {})
|
27
27
|
Parser.parse(value, line, offset, options)
|
@@ -77,7 +77,7 @@ module Sass::Script
|
|
77
77
|
# \{#complement complement($color)}
|
78
78
|
# : Returns the complement of a color.
|
79
79
|
#
|
80
|
-
# \{#invert invert($color)}
|
80
|
+
# \{#invert invert($color, \[$weight\])}
|
81
81
|
# : Returns the inverse of a color.
|
82
82
|
#
|
83
83
|
# ## Opacity Functions
|
@@ -176,7 +176,7 @@ module Sass::Script
|
|
176
176
|
# \{#set-nth set-nth($list, $n, $value)}
|
177
177
|
# : Replaces the nth item in a list.
|
178
178
|
#
|
179
|
-
# \{#join join($list1, $list2, \[$separator\])}
|
179
|
+
# \{#join join($list1, $list2, \[$separator, $bracketed\])}
|
180
180
|
# : Joins together two lists into one.
|
181
181
|
#
|
182
182
|
# \{#append append($list1, $val, \[$separator\])}
|
@@ -191,6 +191,9 @@ module Sass::Script
|
|
191
191
|
# \{#list_separator list-separator($list)}
|
192
192
|
# : Returns the separator of a list.
|
193
193
|
#
|
194
|
+
# \{#is_bracketed is-bracketed($list)}
|
195
|
+
# : Returns whether a list has square brackets.
|
196
|
+
#
|
194
197
|
# ## Map Functions {#map-functions}
|
195
198
|
#
|
196
199
|
# Maps in Sass are immutable; all map functions return a new map rather than
|
@@ -276,6 +279,9 @@ module Sass::Script
|
|
276
279
|
# \{#mixin_exists mixin-exists($name)}
|
277
280
|
# : Returns whether a mixin with the given name exists.
|
278
281
|
#
|
282
|
+
# \{#content_exists content-exists()}
|
283
|
+
# : Returns whether the current mixin was passed a content block.
|
284
|
+
#
|
279
285
|
# \{#inspect inspect($value)}
|
280
286
|
# : Returns the string representation of a value as it would be represented in Sass.
|
281
287
|
#
|
@@ -291,8 +297,12 @@ module Sass::Script
|
|
291
297
|
# \{#comparable comparable($number1, $number2)}
|
292
298
|
# : Returns whether two numbers can be added, subtracted, or compared.
|
293
299
|
#
|
294
|
-
# \{#call call($
|
295
|
-
# : Dynamically calls a Sass function
|
300
|
+
# \{#call call($function, $args...)}
|
301
|
+
# : Dynamically calls a Sass function reference returned by `get-function`.
|
302
|
+
#
|
303
|
+
# \{#get_function get-function($name)}
|
304
|
+
# : Looks up a function with the given name in the current lexical scope
|
305
|
+
# and returns a reference to it.
|
296
306
|
#
|
297
307
|
# ## Miscellaneous Functions
|
298
308
|
#
|
@@ -431,8 +441,8 @@ module Sass::Script
|
|
431
441
|
# If no signatures match, the first signature is returned for error messaging.
|
432
442
|
#
|
433
443
|
# @param method_name [Symbol] The name of the Ruby function to be called.
|
434
|
-
# @param arg_arity [
|
435
|
-
# @param kwarg_arity [
|
444
|
+
# @param arg_arity [Fixnum] The number of unnamed arguments the function was passed.
|
445
|
+
# @param kwarg_arity [Fixnum] The number of keyword arguments the function was passed.
|
436
446
|
#
|
437
447
|
# @return [{Symbol => Object}, nil]
|
438
448
|
# The signature options for the matching signature,
|
@@ -471,14 +481,14 @@ module Sass::Script
|
|
471
481
|
# @param seed [Integer]
|
472
482
|
# @return [Integer] The same seed.
|
473
483
|
def self.random_seed=(seed)
|
474
|
-
@random_number_generator =
|
484
|
+
@random_number_generator = Random.new(seed)
|
475
485
|
end
|
476
486
|
|
477
487
|
# Get Sass's internal random number generator.
|
478
488
|
#
|
479
489
|
# @return [Random]
|
480
490
|
def self.random_number_generator
|
481
|
-
@random_number_generator ||=
|
491
|
+
@random_number_generator ||= Random.new
|
482
492
|
end
|
483
493
|
|
484
494
|
# The context in which methods in {Script::Functions} are evaluated.
|
@@ -522,18 +532,27 @@ module Sass::Script
|
|
522
532
|
# assert_type value, :String
|
523
533
|
# assert_type value, :Number
|
524
534
|
# @param value [Sass::Script::Value::Base] A SassScript value
|
525
|
-
# @param type [Symbol] The name of the type the value is expected to be
|
535
|
+
# @param type [Symbol, Array<Symbol>] The name(s) of the type the value is expected to be
|
526
536
|
# @param name [String, Symbol, nil] The name of the argument.
|
527
537
|
# @raise [ArgumentError] if value is not of the correct type.
|
528
538
|
def assert_type(value, type, name = nil)
|
529
|
-
|
530
|
-
|
531
|
-
value.
|
539
|
+
valid_types = Array(type)
|
540
|
+
found_type = valid_types.find do |t|
|
541
|
+
value.is_a?(Sass::Script::Value.const_get(t)) ||
|
542
|
+
t == :Map && value.is_a?(Sass::Script::Value::List) && value.value.empty?
|
543
|
+
end
|
544
|
+
|
545
|
+
if found_type
|
546
|
+
value.check_deprecated_interp if found_type == :String
|
532
547
|
return
|
533
548
|
end
|
534
549
|
|
535
|
-
|
536
|
-
|
550
|
+
err = if valid_types.size == 1
|
551
|
+
"#{value.inspect} is not a #{TYPE_NAMES[type] || type.to_s.downcase}"
|
552
|
+
else
|
553
|
+
type_names = valid_types.map {|t| TYPE_NAMES[t] || t.to_s.downcase}
|
554
|
+
"#{value.inspect} is not any of #{type_names.join(', ')}"
|
555
|
+
end
|
537
556
|
err = "$#{name.to_s.tr('_', '-')}: " + err if name
|
538
557
|
raise ArgumentError.new(err)
|
539
558
|
end
|
@@ -1305,7 +1324,7 @@ module Sass::Script
|
|
1305
1324
|
# @param $color1 [Sass::Script::Value::Color]
|
1306
1325
|
# @param $color2 [Sass::Script::Value::Color]
|
1307
1326
|
# @param $weight [Sass::Script::Value::Number] The relative weight of each
|
1308
|
-
# color. Closer to `
|
1327
|
+
# color. Closer to `0%` gives more weight to `$color1`, closer to `100%`
|
1309
1328
|
# gives more weight to `$color2`
|
1310
1329
|
# @return [Sass::Script::Value::Color]
|
1311
1330
|
# @raise [ArgumentError] if `$weight` is out of bounds or any parameter is
|
@@ -1384,20 +1403,28 @@ module Sass::Script
|
|
1384
1403
|
#
|
1385
1404
|
# @overload invert($color)
|
1386
1405
|
# @param $color [Sass::Script::Value::Color]
|
1406
|
+
# @overload invert($color, $weight: 100%)
|
1407
|
+
# @param $color [Sass::Script::Value::Color]
|
1408
|
+
# @param $weight [Sass::Script::Value::Number] The relative weight of the
|
1409
|
+
# color color's inverse
|
1387
1410
|
# @return [Sass::Script::Value::Color]
|
1388
|
-
# @raise [ArgumentError] if `$color` isn't a color
|
1389
|
-
|
1411
|
+
# @raise [ArgumentError] if `$color` isn't a color or `$weight`
|
1412
|
+
# isn't a percentage between 0% and 100%
|
1413
|
+
def invert(color, weight = number(100))
|
1390
1414
|
if color.is_a?(Sass::Script::Value::Number)
|
1391
1415
|
return identifier("invert(#{color})")
|
1392
1416
|
end
|
1393
1417
|
|
1394
1418
|
assert_type color, :Color, :color
|
1395
|
-
color.with(
|
1419
|
+
inv = color.with(
|
1396
1420
|
:red => (255 - color.red),
|
1397
1421
|
:green => (255 - color.green),
|
1398
1422
|
:blue => (255 - color.blue))
|
1423
|
+
|
1424
|
+
mix(inv, color, weight)
|
1399
1425
|
end
|
1400
1426
|
declare :invert, [:color]
|
1427
|
+
declare :invert, [:color, :weight]
|
1401
1428
|
|
1402
1429
|
# Removes quotes from a string. If the string is already unquoted, this will
|
1403
1430
|
# return it unmodified.
|
@@ -1546,7 +1573,7 @@ MESSAGE
|
|
1546
1573
|
# @param $start-at [Sass::Script::Value::Number] The index of the first
|
1547
1574
|
# character of the substring. If this is negative, it counts from the end
|
1548
1575
|
# of `$string`
|
1549
|
-
# @param $end-
|
1576
|
+
# @param $end-before [Sass::Script::Value::Number] The index of the last
|
1550
1577
|
# character of the substring. If this is negative, it counts from the end
|
1551
1578
|
# of `$string`. Defaults to -1
|
1552
1579
|
# @return [Sass::Script::Value::String] The substring. This will be quoted
|
@@ -1565,7 +1592,7 @@ MESSAGE
|
|
1565
1592
|
s = string.value.length + s if s < 0
|
1566
1593
|
s = 0 if s < 0
|
1567
1594
|
e = string.value.length + e if e < 0
|
1568
|
-
|
1595
|
+
e = 0 if s < 0
|
1569
1596
|
extracted = string.value.slice(s..e)
|
1570
1597
|
Sass::Script::Value::String.new(extracted || "", string.type)
|
1571
1598
|
end
|
@@ -1583,7 +1610,7 @@ MESSAGE
|
|
1583
1610
|
# @raise [ArgumentError] if `$string` isn't a string
|
1584
1611
|
def to_upper_case(string)
|
1585
1612
|
assert_type string, :String, :string
|
1586
|
-
Sass::Script::Value::String.new(
|
1613
|
+
Sass::Script::Value::String.new(string.value.upcase, string.type)
|
1587
1614
|
end
|
1588
1615
|
declare :to_upper_case, [:string]
|
1589
1616
|
|
@@ -1598,7 +1625,7 @@ MESSAGE
|
|
1598
1625
|
# @raise [ArgumentError] if `$string` isn't a string
|
1599
1626
|
def to_lower_case(string)
|
1600
1627
|
assert_type string, :String, :string
|
1601
|
-
Sass::Script::Value::String.new(
|
1628
|
+
Sass::Script::Value::String.new(string.value.downcase, string.type)
|
1602
1629
|
end
|
1603
1630
|
declare :to_lower_case, [:string]
|
1604
1631
|
|
@@ -1612,6 +1639,10 @@ MESSAGE
|
|
1612
1639
|
# type-of(#fff) => color
|
1613
1640
|
# type-of(blue) => color
|
1614
1641
|
# type-of(null) => null
|
1642
|
+
# type-of(a b c) => list
|
1643
|
+
# type-of((a: 1, b: 2)) => map
|
1644
|
+
# type-of(get-function("foo")) => function
|
1645
|
+
#
|
1615
1646
|
# @overload type_of($value)
|
1616
1647
|
# @param $value [Sass::Script::Value::Base] The value to inspect
|
1617
1648
|
# @return [Sass::Script::Value::String] The unquoted string name of the
|
@@ -1639,6 +1670,12 @@ MESSAGE
|
|
1639
1670
|
#
|
1640
1671
|
# * `at-error` indicates that the Sass `@error` directive is supported.
|
1641
1672
|
#
|
1673
|
+
# * `custom-property` indicates that the [Custom Properties Level 1][] spec
|
1674
|
+
# is supported. This means that custom properties are parsed statically,
|
1675
|
+
# with only interpolation treated as SassScript.
|
1676
|
+
#
|
1677
|
+
# [Custom Properties Level 1]: https://www.w3.org/TR/css-variables-1/
|
1678
|
+
#
|
1642
1679
|
# @example
|
1643
1680
|
# feature-exists(some-feature-that-exists) => true
|
1644
1681
|
# feature-exists(what-is-this-i-dont-know) => false
|
@@ -1653,6 +1690,56 @@ MESSAGE
|
|
1653
1690
|
end
|
1654
1691
|
declare :feature_exists, [:feature]
|
1655
1692
|
|
1693
|
+
# Returns a reference to a function for later invocation with the `call` function.
|
1694
|
+
#
|
1695
|
+
# The function reference created may refer to a function defined in
|
1696
|
+
# your stylesheet, built-in to the host environment, or a CSS native
|
1697
|
+
# function. As such, this function never returns an error, but the
|
1698
|
+
# you can use `function-exists()` to check if the function reference
|
1699
|
+
# created points at a Sass function.
|
1700
|
+
#
|
1701
|
+
# @example
|
1702
|
+
# get-function("rgb")
|
1703
|
+
#
|
1704
|
+
# @function myfunc { @return "something"; }
|
1705
|
+
# get-function("myfunc")
|
1706
|
+
#
|
1707
|
+
# @overload get_function($name)
|
1708
|
+
# @param name [Sass::Script::Value::String] The name of the function being referenced.
|
1709
|
+
#
|
1710
|
+
# @return [Sass::Script::Value::Function] A function reference.
|
1711
|
+
def get_function(name, kwargs = {})
|
1712
|
+
assert_type name, :String, :name
|
1713
|
+
|
1714
|
+
css = if kwargs.has_key?("css")
|
1715
|
+
v = kwargs.delete("css")
|
1716
|
+
assert_type v, :Bool, :css
|
1717
|
+
v.value
|
1718
|
+
else
|
1719
|
+
false
|
1720
|
+
end
|
1721
|
+
|
1722
|
+
if kwargs.any?
|
1723
|
+
raise ArgumentError.new("Illegal keyword argument '#{kwargs.keys.first}'")
|
1724
|
+
end
|
1725
|
+
|
1726
|
+
if css
|
1727
|
+
return Sass::Script::Value::Function.new(
|
1728
|
+
Sass::Callable.new(name.value, nil, nil, nil, nil, nil, "function", :css))
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
callable = environment.caller.function(name.value) ||
|
1732
|
+
(Sass::Script::Functions.callable?(name.value.tr("-", "_")) &&
|
1733
|
+
Sass::Callable.new(name.value, nil, nil, nil, nil, nil, "function", :builtin))
|
1734
|
+
|
1735
|
+
if callable
|
1736
|
+
Sass::Script::Value::Function.new(callable)
|
1737
|
+
else
|
1738
|
+
raise Sass::SyntaxError.new("Function not found: #{name}")
|
1739
|
+
end
|
1740
|
+
end
|
1741
|
+
declare :get_function, [:name], :var_kwargs => true
|
1742
|
+
|
1656
1743
|
# Returns the unit(s) associated with a number. Complex units are sorted in
|
1657
1744
|
# alphabetical order by numerator and denominator.
|
1658
1745
|
#
|
@@ -1855,7 +1942,7 @@ MESSAGE
|
|
1855
1942
|
index = n.to_i > 0 ? n.to_i - 1 : n.to_i
|
1856
1943
|
new_list = list.to_a.dup
|
1857
1944
|
new_list[index] = value
|
1858
|
-
|
1945
|
+
list.with_contents(new_list)
|
1859
1946
|
end
|
1860
1947
|
declare :set_nth, [:list, :n, :value]
|
1861
1948
|
|
@@ -1896,6 +1983,9 @@ MESSAGE
|
|
1896
1983
|
# list. If both lists have fewer than two items, spaces are used for the
|
1897
1984
|
# resulting list.
|
1898
1985
|
#
|
1986
|
+
# Unless `$bracketed` is passed, the resulting list is bracketed if the
|
1987
|
+
# first parameter is.
|
1988
|
+
#
|
1899
1989
|
# Like all list functions, `join()` returns a new list rather than modifying
|
1900
1990
|
# its arguments in place.
|
1901
1991
|
#
|
@@ -1905,27 +1995,73 @@ MESSAGE
|
|
1905
1995
|
# join(10px, 20px) => 10px 20px
|
1906
1996
|
# join(10px, 20px, comma) => 10px, 20px
|
1907
1997
|
# join((blue, red), (#abc, #def), space) => blue red #abc #def
|
1908
|
-
#
|
1998
|
+
# join([10px], 20px) => [10px 20px]
|
1999
|
+
# @overload join($list1, $list2, $separator: auto, $bracketed: auto)
|
1909
2000
|
# @param $list1 [Sass::Script::Value::Base]
|
1910
2001
|
# @param $list2 [Sass::Script::Value::Base]
|
1911
2002
|
# @param $separator [Sass::Script::Value::String] The list separator to use.
|
1912
2003
|
# If this is `comma` or `space`, that separator will be used. If this is
|
1913
2004
|
# `auto` (the default), the separator is determined as explained above.
|
2005
|
+
# @param $bracketed [Sass::Script::Value::Base] Whether the resulting list
|
2006
|
+
# will be bracketed. If this is `auto` (the default), the separator is
|
2007
|
+
# determined as explained above.
|
1914
2008
|
# @return [Sass::Script::Value::List]
|
1915
|
-
|
2009
|
+
# @comment
|
2010
|
+
# rubocop:disable ParameterLists
|
2011
|
+
def join(list1, list2,
|
2012
|
+
separator = identifier("auto"), bracketed = identifier("auto"),
|
2013
|
+
kwargs = nil, *rest)
|
2014
|
+
# rubocop:enable ParameterLists
|
2015
|
+
if separator.is_a?(Hash)
|
2016
|
+
kwargs = separator
|
2017
|
+
separator = identifier("auto")
|
2018
|
+
elsif bracketed.is_a?(Hash)
|
2019
|
+
kwargs = bracketed
|
2020
|
+
bracketed = identifier("auto")
|
2021
|
+
elsif rest.last.is_a?(Hash)
|
2022
|
+
rest.unshift kwargs
|
2023
|
+
kwargs = rest.pop
|
2024
|
+
end
|
2025
|
+
|
2026
|
+
unless rest.empty?
|
2027
|
+
# Add 4 to rest.length because we don't want to count the kwargs hash,
|
2028
|
+
# which is always passed.
|
2029
|
+
raise ArgumentError.new("wrong number of arguments (#{rest.length + 4} for 2..4)")
|
2030
|
+
end
|
2031
|
+
|
2032
|
+
if kwargs
|
2033
|
+
separator = kwargs.delete("separator") || separator
|
2034
|
+
bracketed = kwargs.delete("bracketed") || bracketed
|
2035
|
+
|
2036
|
+
unless kwargs.empty?
|
2037
|
+
name, val = kwargs.to_a.first
|
2038
|
+
raise ArgumentError.new("Unknown argument $#{name} (#{val})")
|
2039
|
+
end
|
2040
|
+
end
|
2041
|
+
|
1916
2042
|
assert_type separator, :String, :separator
|
1917
2043
|
unless %w(auto space comma).include?(separator.value)
|
1918
2044
|
raise ArgumentError.new("Separator name must be space, comma, or auto")
|
1919
2045
|
end
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
2046
|
+
|
2047
|
+
list(list1.to_a + list2.to_a,
|
2048
|
+
separator:
|
2049
|
+
if separator.value == 'auto'
|
2050
|
+
list1.separator || list2.separator || :space
|
2051
|
+
else
|
2052
|
+
separator.value.to_sym
|
2053
|
+
end,
|
2054
|
+
bracketed:
|
2055
|
+
if bracketed.is_a?(Sass::Script::Value::String) && bracketed.value == 'auto'
|
2056
|
+
list1.bracketed
|
2057
|
+
else
|
2058
|
+
bracketed.to_bool
|
2059
|
+
end)
|
1926
2060
|
end
|
1927
|
-
|
1928
|
-
|
2061
|
+
# We don't actually take variable arguments or keyword arguments, but this
|
2062
|
+
# is the best way to take either `$separator` or `$bracketed` as keywords
|
2063
|
+
# without complaining about the other missing.
|
2064
|
+
declare :join, [:list1, :list2], :var_args => true, :var_kwargs => true
|
1929
2065
|
|
1930
2066
|
# Appends a single value onto the end of a list.
|
1931
2067
|
#
|
@@ -1953,12 +2089,13 @@ MESSAGE
|
|
1953
2089
|
unless %w(auto space comma).include?(separator.value)
|
1954
2090
|
raise ArgumentError.new("Separator name must be space, comma, or auto")
|
1955
2091
|
end
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
2092
|
+
list.with_contents(list.to_a + [val],
|
2093
|
+
separator:
|
2094
|
+
if separator.value == 'auto'
|
2095
|
+
list.separator || :space
|
2096
|
+
else
|
2097
|
+
separator.value.to_sym
|
2098
|
+
end)
|
1962
2099
|
end
|
1963
2100
|
declare :append, [:list, :val]
|
1964
2101
|
declare :append, [:list, :val, :separator]
|
@@ -2028,7 +2165,20 @@ MESSAGE
|
|
2028
2165
|
def list_separator(list)
|
2029
2166
|
identifier((list.separator || :space).to_s)
|
2030
2167
|
end
|
2031
|
-
declare :
|
2168
|
+
declare :list_separator, [:list]
|
2169
|
+
|
2170
|
+
# Returns whether a list uses square brackets.
|
2171
|
+
#
|
2172
|
+
# @example
|
2173
|
+
# is-bracketed(1px 2px 3px) => false
|
2174
|
+
# is-bracketed([1px, 2px, 3px]) => true
|
2175
|
+
# @overload is_bracketed($list)
|
2176
|
+
# @param $list [Sass::Script::Value::Base]
|
2177
|
+
# @return [Sass::Script::Value::Bool]
|
2178
|
+
def is_bracketed(list)
|
2179
|
+
bool(list.bracketed)
|
2180
|
+
end
|
2181
|
+
declare :is_bracketed, [:list]
|
2032
2182
|
|
2033
2183
|
# Returns the value in a map associated with the given key. If the map
|
2034
2184
|
# doesn't have such a key, returns `null`.
|
@@ -2214,10 +2364,24 @@ MESSAGE
|
|
2214
2364
|
# $fn: nth;
|
2215
2365
|
# call($fn, (a b c), 2) => b
|
2216
2366
|
#
|
2217
|
-
# @overload call($
|
2218
|
-
# @param $
|
2367
|
+
# @overload call($function, $args...)
|
2368
|
+
# @param $function [Sass::Script::Value::Function] The function to call.
|
2219
2369
|
def call(name, *args)
|
2220
|
-
|
2370
|
+
unless name.is_a?(Sass::Script::Value::String) ||
|
2371
|
+
name.is_a?(Sass::Script::Value::Function)
|
2372
|
+
assert_type name, :Function, :function
|
2373
|
+
end
|
2374
|
+
if name.is_a?(Sass::Script::Value::String)
|
2375
|
+
name = if function_exists(name).to_bool
|
2376
|
+
get_function(name)
|
2377
|
+
else
|
2378
|
+
get_function(name, "css" => bool(true))
|
2379
|
+
end
|
2380
|
+
Sass::Util.sass_warn(<<WARNING)
|
2381
|
+
DEPRECATION WARNING: Passing a string to call() is deprecated and will be illegal
|
2382
|
+
in Sass 4.0. Use call(#{name.to_sass}) instead.
|
2383
|
+
WARNING
|
2384
|
+
end
|
2221
2385
|
kwargs = args.last.is_a?(Hash) ? args.pop : {}
|
2222
2386
|
funcall = Sass::Script::Tree::Funcall.new(
|
2223
2387
|
name.value,
|
@@ -2225,6 +2389,8 @@ MESSAGE
|
|
2225
2389
|
Sass::Util.map_vals(kwargs) {|v| Sass::Script::Tree::Literal.new(v)},
|
2226
2390
|
nil,
|
2227
2391
|
nil)
|
2392
|
+
funcall.line = environment.stack.frames.last.line
|
2393
|
+
funcall.filename = environment.stack.frames.last.filename
|
2228
2394
|
funcall.options = options
|
2229
2395
|
perform(funcall)
|
2230
2396
|
end
|
@@ -2313,12 +2479,12 @@ MESSAGE
|
|
2313
2479
|
#
|
2314
2480
|
# @overload function_exists($name)
|
2315
2481
|
# @param name [Sass::Script::Value::String] The name of the function to
|
2316
|
-
# check.
|
2482
|
+
# check or a function reference.
|
2317
2483
|
# @return [Sass::Script::Value::Bool] Whether the function is defined.
|
2318
2484
|
def function_exists(name)
|
2319
2485
|
assert_type name, :String, :name
|
2320
2486
|
exists = Sass::Script::Functions.callable?(name.value.tr("-", "_"))
|
2321
|
-
exists ||= environment.function(name.value)
|
2487
|
+
exists ||= environment.caller.function(name.value)
|
2322
2488
|
bool(exists)
|
2323
2489
|
end
|
2324
2490
|
declare :function_exists, [:name]
|
@@ -2341,6 +2507,31 @@ MESSAGE
|
|
2341
2507
|
end
|
2342
2508
|
declare :mixin_exists, [:name]
|
2343
2509
|
|
2510
|
+
# Check whether a mixin was passed a content block.
|
2511
|
+
#
|
2512
|
+
# Unless `content-exists()` is called directly from a mixin, an error will be raised.
|
2513
|
+
#
|
2514
|
+
# @example
|
2515
|
+
# @mixin needs-content {
|
2516
|
+
# @if not content-exists() {
|
2517
|
+
# @error "You must pass a content block!"
|
2518
|
+
# }
|
2519
|
+
# @content;
|
2520
|
+
# }
|
2521
|
+
#
|
2522
|
+
# @overload content_exists()
|
2523
|
+
# @return [Sass::Script::Value::Bool] Whether a content block was passed to the mixin.
|
2524
|
+
def content_exists
|
2525
|
+
# frames.last is the stack frame for this function,
|
2526
|
+
# so we use frames[-2] to get the frame before that.
|
2527
|
+
mixin_frame = environment.stack.frames[-2]
|
2528
|
+
unless mixin_frame && mixin_frame.type == :mixin
|
2529
|
+
raise Sass::SyntaxError.new("Cannot call content-exists() except within a mixin.")
|
2530
|
+
end
|
2531
|
+
bool(!environment.caller.content.nil?)
|
2532
|
+
end
|
2533
|
+
declare :content_exists, []
|
2534
|
+
|
2344
2535
|
# Return a string containing the value as its Sass representation.
|
2345
2536
|
#
|
2346
2537
|
# @overload inspect($value)
|
@@ -2510,7 +2701,7 @@ MESSAGE
|
|
2510
2701
|
|
2511
2702
|
extends = Sass::Util::SubsetMap.new
|
2512
2703
|
begin
|
2513
|
-
extender.populate_extends(extends, extendee
|
2704
|
+
extender.populate_extends(extends, extendee)
|
2514
2705
|
selector.do_extend(extends).to_sass_script
|
2515
2706
|
rescue Sass::SyntaxError => e
|
2516
2707
|
raise ArgumentError.new(e.to_s)
|
@@ -2553,7 +2744,7 @@ MESSAGE
|
|
2553
2744
|
|
2554
2745
|
extends = Sass::Util::SubsetMap.new
|
2555
2746
|
begin
|
2556
|
-
replacement.populate_extends(extends, original
|
2747
|
+
replacement.populate_extends(extends, original)
|
2557
2748
|
selector.do_extend(extends, [], true).to_sass_script
|
2558
2749
|
rescue Sass::SyntaxError => e
|
2559
2750
|
raise ArgumentError.new(e.to_s)
|