sass 3.4.25 → 3.5.0.pre.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|