oreorenasass 3.4.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.
Files changed (268) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +11 -0
  3. data/CONTRIBUTING +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +221 -0
  6. data/Rakefile +370 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/sass +13 -0
  10. data/bin/sass-convert +12 -0
  11. data/bin/scss +13 -0
  12. data/extra/update_watch.rb +13 -0
  13. data/init.rb +18 -0
  14. data/lib/sass/cache_stores/base.rb +88 -0
  15. data/lib/sass/cache_stores/chain.rb +34 -0
  16. data/lib/sass/cache_stores/filesystem.rb +60 -0
  17. data/lib/sass/cache_stores/memory.rb +47 -0
  18. data/lib/sass/cache_stores/null.rb +25 -0
  19. data/lib/sass/cache_stores.rb +15 -0
  20. data/lib/sass/callbacks.rb +67 -0
  21. data/lib/sass/css.rb +407 -0
  22. data/lib/sass/engine.rb +1181 -0
  23. data/lib/sass/environment.rb +191 -0
  24. data/lib/sass/error.rb +198 -0
  25. data/lib/sass/exec/base.rb +187 -0
  26. data/lib/sass/exec/sass_convert.rb +264 -0
  27. data/lib/sass/exec/sass_scss.rb +424 -0
  28. data/lib/sass/exec.rb +9 -0
  29. data/lib/sass/features.rb +47 -0
  30. data/lib/sass/importers/base.rb +182 -0
  31. data/lib/sass/importers/filesystem.rb +211 -0
  32. data/lib/sass/importers.rb +22 -0
  33. data/lib/sass/logger/base.rb +30 -0
  34. data/lib/sass/logger/log_level.rb +45 -0
  35. data/lib/sass/logger.rb +12 -0
  36. data/lib/sass/media.rb +210 -0
  37. data/lib/sass/plugin/compiler.rb +565 -0
  38. data/lib/sass/plugin/configuration.rb +118 -0
  39. data/lib/sass/plugin/generic.rb +15 -0
  40. data/lib/sass/plugin/merb.rb +48 -0
  41. data/lib/sass/plugin/rack.rb +60 -0
  42. data/lib/sass/plugin/rails.rb +47 -0
  43. data/lib/sass/plugin/staleness_checker.rb +199 -0
  44. data/lib/sass/plugin.rb +133 -0
  45. data/lib/sass/railtie.rb +10 -0
  46. data/lib/sass/repl.rb +57 -0
  47. data/lib/sass/root.rb +7 -0
  48. data/lib/sass/script/css_lexer.rb +33 -0
  49. data/lib/sass/script/css_parser.rb +34 -0
  50. data/lib/sass/script/functions.rb +2626 -0
  51. data/lib/sass/script/lexer.rb +449 -0
  52. data/lib/sass/script/parser.rb +637 -0
  53. data/lib/sass/script/tree/funcall.rb +306 -0
  54. data/lib/sass/script/tree/interpolation.rb +118 -0
  55. data/lib/sass/script/tree/list_literal.rb +77 -0
  56. data/lib/sass/script/tree/literal.rb +45 -0
  57. data/lib/sass/script/tree/map_literal.rb +64 -0
  58. data/lib/sass/script/tree/node.rb +109 -0
  59. data/lib/sass/script/tree/operation.rb +103 -0
  60. data/lib/sass/script/tree/selector.rb +26 -0
  61. data/lib/sass/script/tree/string_interpolation.rb +104 -0
  62. data/lib/sass/script/tree/unary_operation.rb +69 -0
  63. data/lib/sass/script/tree/variable.rb +57 -0
  64. data/lib/sass/script/tree.rb +16 -0
  65. data/lib/sass/script/value/arg_list.rb +36 -0
  66. data/lib/sass/script/value/base.rb +240 -0
  67. data/lib/sass/script/value/bool.rb +35 -0
  68. data/lib/sass/script/value/color.rb +680 -0
  69. data/lib/sass/script/value/helpers.rb +262 -0
  70. data/lib/sass/script/value/list.rb +113 -0
  71. data/lib/sass/script/value/map.rb +70 -0
  72. data/lib/sass/script/value/null.rb +44 -0
  73. data/lib/sass/script/value/number.rb +530 -0
  74. data/lib/sass/script/value/string.rb +97 -0
  75. data/lib/sass/script/value.rb +11 -0
  76. data/lib/sass/script.rb +66 -0
  77. data/lib/sass/scss/css_parser.rb +42 -0
  78. data/lib/sass/scss/parser.rb +1209 -0
  79. data/lib/sass/scss/rx.rb +141 -0
  80. data/lib/sass/scss/script_lexer.rb +15 -0
  81. data/lib/sass/scss/script_parser.rb +25 -0
  82. data/lib/sass/scss/static_parser.rb +368 -0
  83. data/lib/sass/scss.rb +16 -0
  84. data/lib/sass/selector/abstract_sequence.rb +109 -0
  85. data/lib/sass/selector/comma_sequence.rb +175 -0
  86. data/lib/sass/selector/pseudo.rb +256 -0
  87. data/lib/sass/selector/sequence.rb +600 -0
  88. data/lib/sass/selector/simple.rb +117 -0
  89. data/lib/sass/selector/simple_sequence.rb +325 -0
  90. data/lib/sass/selector.rb +326 -0
  91. data/lib/sass/shared.rb +76 -0
  92. data/lib/sass/source/map.rb +210 -0
  93. data/lib/sass/source/position.rb +39 -0
  94. data/lib/sass/source/range.rb +41 -0
  95. data/lib/sass/stack.rb +120 -0
  96. data/lib/sass/supports.rb +227 -0
  97. data/lib/sass/tree/at_root_node.rb +83 -0
  98. data/lib/sass/tree/charset_node.rb +22 -0
  99. data/lib/sass/tree/comment_node.rb +82 -0
  100. data/lib/sass/tree/content_node.rb +9 -0
  101. data/lib/sass/tree/css_import_node.rb +60 -0
  102. data/lib/sass/tree/debug_node.rb +18 -0
  103. data/lib/sass/tree/directive_node.rb +59 -0
  104. data/lib/sass/tree/each_node.rb +24 -0
  105. data/lib/sass/tree/error_node.rb +18 -0
  106. data/lib/sass/tree/extend_node.rb +43 -0
  107. data/lib/sass/tree/for_node.rb +36 -0
  108. data/lib/sass/tree/function_node.rb +39 -0
  109. data/lib/sass/tree/if_node.rb +52 -0
  110. data/lib/sass/tree/import_node.rb +74 -0
  111. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  112. data/lib/sass/tree/media_node.rb +48 -0
  113. data/lib/sass/tree/mixin_def_node.rb +38 -0
  114. data/lib/sass/tree/mixin_node.rb +52 -0
  115. data/lib/sass/tree/node.rb +238 -0
  116. data/lib/sass/tree/prop_node.rb +171 -0
  117. data/lib/sass/tree/return_node.rb +19 -0
  118. data/lib/sass/tree/root_node.rb +44 -0
  119. data/lib/sass/tree/rule_node.rb +145 -0
  120. data/lib/sass/tree/supports_node.rb +38 -0
  121. data/lib/sass/tree/trace_node.rb +33 -0
  122. data/lib/sass/tree/variable_node.rb +36 -0
  123. data/lib/sass/tree/visitors/base.rb +72 -0
  124. data/lib/sass/tree/visitors/check_nesting.rb +177 -0
  125. data/lib/sass/tree/visitors/convert.rb +334 -0
  126. data/lib/sass/tree/visitors/cssize.rb +369 -0
  127. data/lib/sass/tree/visitors/deep_copy.rb +107 -0
  128. data/lib/sass/tree/visitors/extend.rb +68 -0
  129. data/lib/sass/tree/visitors/perform.rb +539 -0
  130. data/lib/sass/tree/visitors/set_options.rb +139 -0
  131. data/lib/sass/tree/visitors/to_css.rb +381 -0
  132. data/lib/sass/tree/warn_node.rb +18 -0
  133. data/lib/sass/tree/while_node.rb +18 -0
  134. data/lib/sass/util/cross_platform_random.rb +19 -0
  135. data/lib/sass/util/multibyte_string_scanner.rb +157 -0
  136. data/lib/sass/util/normalized_map.rb +130 -0
  137. data/lib/sass/util/ordered_hash.rb +192 -0
  138. data/lib/sass/util/subset_map.rb +110 -0
  139. data/lib/sass/util/test.rb +9 -0
  140. data/lib/sass/util.rb +1318 -0
  141. data/lib/sass/version.rb +124 -0
  142. data/lib/sass.rb +102 -0
  143. data/rails/init.rb +1 -0
  144. data/test/sass/cache_test.rb +131 -0
  145. data/test/sass/callbacks_test.rb +61 -0
  146. data/test/sass/compiler_test.rb +232 -0
  147. data/test/sass/conversion_test.rb +2054 -0
  148. data/test/sass/css2sass_test.rb +477 -0
  149. data/test/sass/data/hsl-rgb.txt +319 -0
  150. data/test/sass/encoding_test.rb +219 -0
  151. data/test/sass/engine_test.rb +3301 -0
  152. data/test/sass/exec_test.rb +86 -0
  153. data/test/sass/extend_test.rb +1661 -0
  154. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  155. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  156. data/test/sass/functions_test.rb +1926 -0
  157. data/test/sass/importer_test.rb +412 -0
  158. data/test/sass/logger_test.rb +58 -0
  159. data/test/sass/mock_importer.rb +49 -0
  160. data/test/sass/more_results/more1.css +9 -0
  161. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  162. data/test/sass/more_results/more_import.css +29 -0
  163. data/test/sass/more_templates/_more_partial.sass +2 -0
  164. data/test/sass/more_templates/more1.sass +23 -0
  165. data/test/sass/more_templates/more_import.sass +11 -0
  166. data/test/sass/plugin_test.rb +554 -0
  167. data/test/sass/results/alt.css +4 -0
  168. data/test/sass/results/basic.css +9 -0
  169. data/test/sass/results/cached_import_option.css +3 -0
  170. data/test/sass/results/compact.css +5 -0
  171. data/test/sass/results/complex.css +86 -0
  172. data/test/sass/results/compressed.css +1 -0
  173. data/test/sass/results/expanded.css +19 -0
  174. data/test/sass/results/filename_fn.css +3 -0
  175. data/test/sass/results/if.css +3 -0
  176. data/test/sass/results/import.css +31 -0
  177. data/test/sass/results/import_charset.css +5 -0
  178. data/test/sass/results/import_charset_1_8.css +5 -0
  179. data/test/sass/results/import_charset_ibm866.css +5 -0
  180. data/test/sass/results/import_content.css +1 -0
  181. data/test/sass/results/line_numbers.css +49 -0
  182. data/test/sass/results/mixins.css +95 -0
  183. data/test/sass/results/multiline.css +24 -0
  184. data/test/sass/results/nested.css +22 -0
  185. data/test/sass/results/options.css +1 -0
  186. data/test/sass/results/parent_ref.css +13 -0
  187. data/test/sass/results/script.css +16 -0
  188. data/test/sass/results/scss_import.css +31 -0
  189. data/test/sass/results/scss_importee.css +2 -0
  190. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  191. data/test/sass/results/subdir/subdir.css +3 -0
  192. data/test/sass/results/units.css +11 -0
  193. data/test/sass/results/warn.css +0 -0
  194. data/test/sass/results/warn_imported.css +0 -0
  195. data/test/sass/script_conversion_test.rb +328 -0
  196. data/test/sass/script_test.rb +1054 -0
  197. data/test/sass/scss/css_test.rb +1215 -0
  198. data/test/sass/scss/rx_test.rb +156 -0
  199. data/test/sass/scss/scss_test.rb +3900 -0
  200. data/test/sass/scss/test_helper.rb +37 -0
  201. data/test/sass/source_map_test.rb +977 -0
  202. data/test/sass/superselector_test.rb +191 -0
  203. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  204. data/test/sass/templates/_double_import_loop2.sass +1 -0
  205. data/test/sass/templates/_filename_fn_import.scss +11 -0
  206. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  207. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  208. data/test/sass/templates/_imported_content.sass +3 -0
  209. data/test/sass/templates/_partial.sass +2 -0
  210. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  211. data/test/sass/templates/alt.sass +16 -0
  212. data/test/sass/templates/basic.sass +23 -0
  213. data/test/sass/templates/bork1.sass +2 -0
  214. data/test/sass/templates/bork2.sass +2 -0
  215. data/test/sass/templates/bork3.sass +2 -0
  216. data/test/sass/templates/bork4.sass +2 -0
  217. data/test/sass/templates/bork5.sass +3 -0
  218. data/test/sass/templates/cached_import_option.scss +3 -0
  219. data/test/sass/templates/compact.sass +17 -0
  220. data/test/sass/templates/complex.sass +305 -0
  221. data/test/sass/templates/compressed.sass +15 -0
  222. data/test/sass/templates/double_import_loop1.sass +1 -0
  223. data/test/sass/templates/expanded.sass +17 -0
  224. data/test/sass/templates/filename_fn.scss +18 -0
  225. data/test/sass/templates/if.sass +11 -0
  226. data/test/sass/templates/import.sass +12 -0
  227. data/test/sass/templates/import_charset.sass +9 -0
  228. data/test/sass/templates/import_charset_1_8.sass +6 -0
  229. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  230. data/test/sass/templates/import_content.sass +4 -0
  231. data/test/sass/templates/importee.less +2 -0
  232. data/test/sass/templates/importee.sass +19 -0
  233. data/test/sass/templates/line_numbers.sass +13 -0
  234. data/test/sass/templates/mixin_bork.sass +5 -0
  235. data/test/sass/templates/mixins.sass +76 -0
  236. data/test/sass/templates/multiline.sass +20 -0
  237. data/test/sass/templates/nested.sass +25 -0
  238. data/test/sass/templates/nested_bork1.sass +2 -0
  239. data/test/sass/templates/nested_bork2.sass +2 -0
  240. data/test/sass/templates/nested_bork3.sass +2 -0
  241. data/test/sass/templates/nested_bork4.sass +2 -0
  242. data/test/sass/templates/nested_import.sass +2 -0
  243. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  244. data/test/sass/templates/options.sass +2 -0
  245. data/test/sass/templates/parent_ref.sass +25 -0
  246. data/test/sass/templates/same_name_different_ext.sass +2 -0
  247. data/test/sass/templates/same_name_different_ext.scss +1 -0
  248. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  249. data/test/sass/templates/script.sass +101 -0
  250. data/test/sass/templates/scss_import.scss +12 -0
  251. data/test/sass/templates/scss_importee.scss +1 -0
  252. data/test/sass/templates/single_import_loop.sass +1 -0
  253. data/test/sass/templates/subdir/import_up1.scss +1 -0
  254. data/test/sass/templates/subdir/import_up2.scss +1 -0
  255. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  256. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  257. data/test/sass/templates/subdir/subdir.sass +6 -0
  258. data/test/sass/templates/units.sass +11 -0
  259. data/test/sass/templates/warn.sass +3 -0
  260. data/test/sass/templates/warn_imported.sass +4 -0
  261. data/test/sass/test_helper.rb +8 -0
  262. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  263. data/test/sass/util/normalized_map_test.rb +51 -0
  264. data/test/sass/util/subset_map_test.rb +91 -0
  265. data/test/sass/util_test.rb +467 -0
  266. data/test/sass/value_helpers_test.rb +179 -0
  267. data/test/test_helper.rb +109 -0
  268. metadata +386 -0
