sass 3.1.0 → 3.3.0
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 +7 -0
- data/CONTRIBUTING +1 -1
- data/MIT-LICENSE +2 -2
- data/README.md +29 -17
- data/Rakefile +43 -9
- data/VERSION +1 -1
- data/VERSION_DATE +1 -0
- data/VERSION_NAME +1 -1
- data/bin/sass +6 -1
- data/bin/sass-convert +6 -1
- data/bin/scss +6 -1
- data/ext/mkrf_conf.rb +27 -0
- data/lib/sass/cache_stores/base.rb +7 -3
- data/lib/sass/cache_stores/chain.rb +3 -2
- data/lib/sass/cache_stores/filesystem.rb +5 -7
- data/lib/sass/cache_stores/memory.rb +1 -1
- data/lib/sass/cache_stores/null.rb +2 -2
- data/lib/sass/callbacks.rb +2 -1
- data/lib/sass/css.rb +168 -53
- data/lib/sass/engine.rb +502 -174
- data/lib/sass/environment.rb +151 -111
- data/lib/sass/error.rb +7 -7
- data/lib/sass/exec.rb +176 -60
- data/lib/sass/features.rb +40 -0
- data/lib/sass/importers/base.rb +46 -7
- data/lib/sass/importers/deprecated_path.rb +51 -0
- data/lib/sass/importers/filesystem.rb +113 -30
- data/lib/sass/importers.rb +1 -0
- data/lib/sass/logger/base.rb +30 -0
- data/lib/sass/logger/log_level.rb +45 -0
- data/lib/sass/logger.rb +12 -0
- data/lib/sass/media.rb +213 -0
- data/lib/sass/plugin/compiler.rb +194 -104
- data/lib/sass/plugin/configuration.rb +18 -25
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +37 -11
- data/lib/sass/plugin.rb +10 -13
- data/lib/sass/railtie.rb +2 -1
- data/lib/sass/repl.rb +5 -6
- data/lib/sass/script/css_lexer.rb +8 -4
- data/lib/sass/script/css_parser.rb +5 -2
- data/lib/sass/script/functions.rb +1547 -618
- data/lib/sass/script/lexer.rb +122 -72
- data/lib/sass/script/parser.rb +304 -135
- data/lib/sass/script/tree/funcall.rb +306 -0
- data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +43 -13
- data/lib/sass/script/tree/list_literal.rb +77 -0
- data/lib/sass/script/tree/literal.rb +45 -0
- data/lib/sass/script/tree/map_literal.rb +64 -0
- data/lib/sass/script/{node.rb → tree/node.rb} +30 -12
- data/lib/sass/script/{operation.rb → tree/operation.rb} +33 -21
- data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +14 -4
- data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +21 -9
- data/lib/sass/script/tree/variable.rb +57 -0
- data/lib/sass/script/tree.rb +15 -0
- data/lib/sass/script/value/arg_list.rb +36 -0
- data/lib/sass/script/value/base.rb +238 -0
- data/lib/sass/script/value/bool.rb +40 -0
- data/lib/sass/script/{color.rb → value/color.rb} +256 -74
- data/lib/sass/script/value/deprecated_false.rb +55 -0
- data/lib/sass/script/value/helpers.rb +155 -0
- data/lib/sass/script/value/list.rb +128 -0
- data/lib/sass/script/value/map.rb +70 -0
- data/lib/sass/script/value/null.rb +49 -0
- data/lib/sass/script/{number.rb → value/number.rb} +115 -62
- data/lib/sass/script/{string.rb → value/string.rb} +9 -11
- data/lib/sass/script/value.rb +12 -0
- data/lib/sass/script.rb +35 -9
- data/lib/sass/scss/css_parser.rb +2 -12
- data/lib/sass/scss/parser.rb +657 -230
- data/lib/sass/scss/rx.rb +17 -12
- data/lib/sass/scss/static_parser.rb +37 -6
- data/lib/sass/scss.rb +0 -1
- data/lib/sass/selector/abstract_sequence.rb +35 -3
- data/lib/sass/selector/comma_sequence.rb +29 -14
- data/lib/sass/selector/sequence.rb +371 -74
- data/lib/sass/selector/simple.rb +28 -13
- data/lib/sass/selector/simple_sequence.rb +163 -36
- data/lib/sass/selector.rb +138 -36
- data/lib/sass/shared.rb +3 -5
- data/lib/sass/source/map.rb +196 -0
- data/lib/sass/source/position.rb +39 -0
- data/lib/sass/source/range.rb +41 -0
- data/lib/sass/stack.rb +126 -0
- data/lib/sass/supports.rb +228 -0
- data/lib/sass/tree/at_root_node.rb +82 -0
- data/lib/sass/tree/comment_node.rb +34 -29
- data/lib/sass/tree/content_node.rb +9 -0
- data/lib/sass/tree/css_import_node.rb +60 -0
- data/lib/sass/tree/debug_node.rb +3 -3
- data/lib/sass/tree/directive_node.rb +33 -3
- data/lib/sass/tree/each_node.rb +9 -9
- data/lib/sass/tree/extend_node.rb +20 -6
- data/lib/sass/tree/for_node.rb +6 -6
- data/lib/sass/tree/function_node.rb +12 -4
- data/lib/sass/tree/if_node.rb +2 -15
- data/lib/sass/tree/import_node.rb +11 -5
- data/lib/sass/tree/media_node.rb +27 -11
- data/lib/sass/tree/mixin_def_node.rb +15 -4
- data/lib/sass/tree/mixin_node.rb +27 -7
- data/lib/sass/tree/node.rb +69 -35
- data/lib/sass/tree/prop_node.rb +47 -31
- data/lib/sass/tree/return_node.rb +4 -3
- data/lib/sass/tree/root_node.rb +20 -4
- data/lib/sass/tree/rule_node.rb +37 -26
- data/lib/sass/tree/supports_node.rb +38 -0
- data/lib/sass/tree/trace_node.rb +33 -0
- data/lib/sass/tree/variable_node.rb +10 -4
- data/lib/sass/tree/visitors/base.rb +5 -8
- data/lib/sass/tree/visitors/check_nesting.rb +67 -52
- data/lib/sass/tree/visitors/convert.rb +134 -53
- data/lib/sass/tree/visitors/cssize.rb +245 -51
- data/lib/sass/tree/visitors/deep_copy.rb +102 -0
- data/lib/sass/tree/visitors/extend.rb +68 -0
- data/lib/sass/tree/visitors/perform.rb +331 -105
- data/lib/sass/tree/visitors/set_options.rb +125 -0
- data/lib/sass/tree/visitors/to_css.rb +259 -95
- data/lib/sass/tree/warn_node.rb +3 -3
- data/lib/sass/tree/while_node.rb +3 -3
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/multibyte_string_scanner.rb +157 -0
- data/lib/sass/util/normalized_map.rb +130 -0
- data/lib/sass/util/ordered_hash.rb +192 -0
- data/lib/sass/util/subset_map.rb +11 -2
- data/lib/sass/util/test.rb +9 -0
- data/lib/sass/util.rb +565 -39
- data/lib/sass/version.rb +27 -15
- data/lib/sass.rb +39 -4
- data/test/sass/cache_test.rb +15 -0
- data/test/sass/compiler_test.rb +223 -0
- data/test/sass/conversion_test.rb +901 -107
- data/test/sass/css2sass_test.rb +94 -0
- data/test/sass/engine_test.rb +1059 -164
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +933 -837
- data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
- data/test/sass/functions_test.rb +995 -136
- data/test/sass/importer_test.rb +338 -18
- data/test/sass/logger_test.rb +58 -0
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/plugin_test.rb +114 -30
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/results/filename_fn.css +3 -0
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +1 -0
- data/test/sass/results/import_charset_1_8.css +1 -0
- data/test/sass/results/import_charset_ibm866.css +1 -0
- data/test/sass/results/import_content.css +1 -0
- data/test/sass/results/script.css +1 -1
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/results/units.css +2 -2
- data/test/sass/script_conversion_test.rb +43 -1
- data/test/sass/script_test.rb +380 -36
- data/test/sass/scss/css_test.rb +257 -75
- data/test/sass/scss/scss_test.rb +2322 -110
- data/test/sass/source_map_test.rb +887 -0
- data/test/sass/templates/_cached_import_option_partial.scss +1 -0
- data/test/sass/templates/_double_import_loop2.sass +1 -0
- data/test/sass/templates/_filename_fn_import.scss +11 -0
- data/test/sass/templates/_imported_content.sass +3 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/double_import_loop1.sass +1 -0
- data/test/sass/templates/filename_fn.scss +18 -0
- data/test/sass/templates/import_charset.sass +2 -0
- data/test/sass/templates/import_charset_1_8.sass +2 -0
- data/test/sass/templates/import_charset_ibm866.sass +2 -0
- data/test/sass/templates/import_content.sass +4 -0
- data/test/sass/templates/same_name_different_ext.sass +2 -0
- data/test/sass/templates/same_name_different_ext.scss +1 -0
- data/test/sass/templates/same_name_different_partiality.scss +1 -0
- data/test/sass/templates/single_import_loop.sass +1 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
- data/test/sass/util/normalized_map_test.rb +51 -0
- data/test/sass/util_test.rb +183 -0
- data/test/sass/value_helpers_test.rb +181 -0
- data/test/test_helper.rb +45 -5
- data/vendor/listen/CHANGELOG.md +228 -0
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +30 -0
- data/vendor/listen/Guardfile +8 -0
- data/vendor/{fssm → listen}/LICENSE +1 -1
- data/vendor/listen/README.md +315 -0
- data/vendor/listen/Rakefile +47 -0
- data/vendor/listen/Vagrantfile +96 -0
- data/vendor/listen/lib/listen/adapter.rb +214 -0
- data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
- data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
- data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
- data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
- data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
- data/vendor/listen/lib/listen/directory_record.rb +371 -0
- data/vendor/listen/lib/listen/listener.rb +225 -0
- data/vendor/listen/lib/listen/multi_listener.rb +143 -0
- data/vendor/listen/lib/listen/turnstile.rb +28 -0
- data/vendor/listen/lib/listen/version.rb +3 -0
- data/vendor/listen/lib/listen.rb +40 -0
- data/vendor/listen/listen.gemspec +22 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +183 -0
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
- data/vendor/listen/spec/listen/listener_spec.rb +169 -0
- data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
- data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
- data/vendor/listen/spec/listen_spec.rb +73 -0
- data/vendor/listen/spec/spec_helper.rb +21 -0
- data/vendor/listen/spec/support/adapter_helper.rb +629 -0
- data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
- data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
- data/vendor/listen/spec/support/listeners_helper.rb +156 -0
- data/vendor/listen/spec/support/platform_helper.rb +15 -0
- metadata +344 -271
- data/lib/sass/less.rb +0 -382
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/funcall.rb +0 -162
- data/lib/sass/script/list.rb +0 -76
- data/lib/sass/script/literal.rb +0 -245
- data/lib/sass/script/variable.rb +0 -54
- data/lib/sass/scss/sass_parser.rb +0 -11
- data/test/sass/less_conversion_test.rb +0 -653
- data/vendor/fssm/README.markdown +0 -55
- data/vendor/fssm/Rakefile +0 -59
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/example.rb +0 -9
- data/vendor/fssm/fssm.gemspec +0 -77
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
- data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
- data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
- data/vendor/fssm/lib/fssm/monitor.rb +0 -26
- data/vendor/fssm/lib/fssm/path.rb +0 -91
- data/vendor/fssm/lib/fssm/pathname.rb +0 -502
- data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
- data/vendor/fssm/lib/fssm/state/file.rb +0 -24
- data/vendor/fssm/lib/fssm/support.rb +0 -63
- data/vendor/fssm/lib/fssm/tree.rb +0 -176
- data/vendor/fssm/lib/fssm.rb +0 -33
- data/vendor/fssm/profile/prof-cache.rb +0 -40
- data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
- data/vendor/fssm/profile/prof-pathname.rb +0 -68
- data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
- data/vendor/fssm/profile/prof.html +0 -2379
- data/vendor/fssm/spec/path_spec.rb +0 -75
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -0,0 +1,51 @@
|
|
1
|
+
module Sass
|
2
|
+
module Importers
|
3
|
+
# This importer emits a deprecation warning the first time it is used to
|
4
|
+
# import a file. It is used to deprecate the current working
|
5
|
+
# directory from the list of automatic sass load paths.
|
6
|
+
class DeprecatedPath < Filesystem
|
7
|
+
# @param root [String] The absolute, expanded path to the folder that is deprecated.
|
8
|
+
def initialize(root)
|
9
|
+
@specified_root = root
|
10
|
+
@warning_given = false
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
# @see Sass::Importers::Base#find
|
15
|
+
def find(*args)
|
16
|
+
found = super
|
17
|
+
if found && !@warning_given
|
18
|
+
@warning_given = true
|
19
|
+
Sass::Util.sass_warn deprecation_warning
|
20
|
+
end
|
21
|
+
found
|
22
|
+
end
|
23
|
+
|
24
|
+
# @see Base#directories_to_watch
|
25
|
+
def directories_to_watch
|
26
|
+
# The current working directory was not watched in Sass 3.2,
|
27
|
+
# so we continue not to watch it while it's deprecated.
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
|
31
|
+
# @see Sass::Importers::Base#to_s
|
32
|
+
def to_s
|
33
|
+
"#{@root} (DEPRECATED)"
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
# @return [String] The deprecation warning that will be printed the first
|
39
|
+
# time an import occurs.
|
40
|
+
def deprecation_warning
|
41
|
+
path = @specified_root == "." ? "the current working directory" : @specified_root
|
42
|
+
<<WARNING
|
43
|
+
DEPRECATION WARNING: Importing from #{path} will not be
|
44
|
+
automatic in future versions of Sass. To avoid future errors, you can add it
|
45
|
+
to your environment explicitly by setting `SASS_PATH=#{@specified_root}`, by using the -I command
|
46
|
+
line option, or by changing your Sass configuration options.
|
47
|
+
WARNING
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'set'
|
2
2
|
|
3
3
|
module Sass
|
4
4
|
module Importers
|
5
5
|
# The default importer, used for any strings found in the load path.
|
6
6
|
# Simply loads Sass files from the filesystem using the default logic.
|
7
7
|
class Filesystem < Base
|
8
|
-
|
9
8
|
attr_accessor :root
|
10
9
|
|
11
10
|
# Creates a new filesystem importer that imports files relative to a given path.
|
@@ -13,7 +12,8 @@ module Sass
|
|
13
12
|
# @param root [String] The root path.
|
14
13
|
# This importer will import files relative to this path.
|
15
14
|
def initialize(root)
|
16
|
-
@root = root
|
15
|
+
@root = File.expand_path(root)
|
16
|
+
@same_name_warnings = Set.new
|
17
17
|
end
|
18
18
|
|
19
19
|
# @see Base#find_relative
|
@@ -28,7 +28,7 @@ module Sass
|
|
28
28
|
|
29
29
|
# @see Base#mtime
|
30
30
|
def mtime(name, options)
|
31
|
-
file,
|
31
|
+
file, _ = Sass::Util.destructure(find_real_file(@root, name, options))
|
32
32
|
File.mtime(file) if file
|
33
33
|
rescue Errno::ENOENT
|
34
34
|
nil
|
@@ -37,7 +37,7 @@ module Sass
|
|
37
37
|
# @see Base#key
|
38
38
|
def key(name, options)
|
39
39
|
[self.class.name + ":" + File.dirname(File.expand_path(name)),
|
40
|
-
|
40
|
+
File.basename(name)]
|
41
41
|
end
|
42
42
|
|
43
43
|
# @see Base#to_s
|
@@ -45,14 +45,47 @@ module Sass
|
|
45
45
|
@root
|
46
46
|
end
|
47
47
|
|
48
|
+
def hash
|
49
|
+
@root.hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def eql?(other)
|
53
|
+
root.eql?(other.root)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @see Base#directories_to_watch
|
57
|
+
def directories_to_watch
|
58
|
+
[root]
|
59
|
+
end
|
60
|
+
|
61
|
+
# @see Base#watched_file?
|
62
|
+
def watched_file?(filename)
|
63
|
+
filename =~ /\.s[ac]ss$/ &&
|
64
|
+
filename.start_with?(root + File::SEPARATOR)
|
65
|
+
end
|
66
|
+
|
67
|
+
def public_url(name, sourcemap_directory = nil)
|
68
|
+
if sourcemap_directory.nil?
|
69
|
+
warn_about_public_url(name)
|
70
|
+
else
|
71
|
+
file_pathname = Sass::Util.pathname(Sass::Util.absolute_path(name, @root)).cleanpath
|
72
|
+
sourcemap_pathname = Sass::Util.pathname(sourcemap_directory).cleanpath
|
73
|
+
begin
|
74
|
+
file_pathname.relative_path_from(sourcemap_pathname).to_s
|
75
|
+
rescue ArgumentError # when a relative path cannot be constructed
|
76
|
+
warn_about_public_url(name)
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
48
82
|
protected
|
49
83
|
|
50
84
|
# If a full uri is passed, this removes the root from it
|
51
85
|
# otherwise returns the name unchanged
|
52
86
|
def remove_root(name)
|
53
|
-
|
54
|
-
|
55
|
-
name[root.length..-1]
|
87
|
+
if name.index(@root + "/") == 0
|
88
|
+
name[(@root.length + 1)..-1]
|
56
89
|
else
|
57
90
|
name
|
58
91
|
end
|
@@ -77,31 +110,77 @@ module Sass
|
|
77
110
|
# The first element of each pair is a filename to look for;
|
78
111
|
# the second element is the syntax that file would be in (`:sass` or `:scss`).
|
79
112
|
def possible_files(name)
|
113
|
+
name = escape_glob_characters(name)
|
80
114
|
dirname, basename, extname = split(name)
|
81
115
|
sorted_exts = extensions.sort
|
82
116
|
syntax = extensions[extname]
|
83
117
|
|
84
|
-
|
85
|
-
|
118
|
+
if syntax
|
119
|
+
ret = [["#{dirname}/{_,}#{basename}.#{extensions.invert[syntax]}", syntax]]
|
120
|
+
else
|
121
|
+
ret = sorted_exts.map {|ext, syn| ["#{dirname}/{_,}#{basename}.#{ext}", syn]}
|
122
|
+
end
|
123
|
+
|
124
|
+
# JRuby chokes when trying to import files from JARs when the path starts with './'.
|
125
|
+
ret.map {|f, s| [f.sub(/^\.\//, ''), s]}
|
86
126
|
end
|
87
127
|
|
128
|
+
def escape_glob_characters(name)
|
129
|
+
name.gsub(/[\*\[\]\{\}\?]/) do |char|
|
130
|
+
"\\#{char}"
|
131
|
+
end
|
132
|
+
end
|
88
133
|
|
89
|
-
REDUNDANT_DIRECTORY =
|
134
|
+
REDUNDANT_DIRECTORY = /#{Regexp.escape(File::SEPARATOR)}\.#{Regexp.escape(File::SEPARATOR)}/
|
90
135
|
# Given a base directory and an `@import`ed name,
|
91
136
|
# finds an existant file that matches the name.
|
92
137
|
#
|
93
138
|
# @param dir [String] The directory relative to which to search.
|
94
139
|
# @param name [String] The filename to search for.
|
95
140
|
# @return [(String, Symbol)] A filename-syntax pair.
|
96
|
-
def find_real_file(dir, name)
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
141
|
+
def find_real_file(dir, name, options)
|
142
|
+
# on windows 'dir' can be in native File::ALT_SEPARATOR form
|
143
|
+
dir = dir.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil?
|
144
|
+
|
145
|
+
found = possible_files(remove_root(name)).map do |f, s|
|
146
|
+
path = (dir == "." || Sass::Util.pathname(f).absolute?) ? f :
|
147
|
+
"#{escape_glob_characters(dir)}/#{f}"
|
148
|
+
Dir[path].map do |full_path|
|
149
|
+
full_path.gsub!(REDUNDANT_DIRECTORY, File::SEPARATOR)
|
150
|
+
[Sass::Util.pathname(full_path).cleanpath.to_s, s]
|
102
151
|
end
|
103
152
|
end
|
104
|
-
|
153
|
+
found = Sass::Util.flatten(found, 1)
|
154
|
+
return if found.empty?
|
155
|
+
|
156
|
+
if found.size > 1 && !@same_name_warnings.include?(found.first.first)
|
157
|
+
found.each {|(f, _)| @same_name_warnings << f}
|
158
|
+
relative_to = Sass::Util.pathname(dir)
|
159
|
+
if options[:_from_import_node]
|
160
|
+
# If _line exists, we're here due to an actual import in an
|
161
|
+
# import_node and we want to print a warning for a user writing an
|
162
|
+
# ambiguous import.
|
163
|
+
candidates = found.map do |(f, _)|
|
164
|
+
" " + Sass::Util.pathname(f).relative_path_from(relative_to).to_s
|
165
|
+
end.join("\n")
|
166
|
+
raise Sass::SyntaxError.new(<<MESSAGE)
|
167
|
+
It's not clear which file to import for '@import "#{name}"'.
|
168
|
+
Candidates:
|
169
|
+
#{candidates}
|
170
|
+
Please delete or rename all but one of these files.
|
171
|
+
MESSAGE
|
172
|
+
else
|
173
|
+
# Otherwise, we're here via StalenessChecker, and we want to print a
|
174
|
+
# warning for a user running `sass --watch` with two ambiguous files.
|
175
|
+
candidates = found.map {|(f, _)| " " + File.basename(f)}.join("\n")
|
176
|
+
Sass::Util.sass_warn <<WARNING
|
177
|
+
WARNING: In #{File.dirname(name)}:
|
178
|
+
There are multiple files that match the name "#{File.basename(name)}":
|
179
|
+
#{candidates}
|
180
|
+
WARNING
|
181
|
+
end
|
182
|
+
end
|
183
|
+
found.first
|
105
184
|
end
|
106
185
|
|
107
186
|
# Splits a filename into three parts, a directory part, a basename, and an extension
|
@@ -109,25 +188,33 @@ module Sass
|
|
109
188
|
def split(name)
|
110
189
|
extension = nil
|
111
190
|
dirname, basename = File.dirname(name), File.basename(name)
|
112
|
-
if basename =~ /^(.*)\.(#{extensions.keys.map{|e| Regexp.escape(e)}.join('|')})$/
|
191
|
+
if basename =~ /^(.*)\.(#{extensions.keys.map {|e| Regexp.escape(e)}.join('|')})$/
|
113
192
|
basename = $1
|
114
193
|
extension = $2
|
115
194
|
end
|
116
195
|
[dirname, basename, extension]
|
117
196
|
end
|
118
197
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
def
|
124
|
-
|
198
|
+
# Issues a warning about being unable to determine a public url.
|
199
|
+
#
|
200
|
+
# @param uri [String] A URI known to be valid for this importer.
|
201
|
+
# @return [NilClass] nil
|
202
|
+
def warn_about_public_url(uri)
|
203
|
+
@warnings_issued ||= Set.new
|
204
|
+
unless @warnings_issued.include?(uri)
|
205
|
+
Sass::Util.sass_warn <<WARNING
|
206
|
+
WARNING: Couldn't determine public URL for "#{uri}" while generating sourcemap.
|
207
|
+
Without a public URL, there's nothing for the source map to link to.
|
208
|
+
WARNING
|
209
|
+
@warnings_issued << uri
|
210
|
+
end
|
211
|
+
nil
|
125
212
|
end
|
126
213
|
|
127
214
|
private
|
128
215
|
|
129
216
|
def _find(dir, name, options)
|
130
|
-
full_filename, syntax = find_real_file(dir, name)
|
217
|
+
full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options))
|
131
218
|
return unless full_filename && File.readable?(full_filename)
|
132
219
|
|
133
220
|
options[:syntax] = syntax
|
@@ -135,10 +222,6 @@ module Sass
|
|
135
222
|
options[:importer] = self
|
136
223
|
Sass::Engine.new(File.read(full_filename), options)
|
137
224
|
end
|
138
|
-
|
139
|
-
def join(base, path)
|
140
|
-
Pathname.new(base).join(path).to_s
|
141
|
-
end
|
142
225
|
end
|
143
226
|
end
|
144
227
|
end
|
data/lib/sass/importers.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sass/logger/log_level'
|
2
|
+
|
3
|
+
class Sass::Logger::Base
|
4
|
+
include Sass::Logger::LogLevel
|
5
|
+
|
6
|
+
attr_accessor :log_level
|
7
|
+
attr_accessor :disabled
|
8
|
+
|
9
|
+
log_level :trace
|
10
|
+
log_level :debug
|
11
|
+
log_level :info
|
12
|
+
log_level :warn
|
13
|
+
log_level :error
|
14
|
+
|
15
|
+
def initialize(log_level = :debug)
|
16
|
+
self.log_level = log_level
|
17
|
+
end
|
18
|
+
|
19
|
+
def logging_level?(level)
|
20
|
+
!disabled && self.class.log_level?(level, log_level)
|
21
|
+
end
|
22
|
+
|
23
|
+
def log(level, message)
|
24
|
+
_log(level, message) if logging_level?(level)
|
25
|
+
end
|
26
|
+
|
27
|
+
def _log(level, message)
|
28
|
+
Kernel.warn(message)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Sass
|
2
|
+
module Logger
|
3
|
+
module LogLevel
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def inherited(subclass)
|
10
|
+
subclass.log_levels = subclass.superclass.log_levels.dup
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_writer :log_levels
|
14
|
+
|
15
|
+
def log_levels
|
16
|
+
@log_levels ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def log_level?(level, min_level)
|
20
|
+
log_levels[level] >= log_levels[min_level]
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_level(name, options = {})
|
24
|
+
if options[:prepend]
|
25
|
+
level = log_levels.values.min
|
26
|
+
level = level.nil? ? 0 : level - 1
|
27
|
+
else
|
28
|
+
level = log_levels.values.max
|
29
|
+
level = level.nil? ? 0 : level + 1
|
30
|
+
end
|
31
|
+
log_levels.update(name => level)
|
32
|
+
define_logger(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_logger(name, options = {})
|
36
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
37
|
+
def #{name}(message)
|
38
|
+
#{options.fetch(:to, :log)}(#{name.inspect}, message)
|
39
|
+
end
|
40
|
+
RUBY
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/sass/logger.rb
ADDED
data/lib/sass/media.rb
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
# A namespace for the `@media` query parse tree.
|
2
|
+
module Sass::Media
|
3
|
+
# A comma-separated list of queries.
|
4
|
+
#
|
5
|
+
# media_query [ ',' S* media_query ]*
|
6
|
+
class QueryList
|
7
|
+
# The queries contained in this list.
|
8
|
+
#
|
9
|
+
# @return [Array<Query>]
|
10
|
+
attr_accessor :queries
|
11
|
+
|
12
|
+
# @param queries [Array<Query>] See \{#queries}
|
13
|
+
def initialize(queries)
|
14
|
+
@queries = queries
|
15
|
+
end
|
16
|
+
|
17
|
+
# Merges this query list with another. The returned query list
|
18
|
+
# queries for the intersection between the two inputs.
|
19
|
+
#
|
20
|
+
# Both query lists should be resolved.
|
21
|
+
#
|
22
|
+
# @param other [QueryList]
|
23
|
+
# @return [QueryList?] The merged list, or nil if there is no intersection.
|
24
|
+
def merge(other)
|
25
|
+
new_queries = queries.map {|q1| other.queries.map {|q2| q1.merge(q2)}}.flatten.compact
|
26
|
+
return if new_queries.empty?
|
27
|
+
QueryList.new(new_queries)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the CSS for the media query list.
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
def to_css
|
34
|
+
queries.map {|q| q.to_css}.join(', ')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the Sass/SCSS code for the media query list.
|
38
|
+
#
|
39
|
+
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
|
40
|
+
# @return [String]
|
41
|
+
def to_src(options)
|
42
|
+
queries.map {|q| q.to_src(options)}.join(', ')
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns a representation of the query as an array of strings and
|
46
|
+
# potentially {Sass::Script::Tree::Node}s (if there's interpolation in it).
|
47
|
+
# When the interpolation is resolved and the strings are joined together,
|
48
|
+
# this will be the string representation of this query.
|
49
|
+
#
|
50
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
51
|
+
def to_a
|
52
|
+
Sass::Util.intersperse(queries.map {|q| q.to_a}, ', ').flatten
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns a deep copy of this query list and all its children.
|
56
|
+
#
|
57
|
+
# @return [QueryList]
|
58
|
+
def deep_copy
|
59
|
+
QueryList.new(queries.map {|q| q.deep_copy})
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# A single media query.
|
64
|
+
#
|
65
|
+
# [ [ONLY | NOT]? S* media_type S* | expression ] [ AND S* expression ]*
|
66
|
+
class Query
|
67
|
+
# The modifier for the query.
|
68
|
+
#
|
69
|
+
# When parsed as Sass code, this contains strings and SassScript nodes. When
|
70
|
+
# parsed as CSS, it contains a single string (accessible via
|
71
|
+
# \{#resolved_modifier}).
|
72
|
+
#
|
73
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
74
|
+
attr_accessor :modifier
|
75
|
+
|
76
|
+
# The type of the query (e.g. `"screen"` or `"print"`).
|
77
|
+
#
|
78
|
+
# When parsed as Sass code, this contains strings and SassScript nodes. When
|
79
|
+
# parsed as CSS, it contains a single string (accessible via
|
80
|
+
# \{#resolved_type}).
|
81
|
+
#
|
82
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
83
|
+
attr_accessor :type
|
84
|
+
|
85
|
+
# The trailing expressions in the query.
|
86
|
+
#
|
87
|
+
# When parsed as Sass code, each expression contains strings and SassScript
|
88
|
+
# nodes. When parsed as CSS, each one contains a single string.
|
89
|
+
#
|
90
|
+
# @return [Array<Array<String, Sass::Script::Tree::Node>>]
|
91
|
+
attr_accessor :expressions
|
92
|
+
|
93
|
+
# @param modifier [Array<String, Sass::Script::Tree::Node>] See \{#modifier}
|
94
|
+
# @param type [Array<String, Sass::Script::Tree::Node>] See \{#type}
|
95
|
+
# @param expressions [Array<Array<String, Sass::Script::Tree::Node>>] See \{#expressions}
|
96
|
+
def initialize(modifier, type, expressions)
|
97
|
+
@modifier = modifier
|
98
|
+
@type = type
|
99
|
+
@expressions = expressions
|
100
|
+
end
|
101
|
+
|
102
|
+
# See \{#modifier}.
|
103
|
+
# @return [String]
|
104
|
+
def resolved_modifier
|
105
|
+
# modifier should contain only a single string
|
106
|
+
modifier.first || ''
|
107
|
+
end
|
108
|
+
|
109
|
+
# See \{#type}.
|
110
|
+
# @return [String]
|
111
|
+
def resolved_type
|
112
|
+
# type should contain only a single string
|
113
|
+
type.first || ''
|
114
|
+
end
|
115
|
+
|
116
|
+
# Merges this query with another. The returned query queries for
|
117
|
+
# the intersection between the two inputs.
|
118
|
+
#
|
119
|
+
# Both queries should be resolved.
|
120
|
+
#
|
121
|
+
# @param other [Query]
|
122
|
+
# @return [Query?] The merged query, or nil if there is no intersection.
|
123
|
+
def merge(other)
|
124
|
+
m1, t1 = resolved_modifier.downcase, resolved_type.downcase
|
125
|
+
m2, t2 = other.resolved_modifier.downcase, other.resolved_type.downcase
|
126
|
+
t1 = t2 if t1.empty?
|
127
|
+
t2 = t1 if t2.empty?
|
128
|
+
if (m1 == 'not') ^ (m2 == 'not')
|
129
|
+
return if t1 == t2
|
130
|
+
type = m1 == 'not' ? t2 : t1
|
131
|
+
mod = m1 == 'not' ? m2 : m1
|
132
|
+
elsif m1 == 'not' && m2 == 'not'
|
133
|
+
# CSS has no way of representing "neither screen nor print"
|
134
|
+
return unless t1 == t2
|
135
|
+
type = t1
|
136
|
+
mod = 'not'
|
137
|
+
elsif t1 != t2
|
138
|
+
return
|
139
|
+
else # t1 == t2, neither m1 nor m2 are "not"
|
140
|
+
type = t1
|
141
|
+
mod = m1.empty? ? m2 : m1
|
142
|
+
end
|
143
|
+
Query.new([mod], [type], other.expressions + expressions)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the CSS for the media query.
|
147
|
+
#
|
148
|
+
# @return [String]
|
149
|
+
def to_css
|
150
|
+
css = ''
|
151
|
+
css << resolved_modifier
|
152
|
+
css << ' ' unless resolved_modifier.empty?
|
153
|
+
css << resolved_type
|
154
|
+
css << ' and ' unless resolved_type.empty? || expressions.empty?
|
155
|
+
css << expressions.map do |e|
|
156
|
+
# It's possible for there to be script nodes in Expressions even when
|
157
|
+
# we're converting to CSS in the case where we parsed the document as
|
158
|
+
# CSS originally (as in css_test.rb).
|
159
|
+
e.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.to_sass : c.to_s}.join
|
160
|
+
end.join(' and ')
|
161
|
+
css
|
162
|
+
end
|
163
|
+
|
164
|
+
# Returns the Sass/SCSS code for the media query.
|
165
|
+
#
|
166
|
+
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
|
167
|
+
# @return [String]
|
168
|
+
def to_src(options)
|
169
|
+
src = ''
|
170
|
+
src << Sass::Media._interp_to_src(modifier, options)
|
171
|
+
src << ' ' unless modifier.empty?
|
172
|
+
src << Sass::Media._interp_to_src(type, options)
|
173
|
+
src << ' and ' unless type.empty? || expressions.empty?
|
174
|
+
src << expressions.map do |e|
|
175
|
+
Sass::Media._interp_to_src(e, options)
|
176
|
+
end.join(' and ')
|
177
|
+
src
|
178
|
+
end
|
179
|
+
|
180
|
+
# @see \{MediaQuery#to\_a}
|
181
|
+
def to_a
|
182
|
+
res = []
|
183
|
+
res += modifier
|
184
|
+
res << ' ' unless modifier.empty?
|
185
|
+
res += type
|
186
|
+
res << ' and ' unless type.empty? || expressions.empty?
|
187
|
+
res += Sass::Util.intersperse(expressions, ' and ').flatten
|
188
|
+
res
|
189
|
+
end
|
190
|
+
|
191
|
+
# Returns a deep copy of this query and all its children.
|
192
|
+
#
|
193
|
+
# @return [Query]
|
194
|
+
def deep_copy
|
195
|
+
Query.new(
|
196
|
+
modifier.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c},
|
197
|
+
type.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c},
|
198
|
+
expressions.map {|e| e.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}})
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Converts an interpolation array to source.
|
203
|
+
#
|
204
|
+
# @param interp [Array<String, Sass::Script::Tree::Node>] The interpolation array to convert.
|
205
|
+
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
|
206
|
+
# @return [String]
|
207
|
+
def self._interp_to_src(interp, options)
|
208
|
+
interp.map do |r|
|
209
|
+
next r if r.is_a?(String)
|
210
|
+
"\#{#{r.to_sass(options)}}"
|
211
|
+
end.join
|
212
|
+
end
|
213
|
+
end
|