aliddle-sass 1.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.
- data/.yardopts +11 -0
- data/CONTRIBUTING +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +201 -0
- data/Rakefile +347 -0
- data/VERSION +1 -0
- data/VERSION_NAME +1 -0
- data/bin/sass +9 -0
- data/bin/sass-convert +8 -0
- data/bin/scss +9 -0
- data/extra/update_watch.rb +13 -0
- data/init.rb +18 -0
- data/lib/sass.rb +95 -0
- data/lib/sass/cache_stores.rb +15 -0
- data/lib/sass/cache_stores/base.rb +88 -0
- data/lib/sass/cache_stores/chain.rb +33 -0
- data/lib/sass/cache_stores/filesystem.rb +60 -0
- data/lib/sass/cache_stores/memory.rb +47 -0
- data/lib/sass/cache_stores/null.rb +25 -0
- data/lib/sass/callbacks.rb +66 -0
- data/lib/sass/css.rb +409 -0
- data/lib/sass/engine.rb +928 -0
- data/lib/sass/environment.rb +101 -0
- data/lib/sass/error.rb +201 -0
- data/lib/sass/exec.rb +707 -0
- data/lib/sass/importers.rb +22 -0
- data/lib/sass/importers/base.rb +139 -0
- data/lib/sass/importers/filesystem.rb +190 -0
- data/lib/sass/logger.rb +15 -0
- data/lib/sass/logger/base.rb +32 -0
- data/lib/sass/logger/log_level.rb +49 -0
- data/lib/sass/media.rb +213 -0
- data/lib/sass/plugin.rb +132 -0
- data/lib/sass/plugin/compiler.rb +406 -0
- data/lib/sass/plugin/configuration.rb +123 -0
- data/lib/sass/plugin/generic.rb +15 -0
- data/lib/sass/plugin/merb.rb +48 -0
- data/lib/sass/plugin/rack.rb +60 -0
- data/lib/sass/plugin/rails.rb +47 -0
- data/lib/sass/plugin/staleness_checker.rb +183 -0
- data/lib/sass/railtie.rb +9 -0
- data/lib/sass/repl.rb +57 -0
- data/lib/sass/root.rb +7 -0
- data/lib/sass/script.rb +39 -0
- data/lib/sass/script/arg_list.rb +52 -0
- data/lib/sass/script/bool.rb +18 -0
- data/lib/sass/script/color.rb +606 -0
- data/lib/sass/script/css_lexer.rb +29 -0
- data/lib/sass/script/css_parser.rb +31 -0
- data/lib/sass/script/funcall.rb +237 -0
- data/lib/sass/script/functions.rb +1543 -0
- data/lib/sass/script/interpolation.rb +79 -0
- data/lib/sass/script/lexer.rb +348 -0
- data/lib/sass/script/list.rb +85 -0
- data/lib/sass/script/literal.rb +221 -0
- data/lib/sass/script/node.rb +99 -0
- data/lib/sass/script/null.rb +37 -0
- data/lib/sass/script/number.rb +453 -0
- data/lib/sass/script/operation.rb +110 -0
- data/lib/sass/script/parser.rb +495 -0
- data/lib/sass/script/string.rb +51 -0
- data/lib/sass/script/string_interpolation.rb +103 -0
- data/lib/sass/script/unary_operation.rb +69 -0
- data/lib/sass/script/variable.rb +58 -0
- data/lib/sass/scss.rb +16 -0
- data/lib/sass/scss/css_parser.rb +36 -0
- data/lib/sass/scss/parser.rb +1179 -0
- data/lib/sass/scss/rx.rb +133 -0
- data/lib/sass/scss/script_lexer.rb +15 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/scss/static_parser.rb +54 -0
- data/lib/sass/selector.rb +452 -0
- data/lib/sass/selector/abstract_sequence.rb +94 -0
- data/lib/sass/selector/comma_sequence.rb +92 -0
- data/lib/sass/selector/sequence.rb +507 -0
- data/lib/sass/selector/simple.rb +119 -0
- data/lib/sass/selector/simple_sequence.rb +212 -0
- data/lib/sass/shared.rb +76 -0
- data/lib/sass/supports.rb +229 -0
- data/lib/sass/tree/charset_node.rb +22 -0
- data/lib/sass/tree/comment_node.rb +82 -0
- 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 +18 -0
- data/lib/sass/tree/directive_node.rb +42 -0
- data/lib/sass/tree/each_node.rb +24 -0
- data/lib/sass/tree/extend_node.rb +36 -0
- data/lib/sass/tree/for_node.rb +36 -0
- data/lib/sass/tree/function_node.rb +34 -0
- data/lib/sass/tree/if_node.rb +52 -0
- data/lib/sass/tree/import_node.rb +75 -0
- data/lib/sass/tree/media_node.rb +58 -0
- data/lib/sass/tree/mixin_def_node.rb +38 -0
- data/lib/sass/tree/mixin_node.rb +39 -0
- data/lib/sass/tree/node.rb +196 -0
- data/lib/sass/tree/prop_node.rb +152 -0
- data/lib/sass/tree/return_node.rb +18 -0
- data/lib/sass/tree/root_node.rb +28 -0
- data/lib/sass/tree/rule_node.rb +132 -0
- data/lib/sass/tree/supports_node.rb +51 -0
- data/lib/sass/tree/trace_node.rb +32 -0
- data/lib/sass/tree/variable_node.rb +30 -0
- data/lib/sass/tree/visitors/base.rb +75 -0
- data/lib/sass/tree/visitors/check_nesting.rb +147 -0
- data/lib/sass/tree/visitors/convert.rb +316 -0
- data/lib/sass/tree/visitors/cssize.rb +229 -0
- 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 +446 -0
- data/lib/sass/tree/visitors/set_options.rb +125 -0
- data/lib/sass/tree/visitors/to_css.rb +230 -0
- data/lib/sass/tree/warn_node.rb +18 -0
- data/lib/sass/tree/while_node.rb +18 -0
- data/lib/sass/util.rb +906 -0
- data/lib/sass/util/multibyte_string_scanner.rb +155 -0
- data/lib/sass/util/subset_map.rb +109 -0
- data/lib/sass/util/test.rb +10 -0
- data/lib/sass/version.rb +126 -0
- data/rails/init.rb +1 -0
- data/test/Gemfile +3 -0
- data/test/Gemfile.lock +10 -0
- data/test/sass/cache_test.rb +89 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +1760 -0
- data/test/sass/css2sass_test.rb +439 -0
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +3243 -0
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +1461 -0
- 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 +1139 -0
- data/test/sass/importer_test.rb +192 -0
- data/test/sass/logger_test.rb +58 -0
- data/test/sass/mock_importer.rb +49 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +550 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +86 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/filename_fn.css +3 -0
- data/test/sass/results/if.css +3 -0
- data/test/sass/results/import.css +31 -0
- data/test/sass/results/import_charset.css +5 -0
- data/test/sass/results/import_charset_1_8.css +5 -0
- data/test/sass/results/import_charset_ibm866.css +5 -0
- data/test/sass/results/import_content.css +1 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/options.css +1 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/scss_import.css +31 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +299 -0
- data/test/sass/script_test.rb +591 -0
- data/test/sass/scss/css_test.rb +1093 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +2043 -0
- data/test/sass/scss/test_helper.rb +37 -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_charset_ibm866.sass +4 -0
- data/test/sass/templates/_imported_charset_utf8.sass +4 -0
- data/test/sass/templates/_imported_content.sass +3 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork1.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +305 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/double_import_loop1.sass +1 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/filename_fn.scss +18 -0
- data/test/sass/templates/if.sass +11 -0
- data/test/sass/templates/import.sass +12 -0
- data/test/sass/templates/import_charset.sass +9 -0
- data/test/sass/templates/import_charset_1_8.sass +6 -0
- data/test/sass/templates/import_charset_ibm866.sass +11 -0
- data/test/sass/templates/import_content.sass +4 -0
- data/test/sass/templates/importee.less +2 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- data/test/sass/templates/nested_bork1.sass +2 -0
- data/test/sass/templates/nested_bork2.sass +2 -0
- data/test/sass/templates/nested_bork3.sass +2 -0
- data/test/sass/templates/nested_bork4.sass +2 -0
- data/test/sass/templates/nested_import.sass +2 -0
- data/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- data/test/sass/templates/parent_ref.sass +25 -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/script.sass +101 -0
- data/test/sass/templates/scss_import.scss +11 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/single_import_loop.sass +1 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/sass/templates/warn.sass +3 -0
- data/test/sass/templates/warn_imported.sass +4 -0
- data/test/sass/test_helper.rb +8 -0
- data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
- data/test/sass/util/subset_map_test.rb +91 -0
- data/test/sass/util_test.rb +313 -0
- data/test/test_helper.rb +80 -0
- metadata +348 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
require 'strscan'
|
|
2
|
+
|
|
3
|
+
if Sass::Util.ruby1_8?
|
|
4
|
+
Sass::Util::MultibyteStringScanner = StringScanner
|
|
5
|
+
else
|
|
6
|
+
if Sass::Util.rbx?
|
|
7
|
+
# Rubinius's StringScanner class implements some of its methods in terms of
|
|
8
|
+
# others, which causes us to double-count bytes in some cases if we do
|
|
9
|
+
# straightforward inheritance. To work around this, we use a delegate class.
|
|
10
|
+
require 'delegate'
|
|
11
|
+
class Sass::Util::MultibyteStringScanner < DelegateClass(StringScanner)
|
|
12
|
+
def initialize(str)
|
|
13
|
+
super(StringScanner.new(str))
|
|
14
|
+
@mb_pos = 0
|
|
15
|
+
@mb_matched_size = nil
|
|
16
|
+
@mb_last_pos = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def is_a?(klass)
|
|
20
|
+
__getobj__.is_a?(klass) || super
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
class Sass::Util::MultibyteStringScanner < StringScanner
|
|
25
|
+
def initialize(str)
|
|
26
|
+
super
|
|
27
|
+
@mb_pos = 0
|
|
28
|
+
@mb_matched_size = nil
|
|
29
|
+
@mb_last_pos = nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# A wrapper of the native StringScanner class that works correctly with
|
|
35
|
+
# multibyte character encodings. The native class deals only in bytes, not
|
|
36
|
+
# characters, for methods like [#pos] and [#matched_size]. This class deals
|
|
37
|
+
# only in characters, instead.
|
|
38
|
+
class Sass::Util::MultibyteStringScanner
|
|
39
|
+
def self.new(str)
|
|
40
|
+
return StringScanner.new(str) if str.ascii_only?
|
|
41
|
+
super
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
alias_method :byte_pos, :pos
|
|
45
|
+
alias_method :byte_matched_size, :matched_size
|
|
46
|
+
|
|
47
|
+
def check(pattern); _match super; end
|
|
48
|
+
def check_until(pattern); _matched super; end
|
|
49
|
+
def getch; _forward _match super; end
|
|
50
|
+
def match?(pattern); _size check(pattern); end
|
|
51
|
+
def matched_size; @mb_matched_size; end
|
|
52
|
+
def peek(len); string[@mb_pos, len]; end
|
|
53
|
+
alias_method :peep, :peek
|
|
54
|
+
def pos; @mb_pos; end
|
|
55
|
+
alias_method :pointer, :pos
|
|
56
|
+
def rest_size; rest.size; end
|
|
57
|
+
def scan(pattern); _forward _match super; end
|
|
58
|
+
def scan_until(pattern); _forward _matched super; end
|
|
59
|
+
def skip(pattern); _size scan(pattern); end
|
|
60
|
+
def skip_until(pattern); _matched _size scan_until(pattern); end
|
|
61
|
+
|
|
62
|
+
def get_byte
|
|
63
|
+
raise "MultibyteStringScanner doesn't support #get_byte."
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def getbyte
|
|
67
|
+
raise "MultibyteStringScanner doesn't support #getbyte."
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def pos=(n)
|
|
71
|
+
@mb_last_pos = nil
|
|
72
|
+
|
|
73
|
+
# We set position kind of a lot during parsing, so we want it to be as
|
|
74
|
+
# efficient as possible. This is complicated by the fact that UTF-8 is a
|
|
75
|
+
# variable-length encoding, so it's difficult to find the byte length that
|
|
76
|
+
# corresponds to a given character length.
|
|
77
|
+
#
|
|
78
|
+
# Our heuristic here is to try to count the fewest possible characters. So
|
|
79
|
+
# if the new position is close to the current one, just count the
|
|
80
|
+
# characters between the two; if the new position is closer to the
|
|
81
|
+
# beginning of the string, just count the characters from there.
|
|
82
|
+
if @mb_pos - n < @mb_pos / 2
|
|
83
|
+
# New position is close to old position
|
|
84
|
+
byte_delta = @mb_pos > n ? -string[n...@mb_pos].bytesize : string[@mb_pos...n].bytesize
|
|
85
|
+
super(byte_pos + byte_delta)
|
|
86
|
+
else
|
|
87
|
+
# New position is close to BOS
|
|
88
|
+
super(string[0...n].bytesize)
|
|
89
|
+
end
|
|
90
|
+
@mb_pos = n
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def reset
|
|
94
|
+
@mb_pos = 0
|
|
95
|
+
@mb_matched_size = nil
|
|
96
|
+
@mb_last_pos = nil
|
|
97
|
+
super
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def scan_full(pattern, advance_pointer_p, return_string_p)
|
|
101
|
+
res = _match super(pattern, advance_pointer_p, true)
|
|
102
|
+
_forward res if advance_pointer_p
|
|
103
|
+
return res if return_string_p
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def search_full(pattern, advance_pointer_p, return_string_p)
|
|
107
|
+
res = super(pattern, advance_pointer_p, true)
|
|
108
|
+
_forward res if advance_pointer_p
|
|
109
|
+
_matched((res if return_string_p))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def string=(str)
|
|
113
|
+
@mb_pos = 0
|
|
114
|
+
@mb_matched_size = nil
|
|
115
|
+
@mb_last_pos = nil
|
|
116
|
+
super
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def terminate
|
|
120
|
+
@mb_pos = string.size
|
|
121
|
+
@mb_matched_size = nil
|
|
122
|
+
@mb_last_pos = nil
|
|
123
|
+
super
|
|
124
|
+
end
|
|
125
|
+
alias_method :clear, :terminate
|
|
126
|
+
|
|
127
|
+
def unscan
|
|
128
|
+
super
|
|
129
|
+
@mb_pos = @mb_last_pos
|
|
130
|
+
@mb_last_pos = @mb_matched_size = nil
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def _size(str)
|
|
136
|
+
str && str.size
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def _match(str)
|
|
140
|
+
@mb_matched_size = str && str.size
|
|
141
|
+
str
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def _matched(res)
|
|
145
|
+
_match matched
|
|
146
|
+
res
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def _forward(str)
|
|
150
|
+
@mb_last_pos = @mb_pos
|
|
151
|
+
@mb_pos += str.size if str
|
|
152
|
+
str
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
module Sass
|
|
4
|
+
module Util
|
|
5
|
+
# A map from sets to values.
|
|
6
|
+
# A value is \{#\[]= set} by providing a set (the "set-set") and a value,
|
|
7
|
+
# which is then recorded as corresponding to that set.
|
|
8
|
+
# Values are \{#\[] accessed} by providing a set (the "get-set")
|
|
9
|
+
# and returning all values that correspond to set-sets
|
|
10
|
+
# that are subsets of the get-set.
|
|
11
|
+
#
|
|
12
|
+
# SubsetMap preserves the order of values as they're inserted.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# ssm = SubsetMap.new
|
|
16
|
+
# ssm[Set[1, 2]] = "Foo"
|
|
17
|
+
# ssm[Set[2, 3]] = "Bar"
|
|
18
|
+
# ssm[Set[1, 2, 3]] = "Baz"
|
|
19
|
+
#
|
|
20
|
+
# ssm[Set[1, 2, 3]] #=> ["Foo", "Bar", "Baz"]
|
|
21
|
+
class SubsetMap
|
|
22
|
+
# Creates a new, empty SubsetMap.
|
|
23
|
+
def initialize
|
|
24
|
+
@hash = {}
|
|
25
|
+
@vals = []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Whether or not this SubsetMap has any key-value pairs.
|
|
29
|
+
#
|
|
30
|
+
# @return [Boolean]
|
|
31
|
+
def empty?
|
|
32
|
+
@hash.empty?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Associates a value with a set.
|
|
36
|
+
# When `set` or any of its supersets is accessed,
|
|
37
|
+
# `value` will be among the values returned.
|
|
38
|
+
#
|
|
39
|
+
# Note that if the same `set` is passed to this method multiple times,
|
|
40
|
+
# all given `value`s will be associated with that `set`.
|
|
41
|
+
#
|
|
42
|
+
# This runs in `O(n)` time, where `n` is the size of `set`.
|
|
43
|
+
#
|
|
44
|
+
# @param set [#to_set] The set to use as the map key. May not be empty.
|
|
45
|
+
# @param value [Object] The value to associate with `set`.
|
|
46
|
+
# @raise [ArgumentError] If `set` is empty.
|
|
47
|
+
def []=(set, value)
|
|
48
|
+
raise ArgumentError.new("SubsetMap keys may not be empty.") if set.empty?
|
|
49
|
+
|
|
50
|
+
index = @vals.size
|
|
51
|
+
@vals << value
|
|
52
|
+
set.each do |k|
|
|
53
|
+
@hash[k] ||= []
|
|
54
|
+
@hash[k] << [set, set.to_set, index]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns all values associated with subsets of `set`.
|
|
59
|
+
#
|
|
60
|
+
# In the worst case, this runs in `O(m*max(n, log m))` time,
|
|
61
|
+
# where `n` is the size of `set`
|
|
62
|
+
# and `m` is the number of assocations in the map.
|
|
63
|
+
# However, unless many keys in the map overlap with `set`,
|
|
64
|
+
# `m` will typically be much smaller.
|
|
65
|
+
#
|
|
66
|
+
# @param set [Set] The set to use as the map key.
|
|
67
|
+
# @return [Array<(Object, #to_set)>] An array of pairs,
|
|
68
|
+
# where the first value is the value associated with a subset of `set`,
|
|
69
|
+
# and the second value is that subset of `set`
|
|
70
|
+
# (or whatever `#to_set` object was used to set the value)
|
|
71
|
+
# This array is in insertion order.
|
|
72
|
+
# @see #[]
|
|
73
|
+
def get(set)
|
|
74
|
+
res = set.map do |k|
|
|
75
|
+
next unless subsets = @hash[k]
|
|
76
|
+
subsets.map do |subenum, subset, index|
|
|
77
|
+
next unless subset.subset?(set)
|
|
78
|
+
[index, subenum]
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
res = Sass::Util.flatten(res, 1)
|
|
82
|
+
res.compact!
|
|
83
|
+
res.uniq!
|
|
84
|
+
res.sort!
|
|
85
|
+
res.map! {|i, s| [@vals[i], s]}
|
|
86
|
+
return res
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Same as \{#get}, but doesn't return the subsets of the argument
|
|
90
|
+
# for which values were found.
|
|
91
|
+
#
|
|
92
|
+
# @param set [Set] The set to use as the map key.
|
|
93
|
+
# @return [Array] The array of all values
|
|
94
|
+
# associated with subsets of `set`, in insertion order.
|
|
95
|
+
# @see #get
|
|
96
|
+
def [](set)
|
|
97
|
+
get(set).map {|v, _| v}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Iterates over each value in the subset map. Ignores keys completely. If
|
|
101
|
+
# multiple keys have the same value, this will return them multiple times.
|
|
102
|
+
#
|
|
103
|
+
# @yield [Object] Each value in the map.
|
|
104
|
+
def each_value
|
|
105
|
+
@vals.each {|v| yield v}
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
data/lib/sass/version.rb
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
|
|
3
|
+
# This is necessary for loading Sass when Haml is required in Rails 3.
|
|
4
|
+
# Once the split is complete, we can remove it.
|
|
5
|
+
require File.dirname(__FILE__) + '/../sass'
|
|
6
|
+
require 'sass/util'
|
|
7
|
+
|
|
8
|
+
module Sass
|
|
9
|
+
# Handles Sass version-reporting.
|
|
10
|
+
# Sass not only reports the standard three version numbers,
|
|
11
|
+
# but its Git revision hash as well,
|
|
12
|
+
# if it was installed from Git.
|
|
13
|
+
module Version
|
|
14
|
+
include Sass::Util
|
|
15
|
+
|
|
16
|
+
# Returns a hash representing the version of Sass.
|
|
17
|
+
# The `:major`, `:minor`, and `:teeny` keys have their respective numbers as Fixnums.
|
|
18
|
+
# The `:name` key has the name of the version.
|
|
19
|
+
# The `:string` key contains a human-readable string representation of the version.
|
|
20
|
+
# The `:number` key is the major, minor, and teeny keys separated by periods.
|
|
21
|
+
# The `:date` key, which is not guaranteed to be defined, is the [DateTime] at which this release was cut.
|
|
22
|
+
# If Sass is checked out from Git, the `:rev` key will have the revision hash.
|
|
23
|
+
# For example:
|
|
24
|
+
#
|
|
25
|
+
# {
|
|
26
|
+
# :string => "2.1.0.9616393",
|
|
27
|
+
# :rev => "9616393b8924ef36639c7e82aa88a51a24d16949",
|
|
28
|
+
# :number => "2.1.0",
|
|
29
|
+
# :date => DateTime.parse("Apr 30 13:52:01 2009 -0700"),
|
|
30
|
+
# :major => 2, :minor => 1, :teeny => 0
|
|
31
|
+
# }
|
|
32
|
+
#
|
|
33
|
+
# If a prerelease version of Sass is being used,
|
|
34
|
+
# the `:string` and `:number` fields will reflect the full version
|
|
35
|
+
# (e.g. `"2.2.beta.1"`), and the `:teeny` field will be `-1`.
|
|
36
|
+
# A `:prerelease` key will contain the name of the prerelease (e.g. `"beta"`),
|
|
37
|
+
# and a `:prerelease_number` key will contain the rerelease number.
|
|
38
|
+
# For example:
|
|
39
|
+
#
|
|
40
|
+
# {
|
|
41
|
+
# :string => "3.0.beta.1",
|
|
42
|
+
# :number => "3.0.beta.1",
|
|
43
|
+
# :date => DateTime.parse("Mar 31 00:38:04 2010 -0700"),
|
|
44
|
+
# :major => 3, :minor => 0, :teeny => -1,
|
|
45
|
+
# :prerelease => "beta",
|
|
46
|
+
# :prerelease_number => 1
|
|
47
|
+
# }
|
|
48
|
+
#
|
|
49
|
+
# @return [{Symbol => String/Fixnum}] The version hash
|
|
50
|
+
def version
|
|
51
|
+
return @@version if defined?(@@version)
|
|
52
|
+
|
|
53
|
+
numbers = File.read(scope('VERSION')).strip.split('.').
|
|
54
|
+
map {|n| n =~ /^[0-9]+$/ ? n.to_i : n}
|
|
55
|
+
name = File.read(scope('VERSION_NAME')).strip
|
|
56
|
+
@@version = {
|
|
57
|
+
:major => numbers[0],
|
|
58
|
+
:minor => numbers[1],
|
|
59
|
+
:teeny => numbers[2],
|
|
60
|
+
:name => name
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if date = version_date
|
|
64
|
+
@@version[:date] = date
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if numbers[3].is_a?(String)
|
|
68
|
+
@@version[:teeny] = -1
|
|
69
|
+
@@version[:prerelease] = numbers[3]
|
|
70
|
+
@@version[:prerelease_number] = numbers[4]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
@@version[:number] = numbers.join('.')
|
|
74
|
+
@@version[:string] = @@version[:number].dup
|
|
75
|
+
|
|
76
|
+
if rev = revision_number
|
|
77
|
+
@@version[:rev] = rev
|
|
78
|
+
unless rev[0] == ?(
|
|
79
|
+
@@version[:string] << "." << rev[0...7]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
@@version[:string] << " (#{name})"
|
|
84
|
+
@@version
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def revision_number
|
|
90
|
+
if File.exists?(scope('REVISION'))
|
|
91
|
+
rev = File.read(scope('REVISION')).strip
|
|
92
|
+
return rev unless rev =~ /^([a-f0-9]+|\(.*\))$/ || rev == '(unknown)'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
return unless File.exists?(scope('.git/HEAD'))
|
|
96
|
+
rev = File.read(scope('.git/HEAD')).strip
|
|
97
|
+
return rev unless rev =~ /^ref: (.*)$/
|
|
98
|
+
|
|
99
|
+
ref_name = $1
|
|
100
|
+
ref_file = scope(".git/#{ref_name}")
|
|
101
|
+
info_file = scope(".git/info/refs")
|
|
102
|
+
return File.read(ref_file).strip if File.exists?(ref_file)
|
|
103
|
+
return unless File.exists?(info_file)
|
|
104
|
+
File.open(info_file) do |f|
|
|
105
|
+
f.each do |l|
|
|
106
|
+
sha, ref = l.strip.split("\t", 2)
|
|
107
|
+
next unless ref == ref_name
|
|
108
|
+
return sha
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
return nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def version_date
|
|
115
|
+
return unless File.exists?(scope('VERSION_DATE'))
|
|
116
|
+
return DateTime.parse(File.read(scope('VERSION_DATE')).strip)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
extend Sass::Version
|
|
121
|
+
|
|
122
|
+
# A string representing the version of Sass.
|
|
123
|
+
# A more fine-grained representation is available from Sass.version.
|
|
124
|
+
# @api public
|
|
125
|
+
VERSION = version[:string] unless defined?(Sass::VERSION)
|
|
126
|
+
end
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Kernel.load File.join(File.dirname(__FILE__), '..', 'init.rb')
|
data/test/Gemfile
ADDED
data/test/Gemfile.lock
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
3
|
+
require File.dirname(__FILE__) + '/test_helper'
|
|
4
|
+
require 'sass/engine'
|
|
5
|
+
|
|
6
|
+
class CacheTest < Test::Unit::TestCase
|
|
7
|
+
@@cache_dir = "tmp/file_cache"
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
FileUtils.mkdir_p @@cache_dir
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def teardown
|
|
14
|
+
FileUtils.rm_rf @@cache_dir
|
|
15
|
+
clean_up_sassc
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_file_cache_writes_a_file
|
|
19
|
+
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
|
20
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
|
21
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_file_cache_reads_a_file
|
|
25
|
+
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
|
26
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
27
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
|
28
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
29
|
+
assert_kind_of Sass::Tree::RootNode, file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_file_cache_miss_returns_nil
|
|
33
|
+
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
|
34
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
35
|
+
assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_sha_change_invalidates_cache_and_cleans_up
|
|
39
|
+
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
|
40
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
41
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
|
42
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
43
|
+
assert_nil file_store.retrieve("asdf/foo.scssc", "differentsha1")
|
|
44
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_version_change_invalidates_cache_and_cleans_up
|
|
48
|
+
file_store = Sass::CacheStores::Filesystem.new(@@cache_dir)
|
|
49
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
50
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
|
51
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
52
|
+
real_version = Sass::VERSION
|
|
53
|
+
begin
|
|
54
|
+
Sass::VERSION.replace("a different version")
|
|
55
|
+
assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
|
56
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
|
57
|
+
ensure
|
|
58
|
+
Sass::VERSION.replace(real_version)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_arbitrary_objects_can_go_into_cache
|
|
63
|
+
cache = Sass::CacheStores::Memory.new
|
|
64
|
+
an_object = {:foo => :bar}
|
|
65
|
+
cache.store("an_object", "", an_object)
|
|
66
|
+
assert_equal an_object, cache.retrieve("an_object", "")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class Unmarshalable
|
|
70
|
+
def _dump(_)
|
|
71
|
+
raise 'Unmarshalable'
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_cache_node_with_unmarshalable_option
|
|
76
|
+
engine = Sass::Engine.new("foo {a: b + c}",
|
|
77
|
+
:syntax => :scss, :object => Unmarshalable.new, :filename => 'file.scss',
|
|
78
|
+
:importer => Sass::Importers::Filesystem.new(absolutize('templates')))
|
|
79
|
+
engine.to_tree
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
def root_node
|
|
84
|
+
Sass::Engine.new(<<-SCSS, :syntax => :scss).to_tree
|
|
85
|
+
@mixin color($c) { color: $c}
|
|
86
|
+
div { @include color(red); }
|
|
87
|
+
SCSS
|
|
88
|
+
end
|
|
89
|
+
end
|