@@ -0,0 +1,18 @@
1
+ module Sass
2
+ module Tree
3
+ # A dynamic node representing a Sass `@warn` statement.
4
+ #
5
+ # @see Sass::Tree
6
+ class WarnNode < Node
7
+ # The expression to print.
8
+ # @return [Script::Tree::Node]
9
+ attr_accessor :expr
10
+
11
+ # @param expr [Script::Tree::Node] The expression to print
12
+ def initialize(expr)
13
+ @expr = expr
14
+ super()
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ # A dynamic node representing a Sass `@while` loop.
5
+ #
6
+ # @see Sass::Tree
7
+ class WhileNode < Node
8
+ # The parse tree for the continuation expression.
9
+ # @return [Script::Tree::Node]
10
+ attr_accessor :expr
11
+
12
+ # @param expr [Script::Tree::Node] See \{#expr}
13
+ def initialize(expr)
14
+ @expr = expr
15
+ super()
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module Sass
2
+ module Util
3
+ # Ruby 1.8 doesn't support an actual Random class with a settable seed.
4
+ class CrossPlatformRandom
5
+ def initialize(seed = nil)
6
+ if Sass::Util.ruby1_8?
7
+ srand(seed) if seed
8
+ else
9
+ @random = seed ? ::Random.new(seed) : ::Random.new
10
+ end
11
+ end
12
+
13
+ def rand(*args)
14
+ return @random.rand(*args) if @random
15
+ Kernel.rand(*args)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,157 @@
1
+ require 'strscan'
2
+
3
+ if Sass::Util.ruby1_8?
4
+ # rubocop:disable ConstantName
5
+ Sass::Util::MultibyteStringScanner = StringScanner
6
+ # rubocop:enable ConstantName
7
+ else
8
+ if Sass::Util.rbx?
9
+ # Rubinius's StringScanner class implements some of its methods in terms of
10
+ # others, which causes us to double-count bytes in some cases if we do
11
+ # straightforward inheritance. To work around this, we use a delegate class.
12
+ require 'delegate'
13
+ class Sass::Util::MultibyteStringScanner < DelegateClass(StringScanner)
14
+ def initialize(str)
15
+ super(StringScanner.new(str))
16
+ @mb_pos = 0
17
+ @mb_matched_size = nil
18
+ @mb_last_pos = nil
19
+ end
20
+
21
+ def is_a?(klass)
22
+ __getobj__.is_a?(klass) || super
23
+ end
24
+ end
25
+ else
26
+ class Sass::Util::MultibyteStringScanner < StringScanner
27
+ def initialize(str)
28
+ super
29
+ @mb_pos = 0
30
+ @mb_matched_size = nil
31
+ @mb_last_pos = nil
32
+ end
33
+ end
34
+ end
35
+
36
+ # A wrapper of the native StringScanner class that works correctly with
37
+ # multibyte character encodings. The native class deals only in bytes, not
38
+ # characters, for methods like [#pos] and [#matched_size]. This class deals
39
+ # only in characters, instead.
40
+ class Sass::Util::MultibyteStringScanner
41
+ def self.new(str)
42
+ return StringScanner.new(str) if str.ascii_only?
43
+ super
44
+ end
45
+
46
+ alias_method :byte_pos, :pos
47
+ alias_method :byte_matched_size, :matched_size
48
+
49
+ def check(pattern); _match super; end
50
+ def check_until(pattern); _matched super; end
51
+ def getch; _forward _match super; end
52
+ def match?(pattern); _size check(pattern); end
53
+ def matched_size; @mb_matched_size; end
54
+ def peek(len); string[@mb_pos, len]; end
55
+ alias_method :peep, :peek
56
+ def pos; @mb_pos; end
57
+ alias_method :pointer, :pos
58
+ def rest_size; rest.size; end
59
+ def scan(pattern); _forward _match super; end
60
+ def scan_until(pattern); _forward _matched super; end
61
+ def skip(pattern); _size scan(pattern); end
62
+ def skip_until(pattern); _matched _size scan_until(pattern); end
63
+
64
+ def get_byte
65
+ raise "MultibyteStringScanner doesn't support #get_byte."
66
+ end
67
+
68
+ def getbyte
69
+ raise "MultibyteStringScanner doesn't support #getbyte."
70
+ end
71
+
72
+ def pos=(n)
73
+ @mb_last_pos = nil
74
+
75
+ # We set position kind of a lot during parsing, so we want it to be as
76
+ # efficient as possible. This is complicated by the fact that UTF-8 is a
77
+ # variable-length encoding, so it's difficult to find the byte length that
78
+ # corresponds to a given character length.
79
+ #
80
+ # Our heuristic here is to try to count the fewest possible characters. So
81
+ # if the new position is close to the current one, just count the
82
+ # characters between the two; if the new position is closer to the
83
+ # beginning of the string, just count the characters from there.
84
+ if @mb_pos - n < @mb_pos / 2
85
+ # New position is close to old position
86
+ byte_delta = @mb_pos > n ? -string[n...@mb_pos].bytesize : string[@mb_pos...n].bytesize
87
+ super(byte_pos + byte_delta)
88
+ else
89
+ # New position is close to BOS
90
+ super(string[0...n].bytesize)
91
+ end
92
+ @mb_pos = n
93
+ end
94
+
95
+ def reset
96
+ @mb_pos = 0
97
+ @mb_matched_size = nil
98
+ @mb_last_pos = nil
99
+ super
100
+ end
101
+
102
+ def scan_full(pattern, advance_pointer_p, return_string_p)
103
+ res = _match super(pattern, advance_pointer_p, true)
104
+ _forward res if advance_pointer_p
105
+ return res if return_string_p
106
+ end
107
+
108
+ def search_full(pattern, advance_pointer_p, return_string_p)
109
+ res = super(pattern, advance_pointer_p, true)
110
+ _forward res if advance_pointer_p
111
+ _matched((res if return_string_p))
112
+ end
113
+
114
+ def string=(str)
115
+ @mb_pos = 0
116
+ @mb_matched_size = nil
117
+ @mb_last_pos = nil
118
+ super
119
+ end
120
+
121
+ def terminate
122
+ @mb_pos = string.size
123
+ @mb_matched_size = nil
124
+ @mb_last_pos = nil
125
+ super
126
+ end
127
+ alias_method :clear, :terminate
128
+
129
+ def unscan
130
+ super
131
+ @mb_pos = @mb_last_pos
132
+ @mb_last_pos = @mb_matched_size = nil
133
+ end
134
+
135
+ private
136
+
137
+ def _size(str)
138
+ str && str.size
139
+ end
140
+
141
+ def _match(str)
142
+ @mb_matched_size = str && str.size
143
+ str
144
+ end
145
+
146
+ def _matched(res)
147
+ _match matched
148
+ res
149
+ end
150
+
151
+ def _forward(str)
152
+ @mb_last_pos = @mb_pos
153
+ @mb_pos += str.size if str
154
+ str
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,130 @@
1
+ require 'delegate'
2
+ require 'sass/util'
3
+
4
+ module Sass
5
+ module Util
6
+ # A hash that normalizes its string keys while still allowing you to get back
7
+ # to the original keys that were stored. If several different values normalize
8
+ # to the same value, whichever is stored last wins.
9
+ require 'sass/util/ordered_hash' if ruby1_8?
10
+ class NormalizedMap
11
+ # Create a normalized map
12
+ def initialize(map = nil)
13
+ @key_strings = {}
14
+ @map = Util.ruby1_8? ? OrderedHash.new : {}
15
+
16
+ map.each {|key, value| self[key] = value} if map
17
+ end
18
+
19
+ # Specifies how to transform the key.
20
+ #
21
+ # This can be overridden to create other normalization behaviors.
22
+ def normalize(key)
23
+ key.tr("-", "_")
24
+ end
25
+
26
+ # Returns the version of `key` as it was stored before
27
+ # normalization. If `key` isn't in the map, returns it as it was
28
+ # passed in.
29
+ #
30
+ # @return [String]
31
+ def denormalize(key)
32
+ @key_strings[normalize(key)] || key
33
+ end
34
+
35
+ # @private
36
+ def []=(k, v)
37
+ normalized = normalize(k)
38
+ @map[normalized] = v
39
+ @key_strings[normalized] = k
40
+ v
41
+ end
42
+
43
+ # @private
44
+ def [](k)
45
+ @map[normalize(k)]
46
+ end
47
+
48
+ # @private
49
+ def has_key?(k)
50
+ @map.has_key?(normalize(k))
51
+ end
52
+
53
+ # @private
54
+ def delete(k)
55
+ normalized = normalize(k)
56
+ @key_strings.delete(normalized)
57
+ @map.delete(normalized)
58
+ end
59
+
60
+ # @return [Hash] Hash with the keys as they were stored (before normalization).
61
+ def as_stored
62
+ Sass::Util.map_keys(@map) {|k| @key_strings[k]}
63
+ end
64
+
65
+ def empty?
66
+ @map.empty?
67
+ end
68
+
69
+ def values
70
+ @map.values
71
+ end
72
+
73
+ def keys
74
+ @map.keys
75
+ end
76
+
77
+ def each
78
+ @map.each {|k, v| yield(k, v)}
79
+ end
80
+
81
+ def size
82
+ @map.size
83
+ end
84
+
85
+ def to_hash
86
+ @map.dup
87
+ end
88
+
89
+ def to_a
90
+ @map.to_a
91
+ end
92
+
93
+ def map
94
+ @map.map {|k, v| yield(k, v)}
95
+ end
96
+
97
+ def dup
98
+ d = super
99
+ d.send(:instance_variable_set, "@map", @map.dup)
100
+ d
101
+ end
102
+
103
+ def sort_by
104
+ @map.sort_by {|k, v| yield k, v}
105
+ end
106
+
107
+ def update(map)
108
+ map = map.as_stored if map.is_a?(NormalizedMap)
109
+ map.each {|k, v| self[k] = v}
110
+ end
111
+
112
+ def method_missing(method, *args, &block)
113
+ if Sass.tests_running
114
+ raise ArgumentError.new("The method #{method} must be implemented explicitly")
115
+ end
116
+ @map.send(method, *args, &block)
117
+ end
118
+
119
+ if Sass::Util.ruby1_8?
120
+ def respond_to?(method, include_private = false)
121
+ super || @map.respond_to?(method, include_private)
122
+ end
123
+ end
124
+
125
+ def respond_to_missing?(method, include_private = false)
126
+ @map.respond_to?(method, include_private)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,192 @@
1
+ # Copyright (c) 2005-2013 David Heinemeier Hansson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ # This class was copied from an old version of ActiveSupport.
23
+ class OrderedHash < ::Hash
24
+ # In MRI the Hash class is core and written in C. In particular, methods are
25
+ # programmed with explicit C function calls and polymorphism is not honored.
26
+ #
27
+ # For example, []= is crucial in this implementation to maintain the @keys
28
+ # array but hash.c invokes rb_hash_aset() originally. This prevents method
29
+ # reuse through inheritance and forces us to reimplement stuff.
30
+ #
31
+ # For instance, we cannot use the inherited #merge! because albeit the algorithm
32
+ # itself would work, our []= is not being called at all by the C code.
33
+
34
+ def initialize(*args)
35
+ super
36
+ @keys = []
37
+ end
38
+
39
+ def self.[](*args)
40
+ ordered_hash = new
41
+
42
+ if args.length == 1 && args.first.is_a?(Array)
43
+ args.first.each do |key_value_pair|
44
+ next unless key_value_pair.is_a?(Array)
45
+ ordered_hash[key_value_pair[0]] = key_value_pair[1]
46
+ end
47
+
48
+ return ordered_hash
49
+ end
50
+
51
+ unless args.size.even?
52
+ raise ArgumentError.new("odd number of arguments for Hash")
53
+ end
54
+
55
+ args.each_with_index do |val, ind|
56
+ next if ind.odd?
57
+ ordered_hash[val] = args[ind + 1]
58
+ end
59
+
60
+ ordered_hash
61
+ end
62
+
63
+ def initialize_copy(other)
64
+ super
65
+ # make a deep copy of keys
66
+ @keys = other.keys
67
+ end
68
+
69
+ def []=(key, value)
70
+ @keys << key unless has_key?(key)
71
+ super
72
+ end
73
+
74
+ def delete(key)
75
+ if has_key? key
76
+ index = @keys.index(key)
77
+ @keys.delete_at index
78
+ end
79
+ super
80
+ end
81
+
82
+ def delete_if
83
+ super
84
+ sync_keys!
85
+ self
86
+ end
87
+
88
+ def reject!
89
+ super
90
+ sync_keys!
91
+ self
92
+ end
93
+
94
+ def reject
95
+ dup.reject! {|h, k| yield h, k}
96
+ end
97
+
98
+ def keys
99
+ @keys.dup
100
+ end
101
+
102
+ def values
103
+ @keys.map {|key| self[key]}
104
+ end
105
+
106
+ def to_hash
107
+ self
108
+ end
109
+
110
+ def to_a
111
+ @keys.map {|key| [key, self[key]]}
112
+ end
113
+
114
+ def each_key
115
+ return to_enum(:each_key) unless block_given?
116
+ @keys.each {|key| yield key}
117
+ self
118
+ end
119
+
120
+ def each_value
121
+ return to_enum(:each_value) unless block_given?
122
+ @keys.each {|key| yield self[key]}
123
+ self
124
+ end
125
+
126
+ def each
127
+ return to_enum(:each) unless block_given?
128
+ @keys.each {|key| yield [key, self[key]]}
129
+ self
130
+ end
131
+
132
+ def each_pair
133
+ return to_enum(:each_pair) unless block_given?
134
+ @keys.each {|key| yield key, self[key]}
135
+ self
136
+ end
137
+
138
+ alias_method :select, :find_all
139
+
140
+ def clear
141
+ super
142
+ @keys.clear
143
+ self
144
+ end
145
+
146
+ def shift
147
+ k = @keys.first
148
+ v = delete(k)
149
+ [k, v]
150
+ end
151
+
152
+ def merge!(other_hash)
153
+ if block_given?
154
+ other_hash.each {|k, v| self[k] = key?(k) ? yield(k, self[k], v) : v}
155
+ else
156
+ other_hash.each {|k, v| self[k] = v}
157
+ end
158
+ self
159
+ end
160
+
161
+ alias_method :update, :merge!
162
+
163
+ def merge(other_hash)
164
+ if block_given?
165
+ dup.merge!(other_hash) {|k, v1, v2| yield k, v1, v2}
166
+ else
167
+ dup.merge!(other_hash)
168
+ end
169
+ end
170
+
171
+ # When replacing with another hash, the initial order of our keys must come from the other hash --
172
+ # ordered or not.
173
+ def replace(other)
174
+ super
175
+ @keys = other.keys
176
+ self
177
+ end
178
+
179
+ def invert
180
+ OrderedHash[to_a.map! {|key_value_pair| key_value_pair.reverse}]
181
+ end
182
+
183
+ def inspect
184
+ "#<OrderedHash #{super}>"
185
+ end
186
+
187
+ private
188
+
189
+ def sync_keys!
190
+ @keys.delete_if {|k| !has_key?(k)}
191
+ end
192
+ end